------- Comment #5 from wilson at gcc dot gnu dot org 2005-11-01 02:44 ------- Even at -O0, we notice that main ends with a call to a function that does not return, so the epilogue gets optimized away, and the last instruction in the main function is the call to abort.
gdb is naively using return addresses to generate the backtraces. The return address from abort is one past the end of the call to abort, which is past the end of main. We are generating a location list for the frame base, since it differs between the prologue and the function body. This location list defines the value of the frame base at every point between function start and function end, and its value depends on the PC address you have. So gdb is taking a PC address from outside the main function, noticing that this address isn't covered by the frame base location list for main, and generating an error. Possible solutions: 1) Fix gdb to subtract one from a return address before processing the location list. This will ensure that we have an address inside the function, and thus an address for which we have a valid frame base. This is essentially what we do in the dwarf2 unwinder. 2) Pad the function with a nop, so that a return address always points to a valid instruction inside the function. This is what we do in the IA-64 port, to make IA-64 unwinding info work in this case. 3) Extend the location list info to run 1 byte past the end of the function. I don't know if this is safe. If the following function starts immediately after main, then we have two functions with debug info for the same byte of code. This may result in even more confusion than we already have. I think solution 1 should be investigated first, which means we need to get the gdb team to look at this. The problem with the return address can be seen by running "nm -S a.out | grep main" on the compiled testcase which gives you the starting address and size of main, and then comparing this against the PC address in the gdb backtrace. This shows that gdb is using an address 1 byte past the end of main for the backtrace. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24490