Hi Folks, GDB sometimes acts in an unexpected way while showing backtrace argument values in certain optimized binaries. I'll go through the example: The code used to reproduce this follows: unsigned * __attribute__((noinline)) start_sequence (unsigned * x, unsigned * y) { return (unsigned *)0xdeadbeef; }; unsigned __attribute__((noinline)) gen_movsd (unsigned * operand0, unsigned * operand1) { return *start_sequence(operand0, operand1); } int main(void) { unsigned x, y; x = 13; y = 14; return (int)gen_movsd (&x, &y); } Basically we have two functions, gen_movsd and start_sequence. Since the argument values for those two functions are not really used, GCC optimizes some of them. Loading the binary on GDB, we step through the code until we reach the "start_sequence" function. It shows the following frame info: #0 - start_sequence (x=, y=0xfffff9b1b34) "x" was originally passed on R3, and it's now lost since the same register was used for the return value (0xdeadbeef) of the "start_sequence" function. This is OK. If we call a backtrace on GDB, that's what we have: #0 - start_sequence (x=, y=0xfffff9b1b34) #1 - gen_movsd (operand0=0xdeadbeef, operand1=0xfffff9b1b34) Notice that on frame #1, "operand0" has a "0xdeadbeef" value, which happens to be the return value from the "start_sequence" function from frame #0. This is clearly incorrect. Stepping a little bit further through the code until we exit from "start_sequence" and fall back into "gen_movsd", we have the following as the frame info: #0 - gen_movsd (operand0=, operand1=) This last frame info is just correct, since both values aren't available anymore. What is causing this incorrect value to be printed on frame levels above 0 is an adjustment to the PC on the "frame_unwind_address_in_block" function. The purpose of this adjustment to PC is to make it point to the branch instruction rather than the instruction right after the branch instruction ( this is achieved with a --pc decrement). This breaks the code that finds the right DWARF expression in the location lists for each argument due to an off-by-1 error. Thus, GDB selects the incorrect DWARF expression and shows the wrong value on backtrace. This patch fixes the problem by adjusting the PC to prevent the off-by-1 problem, thus making GDB select the correct DWARF expression. Another point is that the PC decrement operation on "frame_unwind_address_in_block", as it is now, doesn't make sense if the branch instruction is longer than 1 byte. To make sure that PC points to the branch instruction we must go back the length of the last instruction executed. On ppc this length is fixed, but on other architectures it is not. Comments and suggestions are welcome. Best regards, Luis