This week I came across a strange issue. In a process running on an embedded device, one of the threads, at some point, remained stuck. Since the gdbserver was not immediately available for that particular target, I tried to add some printf() but without being able to understand what was going wrong.

Eventually, I managed to do a remote debug and... everything worked just fine. So, after double-checking my code, I started to think that the problem was due to the optimization made by that particular toolchain.

Quick Digression

If you are not familiar with embedded devices terminology, a toolchain is basically a (C/C++) compiler with its libraries (libc and others) that compiles your source code for a processor/OS different from the one it's running.

In my case, I have almost the same code running on two different embedded devices, compiled with two different toolchains, both GCC-based. And this issue only appears on one of the two devices.

The Solution

Leaving all the program not optimized is a possible solution, but I don't like it much. So I tried to look at the same old GCC attributes page until I found this:

The optimize attribute is used to specify that a function is to be compiled with different optimization options than specified on the command line.

Bingo! So this is how my thread function become:

void __attribute__((optimize("O0"))) foo(void *data) {
        ...
}

And the rest of the program is optimized with standard -O2.


Image taken from Wikimedia Commons licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license.