Getting CppUTest to work on Crossworks

620 views
Skip to first unread message

Ivan Zrno

unread,
Mar 26, 2015, 10:31:40 AM3/26/15
to cppu...@googlegroups.com
Hello everyone,

after reading the book twice and every post in this group, encouraged by your super support i finaly decided to post here.

I am preety new to the embedded world, but not a total noob. Unfortunately i am a complete noob when it comes to C++ or the CrossStudio, Crossworks form Rowley.

Until now i tried to follow and to understand the succes stories of implementing CppUtest in IAR, Keil and ATmel Studio.

In little steps i managed to get the CppUTest and CppUtestExt to compile creating a library. The UtestPlatform.cpp i used was the one from src\Platforms\Iar. It compiles but i am not completely sure if i need to change something in there to get it working for Crossworks.

The first problem was that with the gcc compiler chosen hundreds od erros would come up.
Many of them in such form: declaration of C function 'long int abs(long int)' conflicts with stdlib.h

The solution was to choose the clang compiler. One other thing was to enable excpetion support in the code generation options.
In the compiler options this command had to be included: -fno-threadsafe-statics. It had something to do with no safe threads. For a C++ noob like me this is a little bit unclear to understand. And i am not sure if this option will break something in CppUTest.

That was the first part. After that i tried to add the second project like described in the stories, the CppUTest_Tests project. Offcourse that after adding all the .cpp's and .c's it didnt compile. After adding the memory map file that i found in this group for the Cortex M3 things started getting better.

The first problem was the "Undefined reference to '__cxa_guard_acquire'" error message. Solved also with the parameter: -fno-threadsafe-statics
Next was the "undefined reference to 'abort'" error message. Solved with following code:

extern "C" void abort(void)
{
  while (1);
}

Next error was
"Undefined reference to '__cxa_pure_virtual'" error message, solved in a similar way:
extern "C" void __cxa_pure_virtual() { while (1); }


After that folowed the undefined clock() function. I solved that by implementing the clock() function mentione in the Keil succes story.


One of the problems is that i dont know if all those sollution are realy working, they just helped me compile the tests.

Now after the tests are compiling i cant see any result and i dont realy understand how to do that. I amanged to get it working on visual studio,
but this crossworks is killing me. I tried to implement something similar to the Keil semihosting thing to retarget the fputc, but that didnt seem to help.

I hope this isnt to much text for you, but i simply dont know what to do next. Thanks in forward for everyone who wants to help.

James Grenning

unread,
Mar 26, 2015, 12:48:06 PM3/26/15
to cppu...@googlegroups.com
Is your code in an infinite loop?

Maybe rather than while(1) you could make an exploding fake

#include "CppUTest/TestHarness_c.h"

void abort() { FAIL_TEXT_C("abort"); }

On 26 Mar 2015, at 9:31, Ivan Zrno wrote:

> Hello everyone,
>
> after reading the book twice and every post in this group, encouraged
> by
> your super support i finaly decided to post here.
>
> I am preety new to the embedded world, but not a total noob.
> Unfortunately
> i am a complete noob when it comes to C++ or the CrossStudio,
> Crossworks
> form Rowley.
>
> Until now i tried to follow and to understand the succes stories of
> implementing CppUtest in IAR, Keil and ATmel Studio.
>
> In little steps i managed to get the CppUTest and CppUtestExt to
> compile
> creating a library. The UtestPlatform.cpp i used was the one from
> src\Platforms\Iar. It compiles but i
>
> *am not completely sure if i need to change something in there to get
> it
> working for Crossworks.*The first problem was that with the gcc
> --
> You received this message because you are subscribed to the Google
> Groups "cpputest" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to cpputest+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

A. Robert S.

unread,
Mar 26, 2015, 3:59:13 PM3/26/15
to cppu...@googlegroups.com
Hi James,

I think the infinite loops are intentional. Since embedded code has "nowhere to go" once the code aborts, this is often used for debugging, so the execution keeps going and you can inspect call stack and other things with the debugger. Running on an embedded target, it actually makes sense to put while(1) {} at the end of the test binary's main() function for that reason.

Regards,
Robert
Message has been deleted

Ivan Zrno

unread,
Mar 27, 2015, 3:00:17 AM3/27/15
to cppu...@googlegroups.com
Thanks for the tip James, but i tried it and no difference. I am running this code without HW, just with an ARM simulator choosen as the target. Could the problem be in the output, in the putc() or something like that?

Ivan Zrno

unread,
Mar 27, 2015, 4:08:20 AM3/27/15
to cppu...@googlegroups.com
But now i got a little bit further after playing with teh simulator options. Now the code actualy starts after pressing build+debug. The new problem is that the code just "stops" at this point in Utest.cpp:

NullTestShell& NullTestShell::instance()
{
    static NullTestShell _instance;
    return _instance;
}

So exactly at the static line the code stops there and doesnt get moving past that, the debugger is working and everything, but the code is just frozen there. So any idea why? A C++ friend explained that that line is just a declaration, like int x = 5; and that there shouldnt be problems.

Ivan Zrno

unread,
Mar 27, 2015, 8:37:41 AM3/27/15
to cppu...@googlegroups.com
Ok so i got a little further with the analysis. The code runs into the dabort_handler. It happen after the "Call constructors" part in the crt0.s startup code. The code jumps to the "ctors_start" memory segment which causes it to jump to this part of the code in AllocLetTestFreeTest.cpp:

TEST(AllocLetTestFree, Create)
{
    free(allocLetTestFree);
}

after that it somehows gets to this part in Utest.cpp

UtestShell::UtestShell() :
    group_("UndefinedTestGroup"), name_("UndefinedTest"), file_("UndefinedFile"), lineNumber_(0), next_(&NullTestShell::instance()), isRunAsSeperateProcess_(false), hasFailed_(false)
{
}

which effectively causes the data abort. Hope this info helps you

Wayne J

unread,
Mar 27, 2015, 12:14:58 PM3/27/15
to cppu...@googlegroups.com

On Mar 27, 2015, at 1:08 AM, Ivan Zrno <ivan....@gmail.com> wrote:

NullTestShell& NullTestShell::instance()
{
    static NullTestShell _instance;
    return _instance;
}

So exactly at the static line the code stops there and doesnt get moving past that, the debugger is working and everything, but the code is just frozen there. So any idea why? A C++ friend explained that that line is just a declaration, like int x = 5; and that there shouldnt be problems.

This is probably NOT just like “int x = 5;”

I assume that NullTestShell is a class. You are creating a static instance of the class. When a class is created its constructor gets called.

Since this is a static class it must be constructed before NullTestShell::instance() gets called. Exactly when before is up to the compiler. 

Most likely "Call constructors” is where the compiler calls the constructors for all the classes that have been created statically.

I would start looking in the constructor for NullTestShell.  It’s hard to know why abort is being called. You will need to trace through the code in the constructor. You will either hit an abort in your code OR you will step over a call to a library function and end up in abort(). Once you figure out where the abort is being called (most likely a library function) you will need to figure out why.

Or if your platform supports exceptions, it could be an unhanded exception.

Wayne

Ivan Zrno

unread,
Mar 30, 2015, 3:30:55 AM3/30/15
to cppu...@googlegroups.com
Thanks for the tip Wayne. I really oversimplified when i sad that a constructor is similar to a int x = 5. During the day i learned and cam to the same conclusion like you. I managed to track down the code execution and it goes like this:
1)
  ldr r0, =__ctors_start__  // the ctors start addres is loaded into register R0
  ldr r1, =__ctors_end__   // the ctors end addres is loaded into register R1
  cmp r0, r1                      // if end is reached branch to ctor_end
  beq ctor_end
  ldr r2, [r0], #+4              // r2 = *(r0), r0 = r0+4
  .....
  bx r2

so after that it jumps to the addres which was stored at __ctors_start__

2)
bl 0x000008CC <__static_initialization_and_destruction_0(int, int)>  // this is some gcc part that i dont really understand, but it sounds ok, sounds like the static intialization part that you described that should hapen.

3)
bl 0x0000075C <TEST_AllocLetTestFree_Create_TestShell::TEST_AllocLetTestFree_Create_TestShell()>  //could this be the first constructor?

4)
blx 0x00070230 <UtestShell::UtestShell()>  //another constructor??

5)
Then it jumps to this part in the code:

UtestShell::UtestShell() :
    group_("UndefinedTestGroup"), name_("UndefinedTest"), file_("UndefinedFile"), lineNumber_(0), next_(&NullTestShell::instance()), isRunAsSeperateProcess_(false), hasFailed_(false)
{
}

This part look like this in the assembler:

    movw r2, #0xCC0
    movt r2, #9
    adds r2, #8
    str r2, [r0]
    movw r2, #0xD48  // and this is the line after which the data abort happens, so this is a simple r2 = 0xD48, why would the abort happen after this?
    movt r2, #9        //this doesnt get executed
    str r2, [r0, #4]

Thanks for all the advices so far.

James Grenning

unread,
Mar 31, 2015, 6:56:36 AM3/31/15
to cppu...@googlegroups.com
I get the nowhere to go thing, but with the symptom, seemed it could
have been the problem.

I guess I'd rather not sprinkle while(1); too many places.
>>> an email to cpputest+u...@googlegroups.com <javascript:>.

Ivan Zrno

unread,
Mar 31, 2015, 7:19:37 AM3/31/15
to cppu...@googlegroups.com
So i managed to get a little bit further. After playing with the project options, i declared that the CppUTest_Test has a dependenca on the CppUTest project. That solved the data abort in the contructor part of the memory.

Now i realy get into the main in AllTests.cpp :D, a major breaktrough.

But i get an other data abort :( This time it happens after calling the: return CommandLineTestRunner::RunAllTests(ac_override, av_override);

From which this part is called: MemoryLeakWarningPlugin memLeakWarn(DEF_PLUGIN_MEM_LEAK);

Than it jumps here:

MemoryLeakWarningPlugin::MemoryLeakWarningPlugin(const SimpleString& name, MemoryLeakDetector* localDetector) :
    TestPlugin(name), ignoreAllWarnings_(false), destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_(false), expectedLeaks_(0)
{
    if (firstPlugin_ == 0) firstPlugin_ = this;

    if (localDetector) memLeakDetector_ = localDetector;
    else memLeakDetector_ = getGlobalDetector(); //here comes the error

Than it jumps here:

MemoryLeakDetector* MemoryLeakWarningPlugin::getGlobalDetector()
{
    if (globalDetector == 0) {
        bool newDeleteOverloaded = areNewDeleteOverloaded();
        turnOffNewDeleteOverloads();

        globalReporter = new MemoryLeakWarningReporter;
        globalDetector = new MemoryLeakDetector(globalReporter); //here comes the error

Than this part gets called causing the data abort:

MemoryLeakDetector::MemoryLeakDetector(MemoryLeakFailure* reporter)
{
    doAllocationTypeChecking_ = true;
    allocationSequenceNumber_ = 1;
    current_period_ = mem_leak_period_disabled;
    reporter_ = reporter;
    outputBuffer_ = MemoryLeakOutputStringBuffer();
    memoryTable_ = MemoryLeakDetectorTable(); //this is where the data abort happens

Sory if i am boring. But i would love to continue using TDD in this company, unfortunately it has to be in crossworks IDE.



Bas Vodde

unread,
Mar 31, 2015, 10:09:05 PM3/31/15
to cppu...@googlegroups.com

Hi Ivan,

The easiest way to proceed is to turn off the memory leak detection for now.

The code you showed is a bit weird code as it tries to deal with being executed at odd times :)

You can use the #define for turning it off and try to get everything working without it first?

Thanks!

Bas



Ivan Zrno

unread,
Apr 1, 2015, 3:05:54 AM4/1/15
to cppu...@googlegroups.com
Thanks for the tip. If you mean defining #define CPPUTEST_USE_MEM_LEAK_DETECTION 0 in the CppUTestConfig.h than i have already done that, sory for not mentioning it.

Bas Vodde

unread,
Apr 1, 2015, 6:30:58 AM4/1/15
to cppu...@googlegroups.com

Hi,

In that case, could you comment out these 2 lines:

    outputBuffer_ = MemoryLeakOutputStringBuffer();
    memoryTable_ = MemoryLeakDetectorTable(); //this is where the data abort happens

These two lines are weird as it asks, in the constructor, to overwrite the freshly created object with a new freshly created one :)

I *guess* that they actually might be removed as we changed the allocation of the MemoryLeakDetector. Let me look into that quickly.

Thanks,

Bas

Bas Vodde

unread,
Apr 1, 2015, 6:44:04 AM4/1/15
to cppu...@googlegroups.com

Hi,

Or… it might actually crash on the next line, which creates a mutex?

Anyway, you can try deleting the 2 lines.

Thanks,

Bas
Message has been deleted

Ivan Zrno

unread,
Apr 1, 2015, 8:55:03 AM4/1/15
to cppu...@googlegroups.com
Thanks for the tip! It really helped to get further. I got another error but it was caused with the stack being to small, so i expanded it from 600 bytes to 800 bytes. Now i am stuck on getting a working clock() function inside crossworks ARM simulator. But that will have to wait after my vacation. So ill be back in several days with more questions for sure. Thanks for all the help so far!

Bas Vodde

unread,
Apr 1, 2015, 8:57:33 AM4/1/15
to cppu...@googlegroups.com

Hi,

Ok, the stack might also have been the problem earlier on the MemoryLeakDetector.

Have a good vacation!

Bas

On 1 Apr, 2015, at 8:55 pm, Ivan Zrno <ivan....@gmail.com> wrote:

Thanks for the tip! It really helped to get further. I got another error but it was caused with the stack being to small, so i expanded it from 600 bytes to 800 bytes. Now i am stuck on getting a working clock() function inside crossworks ARM simulator. But that will have to wait after my vacation. So ill be back in several days with more questions for sure. Thanks for all the help so far!

Ivan Zrno

unread,
Apr 15, 2015, 4:51:06 AM4/15/15
to cppu...@googlegroups.com
So i am back again :)

Thanks for all the help so far, i got it running. It even compiles and runs with the memory leak detection enabled. A few problems were there, one of them was the problem with multiple definitions of new and delete inside the MemoryLeakWarningPlugin.cpp , a simple properties change iside the linker options to "allow multiple symbol definition = yes" solved this.

Now i get 5 failing tests.

Failure in TEST(TestHarness_c, callocShouldReturnNULLWhenOutOfMeory)
    CHECK(m == 0) failed

TEST(TestHarness_c, cpputest_malloc_out_of_memory_after_0_mallocs)
    CHECK(m1 == 0) failed

Failure in TEST(TestHarness_c, cpputest_malloc_out_of_memory_after_n_mallocs)
    expected <0x0>
    but was  <0xd86a8>

Failure in TEST(TestHarness_c, cpputest_malloc_out_of_memory)
    CHECK(0 == cpputest_malloc(100)) failed

Failure in TEST(MemoryLeakWarningGlobalDetectorTest, checkIfTheMemoryLeakOverloadsAreOff)
checkIfTheMemoryLeakOverloadsAreOff:300: error:
    Deallocating non-allocated memory
   allocated at file: <unknown> line: 0 size: 0 type: unknown
   deallocated at file: <unknown> line: 0 type: delete

The active compiler in Crossworks is Clang. Any idea what could cause this?

Bas Vodde

unread,
Apr 18, 2015, 8:28:05 AM4/18/15
to cppu...@googlegroups.com

Hi Ivan,

Welcome back.

Those are some strange errors. I would leave the last one last as it might be an effect of the first or an effect of your “allow multiple symbol definitions” (this isn’t a linker option that should need to be on!).

All the others seem to relate to the behavior of out of memory…. so, I would check what the malloc/calloc/new behavior is on your platform when it runs out of memory :) I assume this might actually be important.

Thanks,

Bas

Ivan Zrno

unread,
Jun 2, 2015, 3:09:47 AM6/2/15
to cppu...@googlegroups.com
Hi Bas,

well i got everything working except the memory leak detection. Even got my first project solved with TDD :D

In the attachment you can see the stlport implementation of new that comes with Rowley Crossworks.

The errors that i get come during the linking process. The errors are:

    lib/libcpp_throws_v7m_t_le_eabi.a(new.o): In function `operator new(unsigned int)':
    new.cpp:(.text.libcpp._Znwj+0x0): multiple definition of `operator new(unsigned int)'
    /MemoryLeakWarningPlugin.cpp:216: first defined here
    /lib/libcpp_throws_v7m_t_le_eabi.a(new.o): In function `operator new[](unsigned int)':
    new.cpp:(.text.libcpp._Znaj+0x0): multiple definition of `operator new[](unsigned int)'
    /MemoryLeakWarningPlugin.cpp:236: first defined here
    /lib/libcpp_throws_v7m_t_le_eabi.a(new.o): In function `operator new(unsigned int, std::nothrow_t const&)':
    new.cpp:(.text.libcpp._ZnwjRKSt9nothrow_t+0x0): multiple definition of `operator new(unsigned int, std::nothrow_t const&)'
    MemoryLeakWarningPlugin.cpp:257: first defined here
    /lib/libcpp_throws_v7m_t_le_eabi.a(new.o): In function `operator new[](unsigned int, std::nothrow_t const&)':
    new.cpp:(.text.libcpp._ZnajRKSt9nothrow_t+0x0): multiple definition of `operator new[](unsigned int, std::nothrow_t const&)'
    /MemoryLeakWarningPlugin.cpp:262: first defined here
    /lib/libcpp_throws_v7m_t_le_eabi.a(new.o): In function `operator delete(void*)':
    new.cpp:(.text.libcpp._ZdlPv+0x0): multiple definition of `operator delete(void*)'
    /MemoryLeakWarningPlugin.cpp:224: first defined here
    /lib/libcpp_throws_v7m_t_le_eabi.a(new.o): In function `operator delete[](void*)':
    new.cpp:(.text.libcpp._ZdaPv+0x0): multiple definition of `operator delete[](void*)'
    /MemoryLeakWarningPlugin.cpp:244: first defined here
    /MemoryLeakOperatorOverloadsTest.o: In function `TEST_OutOfMemoryTestsForOperatorNew_FailingNewOperatorReturnsNullWithoutOverride_Test::testBody()':
    undefined reference to `operator new'
    undefined reference to `nothrow'
    /MemoryLeakOperatorOverloadsTest.o: In function `TEST_OutOfMemoryTestsForOperatorNew_FailingNewArrayOperatorReturnsNullWithoutOverride_Test::testBody()':
    undefined reference to `operator new[]'
    undefined reference to `nothrow'
    Build failed


Hope you can find something meaningful.

Thanks,

Ivan
new.h

Bas Vodde

unread,
Jun 2, 2015, 5:12:48 AM6/2/15
to cppu...@googlegroups.com

HI Ivan,

Uhm, with these errors I might know the problem, but not the solution :) It is weird that operator new overload is causing the error. My guess is that *any* operator new overload would cause this error…

I couldn’t find anything in google.

I don’t have the same environment, so I can’t experiment. However, the experiment I would do is to try to build *any* application with an overloaded operator new and see if it would work.

If you want to check further, I’d check that and if it works, then see whats different.

Thanks!

Bas

<new.h>

Ivan Zrno

unread,
Jun 3, 2015, 2:01:20 AM6/3/15
to cppu...@googlegroups.com
Thanks for the answer ill try that later,

until then another question, the CppUTes with MEM_LEAK_DETECTION_DISABLED and CPPUTEST_USE_STD_CPP_LIB is passing all tests except one.

/MemoryLeakDetectorTest.cpp:164: error: Failure in TEST(MemoryLeakDetectorTest, OneHundredLeaks)
/TestMemoryAllocator.cpp:37: error:
    malloc returned null pointer

Any idea why only thistest is failing?

A. Robert S.

unread,
Jun 8, 2015, 4:26:00 AM6/8/15
to cppu...@googlegroups.com
Actually ran out of memory, perhaps?

Bas Vodde

unread,
Jun 8, 2015, 7:25:41 AM6/8/15
to cppu...@googlegroups.com

Hi,

Without having looked into this is detail, that might seem it :)

Ivan: Does it fail after an x number of allocations?

Bas
Reply all
Reply to author
Forward
0 new messages