Why can't I LD_PRELOAD __assert_fail ?
Jeffrey Walton
noloader@gmail.com
Fri Feb 18 06:36:00 GMT 2011
On Thu, Feb 17, 2011 at 9:11 PM, Chris Barry <cbarry@soundmetrics.com> wrote:
> Hello,
>
> Unlike x86, on ARM if a core file is generated when a function annotated with "__attribute ((noreturn))" is on the call stack---a function such as abort or __assert_fail---then a backtrace with that core will be nearly useless: you get a message about the PC not being saved:
>
> =====================================
> Program terminated with signal 6, Aborted.
> [New process 1419]
> #0 0x401f62dc in raise () from /lib/libc.so.6
> (gdb) bt
> #0 0x401f62dc in raise () from /lib/libc.so.6
> #1 0x401fa6c8 in abort () from /lib/libc.so.6
> Backtrace stopped: frame did not save the PC
> (gdb)
> =====================================
>
> Now in the case of abort I was able to work around this by using LD_PRELOAD to load a custom abort that is not annotated with "__attribute ((noreturn))":
>
> =====================================
> Program terminated with signal 6, Aborted.
> [New process 1423]
> #0 0x401f62dc in raise () from /lib/libc.so.6
> (gdb) bt
> #0 0x401f62dc in raise () from /lib/libc.so.6
> #1 0x4002f4bc in abort () at libcustomabort.cpp:7
> #2 0x0000841c in main () at abort_test.cpp:4
> =====================================
>
> But the same LD_PRELOAD trick does not work with the __assert_fail function that the assert macro expands to: this means that when an assert is triggered and a core is dumped, the core is useless.
>
> So before I replace every single "assert" in a large project with a custom "ASSERT" macro to get around this GCC behavior on ARM, I want to ask if one of you is aware of some workaround.
>
I can''t comment on the useless trace due to a missing program
counter, but I am an avid asserter (there's nothing like a program
that debugs itself). It might be a bug in gdb - I seem to recall a
recent thread on GDB's mailing list on incorrect PC values on ARM.
When using asserts in GNU, I always supply my own ASSERT and install a
custom handler for SIG_TRAP (which does nothing). My ASSERT then calls
raise(SIG_TRAP), which snaps a debugger (if present) or continues
execution (if running from the command line). I could never understand
why POSIX specified that a program should abort after an assert
(http://pubs.opengroup.org/onlinepubs/009695399/functions/assert.html).
Its useless behavior for a developer.
If a program is not supposed to assert (i.e., a 'release' build), then
NDEBUG should be specified (often overlooked).
Jeff
More information about the Gcc-help
mailing list