Debugging C++?

Go To Last Post
43 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm trying to debug my C++ code using Studio 6.1.2440 and my JTAGICE2.

I can't see most of the data. I am using the default -O1 optimize option. Is that what I should use? I use new to construct my classes. Is that my problem?

All local (stack) variables are optimized away. All class data members are shown as "Unknown identifier" in quick watch.

In the past I've copied data I want to see to GPIO registers. The debugger shows the register contents. Is that my only option?

I've had this problem forever but I thought it might be better with Studio 6, or maybe I'm doing things wrong.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Volatile?

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes. Volatile does help. Thank you.

The preliminary test shows some promise. Volatile local variables can be examined and the value seen, at least in the one function I tested. Furthermore one other local variable that isn't volatile can be seen, Another non-volatile cannot be seen. Maybe the one that is visible can be seen because it's value depends on the volatile variable.

The volatile class member data is still "Unknown identifier".

Also it seems the function with the volatile local variables that I want to examine must not be inlined. Almost all my functions are normally inlined, but for debug purposes I use my secret formula to prevent inlining. Well okay, if you promise not to tell, -finline-limit=2 does the trick.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

with the latest patch applied in the backend the debugging of c++ works a whole lot better than it used to.

it is now possible to watch members of inherited classes.

A problem is that globals are reported as optimized away. it is necessary to step/break while inside the class and then all is well.

regards
Greg

Last Edited: Wed. Apr 24, 2013 - 10:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have build 2440. Is there a patch for it?

I can't see members of regular (non derived) classes.

I construct classes during initialization on the heap using "new". Is that the way you do it?

Last Edited: Wed. Apr 24, 2013 - 09:31 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Is there a patch for it?

Look for posts here by "danv".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Patch is here

Note that when the release is released, you should uninstall the beta AND make sure that there are no leftover dlls in the installation directory, just to be on the safe side...

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:
I construct classes during initialization on the heap using "new". Is that the way you do it?

I (right or wrong) never use new. I thought I read it was not properly supported somewhere.

I either declare global instances or have also declared local instances (on stack) both with the syntax

class aClass{....};
aClass anInstance;

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I thought I read it was not properly supported somewhere.

That'd be the sticky thread at the top of the GCC forum about C++. But all it says there is that you have to provide an implementation which is basically a call to malloc (and delete is a call to free). However there is always the issue (just as with malloc/free use) of whether any kind of dynamic allocation is a good idea on a micro with limited RAM resources.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gregd99 wrote:
A problem is that globals are reported as optimized away. it is necessary to step/break while inside the class and then all is well.

any joy on a solution for this?

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want to "see" anything in a debugger when using an optimising compiler either make the object itself volatile or copy it to a volatile object of the same type and watch that.

(or do what the rest of us have been doing for years: switch to a mixed C + Asm view and determine which registers the object has been cached into and watch that in the register view)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Is that the way you do it?

That is one way of doing it. The generic term is "dynamic allocation". Such objects must ultimately be destroyed and the memory returned to the memory allocqation sub-system by an explicit call to the 'delete' operator.

There are (at least) two other ways:

Static allocation - i.e. a "global object" defined outside of any class or function. Or defined within a class or function with the 'static' kayword. Such objects exist for the lifetime of the running application.

Automatic allocation - i.e. "a local object" defined as local to a function. You can pass the object (or often better, a reference) to other functions. When the block in which the object was originally defined exits the object is deleted automagically.

Which one to use depends on circumstances - there is no generic answer. It is true though, that misusing dynamic allocation will likely get you into big trouble real fast.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
If you want to "see" anything in a debugger when using an optimising compiler either make the object itself volatile or copy it to a volatile object of the same type and watch that.

(or do what the rest of us have been doing for years: switch to a mixed C + Asm view and determine which registers the object has been cached into and watch that in the register view)


I haven't explained the problem well enough.

a global that truly exists - has not been optimised away - is only visible once you step into a member function. it is not an optimisation issue but a symbol definition issue.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought this was one of the things that patch was supposed to have fixed?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

a global that truly exists - has not been optimised away - is only visible once you step into a member function.

Just to be absolutely sure I understand this correctly: Are you talking about the global object per se not being visible, or are you talking about the members of the global object?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the global object per se is not visible. ie cannot be watched. it is reported as "optimised away"

if you break in a member function of that object then all of its members may be watched.

my original report is in the linked post above.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
That'd be the sticky thread at the top of the GCC forum about C++. But all it says there is that you have to provide an implementation which is basically a call to malloc (and delete is a call to free). However there is always the issue (just as with malloc/free use) of whether any kind of dynamic allocation is a good idea on a micro with limited RAM resources.
Not true. The new operator function needs to return the address where the object to be created will reside. There is no requirement to use malloc. My new operator function that allocates memory from the heap is just a few lines of code.

Furthermore the new operator function doesn't necessarily need to allocate any memory from the heap. For instance when I new my Usart_D0 class, it simply returns the address of the Usart_D0 registers. That would be USARTD0 defined in the io.....h file.

In any case it takes no more RAM to put classes on the heap as it does to have the linker allocate the space beforehand.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

My new operator function that allocates memory from the heap is just a few lines of code.

But that's surely using alloca() which is just a variant of malloc() allocating from a different pool?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
The generic term is "dynamic allocation". Such objects must ultimately be destroyed and the memory returned to the memory allocqation sub-system by an explicit call to the 'delete' operator.
What is the penalty for failure to comply with this law? I have been putting classes on the heap since I started programming microcontrollers 10 years ago. I haven't returned any memory to the heap yet. I haven't been arrested so far. If the memory police are now using drones, maybe I should keep my blinds closed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's no penalty in using "new" alone - it's when you mix "new" and "delete" (which malloc/free from the heap not the stack) that you face heap fragmentation which can occur very quickly in a small micro. If you just "new" it's not really any different to global allocation in that the things are instantiated once then hold the memory they occupy for all time. It's kind of similar to locals in main:

int main(void) {
  char foo[10];
  // rest of program
}

If main() never exits foo[] is "locked" for all time.

alloca is a bit different. It only exists for the scope of the function it's used in and is effectively freed on exit but as it's just adding an offset to SP it doesn't matter.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
But that's surely using alloca() which is just a variant of malloc() allocating from a different pool?
I don't know what alloca() is. Like I said, it only takes few lines of code to allocate memory from the heap. There is no way to return the memory to the heap and no reason on earth to do so. Here is my new.cpp file. This is more elaborate than is usually necessary. I have included code for allocating arrays "new[]" and also for allocating memory at a location specified by the caller "placement new".

#include "stdlib.h"    // for size_t

extern char __heap_start;
char* heap_next_p = &__heap_start;



void* AllocateFromHeap_p(size_t objsize)   {
   void* here_p = heap_next_p;
   heap_next_p += objsize;
   return here_p;
   }


void* operator new(size_t objsize)   {
   return AllocateFromHeap_p(objsize);
   }


// NOTE:  you don't need the rest of this stuff unless you use the array new or the placement new


void* operator new(size_t objsize, void* here_p)   {    // placement new
   return here_p;
   }


void* operator new[](size_t objsize)   {
   return AllocateFromHeap_p(objsize);
   }


void* operator new[](size_t objsize, void* here_p)   {    // placement new
   return here_p;
   }

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then if you use heap not stack and you never free (delete) then why not just malloc()? What's the apparent advantage of accessing the _heap_start system variable yourself? I suppose it saves the 4 byte per allocation overhead that malloc() would have? The sticky at the top of GCC forum about C++ simply suggests:

// the .h
#include 

void * operator new(size_t size);
void operator delete(void * ptr);
// the .cpp implementation
void * operator new(size_t size)
{
  return malloc(size);
}

void operator delete(void * ptr)
{
  free(ptr);
}

Why make it more complicated than that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I assume (maybe incorrectly) that malloc() is much bigger than just a few lines of code. Also I don't know if I could include malloc() without including free() and maybe a lot of other stuff. I'd rather write my own simple code in any case. For instance if I want to see how much free ram I have, I know where heap top is located, etc.

Actually I don't think I include any library code in my AVR code. If I do, it's something that gets included automatically. I say "keep it simple".

I don't have to worry about what version of the library, if any, has the placement new, for instance. Actually the placement new is my favorite, All it does is return the address passed to it. I can handle that one. ;)

Also I should mention that the new operator function I use is based on one posted here about 8 years ago. I don't know who posted it, but thanks to you, whoever you are.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So now it seems clear why I have a harder time doing on chip debugging than most of you. It looks like this situation will continue for a long time unless I can convince you amateurs to write "real" C++. ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For the second time in just a few days I am discussing C++ innards with peopel that I know have a well founded knowledge of C++. In what follows I say things that I believe is rather basic. Please don't take that as an indication of that I think you are an "amateur" but rather as a help to overcome the obvious communication glitches that we must have here.

Quote:

Like I said, it only takes few lines of code to allocate memory from the heap.

After a quick glanse:

1) You are not overriding the delete operator. If that operator ever gets called (explicit or implicit), I speculate that you might be in big trouble.

2) Since you "meddle" with the heap in your own way you seem to have made yourself incompatible with e.g. malloc/free. If a call to malloc() is ever done (again explicit, or implicit e.g. from some stock-pile code) I speculate that you might be in big trouble.

3) There is a default implementation of the new operator supplied by avr-gcc. (It might not have been there from the start, but it's been there for several years now.) Why will not that suffice?

Re matching dynamic allocation using the new operator with de-allocation with the delete operator: If you allocate relatively few objects, at the startup of the application and those objects then live for the lifetime of the executing application, then the system might very well perform well. In effect, this is in effect similar/close to allocating the objects statically (i.e. global variable).

For systems where objects are created with the new operator during the whole lifetime, but where objects should have a relatively short lifetime, not destroying the objects and releasing the allocated memory will of-course lead to the heap being exhausted. The direct comparison is doing malloc()s in the same way without doing the corresponding free()s.

So... Where are we misunderstanding each other?

-----
Now for the more "surly" part: I loathe being classified as an "amateur". Can you give an example of '"real" C++', and something mentioned in this thread that does not fit that classification? I have been programming C++ professionally for some 20 years. The language is big and has evolved over the years (.g. the placement new being just one exsmple), so there might be something I'm missing . Still, I would classify myself as at least a "strong four" on a scale 1-5. Can we please steer clear from calling names here? Lately, the C++ discussions here has upped themselves from the stupid "C++ is inefficient" claims to being really interesting discussions. I'd rather hope for the discussions to stay that way. Please?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Johan, I was joking about the amateur stuff, hence the smiley.

I am not overriding anything. No operator new and operator delete functions are supplied in the basic avr-gcc toolchain. You need to supply them. Obviously the operator new and operator delete functions must be compatible.

If I called delete, my programs wouldn't link. If I wanted to call delete, I could include this code:

void operator delete(void* obj)   {
   }

This would allow delete to be used, but of course no memory would be returned to the heap.

If I wanted to use malloc() I would not use my new and delete functions.

The reason I wrote the post was to suggest that it will probably be a cold day in hell before the debugger will show my class member data. That is because it looks like most C++ programmers here have class objects that are known at link time whereas my class objects are created at run time.

EDIT: Actually I don't know if the avr toolchain includes the new and delete operator functions nowadays. I don't think it did when I started using it 8 years ago.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

No operator new and operator delete functions are supplied in the basic avr-gcc toolchain.

Huh? I could have sworn.. Need to double-check tonight.
[EDIT: And now I see your edit about the new operator not being there 8 years ago. No, it wasn't - but it has been there for several years now. Also, notice Cliffs post above where he actually quotes the avr-gcc default implementation of the new operator).]

Quote:
If I wanted to use malloc() I would not use my new and delete functions.

1) As someone said in aanother post: One does not preclude the other.
2) Again, I see some confusion, or I am misreading you (the latter is much more likely): For objects from classes you can of-course not use malloc since that will not run the constructor.

My proposed scenario for a project using a mix of new and malloc() is a C++ project where I use new to create objects, but where that project also includes some stock pile (C++ or, more likely, C code) that does malloc(). As soon as you enter into such a situation you need to adhere to how malloc handles the heap - the easiest way being to simply use the default implementation which of-course is written to play well with how malloc() handles the stack (by simply using malloc() :D)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Also, notice Cliffs post above where he actually quotes the avr-gcc default implementation of the new operator).

No. What I posted was in this sticky thread at the top of GCC:

avr-c+= micro how-to

As it says there. avr-g++/AVR-LibC do not implement new/delete so you have to and the suggestion there is basically just to point them in the direction of malloc()/free().

Quote:

or I am misreading you (the latter is much more likely):

What Steve's doing is simply using the same heap that malloc/free would have used (that's everything from the end of .bss upwards) and implementing the simplest of memory allocation possible (next allocation just abuts the previous) on the basis that he will never free anything.

As such I'm not entirely sure why you would bother with "new" at all and not simply instantiate the classes globally/statically but I guess if you prefer the new syntax it is the very minimum you'd need to do to support it.

My proposed scenario for a project using a mix of new and malloc()

that's not going to work in steve-land. One of the promises he must make is never to consider using malloc().

What I personally would be tempted to do is something like:

void * operator new(size_t size)
{
  static uint8_t mypool;
  bool new_initd = false;
  if (!new_initd) {
    mypool = malloc(200); // as big as all the expected new activity
    new_initd = true;
  }
  // rest of steve's previous stuff but using mypool as the base
  return some_ptr;
}

that is have the first call to new do a malloc() to reserve a "private heap" then use that in future leaving malloc() available for normal use. But as this would drag in malloc() (and free()) from the library code anyway perhaps there's no point and you might as well go with the simple implementation from that sticky and just mix new classes and other object allocations on the single malloc() controlled heap.

BTW you know when I said:

Quote:
But all it says there is that you have to provide an implementation which is basically a call to malloc (and delete is a call to free).

I probably should have said:
Quote:
But all it says there is that you have to provide an implementation which is FOR MOST PEOPLE basically a call to malloc (and delete is a call to free).

then this whole discussion of new/(delete) implementation might not have occurred ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Real C++ programmers don't call malloc() directly, but use the safer new instead. ;) Oh Oh, I'd better apologize in advance. ;)

Actually if I was going to use malloc() and free() for anything, I would use them for everything. It makes no sense to have 2 heaps. So instead of my new and free operator functions, I would use whatever is supplied with the malloc/free implementation. The only reason I use my functions is so I don't need to include malloc etc. If I want to use malloc etc., I don't need my operator functions.

I worked on a big embedded program that ran on what was essentially a PC. We used the normal PC new and delete that used malloc() and free(). We did that because it made sense. The PC had the memory and power to run it. However we did not "churn the heap". We allocated everything at startup and kept it for the duration.

Actually we did usually do the deletes at shutdown but that was mainly for the convenience of the programmers. The customer shut down the "black box" by shutting off the power, and started it by turning on the power.

I have rarely, if ever, used "static" classes. It apparently works okay but I would have to learn a new way of doing things. I prefer to do what I have always done and use new instead.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I have rarely, if ever, used "static" classes. It apparently works okay but I would have to learn a new way of doing things. I prefer to do what I have always done and use new instead.

The two are effectively the same thing aren't they?

If objects are created statically (what I do) they exist for the whole life of the programme. If you "new" all your objects once and never delete any then they exist for the whole life of the programme and are effectively static aren't they?

[Edited to reflect Johan's comment below.]

regards
Greg

Last Edited: Thu. Apr 25, 2013 - 03:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wish they were to the debugger. ;)

I really don't know all the ramifications of static classes. I construct my classes in a certain order. If I don't do that, I get trouble because some classes depend on other ones being initialized. I can pass the address of some class objects to others when they are constructed. Etc.

The world of static classes is alien to me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Real C++ programmers don't call malloc() directly

Real C++ programmers use proven "stock pile" code, even if it is written in C. And place no smiley on that. I am dead serious.

Look, all I am saying that as long as you have full control over all the code that goes into your applications you can implement your own new operator any way you want. As soon as you get some third party code that you must use you are at risk.

Quote:
If classes are created statically (what I do)

No. Let's not get sloppy with terminology here now. Remeber that this thread might be here for future generations of C++ programmers to read.

You are creating objects.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Whatever works for you. I don't understand the third party code thing. If third party code "churns the heap" than of course malloc and free are required. Otherwise there is no problem. New allocates memory from the "free store". Where that memory is and how it is allocated is no concern of the caller.

If the code wants to use special memory, like I sometimes do, then the class needs to have it's own new operator function, or in some cases the caller will use the placement new.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I don't understand the third party code thing. If third party code "churns the heap" than of course malloc and free are required.

And if your new operator works on the same memory are that malloc() and free() does, but using a different "scheme" then you're in trouble. I read your

extern char __heap_start;

as that you're doing exactly that.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure I understand your point. There can be only one global new operator function in the program. It either uses malloc() or it doesn't. Currently I have no reason to use malloc() and I do have a reason not to. That reason being that malloc() involves a lot of code.

If I want to use malloc() then I would use a global new operator function that calls malloc(). So if I wanted to use third party code that needed malloc() then I would use a global new operator function that called malloc().

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I'm not sure I understand your point.

I read it as "you cannot use any library code that might itself use malloc" (and part of the worry is that you may not know that it is). While there isn't much in libc/AVR-LibC that uses malloc() (though fdev_setup_stream() does I think) I guess you might use some library like FAT or JPEG decode or something that could be using it.

Having said that I suppose there'd be a mention of "malloc" in the .map as a warning that something was using it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now I'll lie awake all night worrying about that. ;)

I guess using malloc() and my new operator function's memory allocator on the same heap would cause a confusing bug.

Maybe if I put this code in my new.cpp it would prevent another malloc() from being linked to, and be easier to debug.

void *malloc(size_t size)   {
   while(1)
      ;
   }   
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void *malloc(size_t size)   {
   while(1)
      ;
   }    

I think I'd vote for:

#define __ASSERT_USE_STDERR 
#include 

void *malloc(size_t size)   {
   assert(false);
   }    

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't know how assert works. Is that STDERR a runtime thing? I don't have a STDERR in my AVR. If it's compile time that would be good, but I don't know how that would work either.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You don't have to use __ASSERT_USE_STDERR but if you already have done the FDEV_SETUP_STREAM to map stdout/stderr to a UART or LCD then it could be useful as you'll be alerted when the thing asserts (rather than a hard loop). As well as the message it then calls abort():

http://www.nongnu.org/avr-libc/u...

and that goes to _exit() with the "cli/here: rjmp hjere".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can use static_assert() with C++11 as a compile time assertion. If your not using C++11 Dan Saks had an article with an implementation like the below.

#define JOIN(x, y) JOIN_AGAIN(x, y)
#define JOIN_AGAIN(x, y) x ## y
#define static_assert(e,msg) \
typedef char JOIN(assert_, __LINE__) [(e) ? 1 : ‐1]
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is an LED on the board. I suppose STDERR could display an error msg there using morse code. ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wonder if other people use heap memory allocated with malloc or anything else and put structs/classes there, and find the debugger won't display the data in the structs/classes.