very strange bug

25 Sep 2013

Hi! I am developing some projects and today there was a very strange behavior. My current project is using a XBee to transmit new firmware. The binary chunks where written to a file at LocalFileSystem. When finished and checksums are OK, the file is getting remaned to a real *.bin file. So, here comes the trouble. A real "rename" implementation is still pending. But there is an alternative: Create File with new Filename, copy old file content into new file, remove old file. OK, no problem, works.

But today I uploaded a new firmware, upload successfull, renaming... Error! It could not create the new empty file !? The code providing file upload and flashing was not touched by me since months. The problem must be the new code, but that is not using any file system functionality !?

So I reduced the project (200KB source code) to this small one: http://mbed.org/users/BlazeX/code/Strange_Test/

It should to the same as the LocalFileSystem demo: https://mbed.org/handbook/LocalFileSystem

But is does'nt.

Why?

26 Sep 2013

I reproduced your problem after importing your project. It is hard faulting trying to dereference a NULL pointer. I deleted your Test subdirectory and the problem still reproduced. I renamed your Base.h to Foo.h, modified the #include in main.cpp to use Foo.h instead, and then the code work as expected. However the weird thing is that renaming Foo.h back to Base.h didn't cause the problem to return. Since I don't have symbols I can't tell exactly what led to the crash. It looks like it crashes when it tries to add the first character, 'H', in your fprintf() call to a NULL buffer (which I am guessing is a stream buffer or something similar). I don't know what leads to this happening though. Is it because something goes wrong when the wrong Base.h gets pulled in somewhere?

10 Dec 2014

I solved it (but forgot to update this thread). ^^

The problem was the shared serial usb connection. In Base.h the instance should be shared by creating a "static" one:

Base.h

...
static Serial PC(USBTX, USBRX);
...

But for every source file (compilation unit), including Base.h, a new instance of Serial(USB) was created. mbed is limited to 16 instances of Serial(USB), whatever exactly. The real problem are the multiple instances that can be avoid by using "extern" instead of static.

So this is working:

Base.h

...
extern Serial PC;
...

Base.cpp

...
Serial PC(USBTX, USBRX);
...

So for Beginners: Don't use "static" to share variables/objects between multiple source code files! Use "extern".