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.