Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [patch] Backtrace prints wrong argument value
@ 2007-04-25 19:13 Luis Machado
  2007-04-25 19:25 ` Daniel Jacobowitz
  0 siblings, 1 reply; 32+ messages in thread
From: Luis Machado @ 2007-04-25 19:13 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2848 bytes --]

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=<value optimized out>, 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=<value optimized out>, 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=<value optimized out>, operand1=<value
optimized out>)

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

[-- Attachment #2: wrong_backtrace_argument.diff --]
[-- Type: text/x-patch, Size: 1292 bytes --]

2007-04-25  Luis Machado  <luisgpm@br.ibm.com>

	* dwarf2loc.c (loclist_read_variable): Corrected the PC value
	before calling the find_location_expression function

Index: gdb/dwarf2loc.c
===================================================================
--- gdb.orig/dwarf2loc.c	2007-04-25 10:29:05.000000000 -0700
+++ gdb/dwarf2loc.c	2007-04-25 11:04:55.000000000 -0700
@@ -528,9 +528,20 @@
   gdb_byte *data;
   size_t size;
 
+/* If the current Frame Level is 0, we pass the unmodified PC, but if the
+   Frame Level is greater than 0, we must adjust the PC by 1 since it was
+   decremented by get_frame_address_in_block() to be more intuitive to the
+   user (to point at the branch instruction rather than the instruction right 
+   after the branch. Due to this adjusting, the Location List has an off-by-1 
+   error when checking the PC. This could cause wrong argument values to be 
+   shown. */
+
   data = find_location_expression (dlbaton, &size,
-				   frame ? get_frame_address_in_block (frame)
-				   : 0);
+          frame ?
+          (frame_relative_level(frame)? (get_frame_address_in_block(frame) + sizeof(CORE_ADDR))
+          : get_frame_address_in_block(frame))
+          : 0);
+
   if (data == NULL)
     {
       val = allocate_value (SYMBOL_TYPE (symbol));

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2007-10-24 22:23 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-25 19:13 [patch] Backtrace prints wrong argument value Luis Machado
2007-04-25 19:25 ` Daniel Jacobowitz
2007-04-25 22:28   ` Luis Machado
2007-04-30 13:31     ` Luis Machado
2007-05-16  5:34   ` Luis Machado
2007-05-16 14:43     ` Daniel Jacobowitz
2007-05-16 15:20       ` Luis Machado
2007-05-16 15:23         ` Daniel Jacobowitz
2007-09-13 14:47       ` Luis Machado
2007-09-16 19:45         ` Daniel Jacobowitz
2007-09-17 13:05           ` Luis Machado
2007-09-17 13:15             ` Daniel Jacobowitz
2007-09-17 13:30               ` Luis Machado
2007-09-17 13:37                 ` Daniel Jacobowitz
2007-09-17 13:46                   ` Luis Machado
2007-09-17 14:00                   ` Luis Machado
2007-09-17 14:04                     ` Daniel Jacobowitz
2007-09-17 16:02                       ` Luis Machado
2007-09-17 17:15                       ` Luis Machado
2007-09-17 17:18                         ` Daniel Jacobowitz
2007-09-17 17:34                           ` Luis Machado
2007-09-17 17:48                             ` Daniel Jacobowitz
2007-10-03 14:58                               ` Luis Machado
2007-10-21 21:41                           ` Luis Machado
2007-10-22  0:03                             ` Joel Brobecker
2007-10-22  1:20                               ` Daniel Jacobowitz
2007-10-22  4:11                                 ` Joel Brobecker
2007-10-24 20:50                                   ` Daniel Jacobowitz
2007-10-24 20:59                                     ` Joel Brobecker
2007-10-24 21:01                                       ` Daniel Jacobowitz
2007-10-24 22:23                                     ` Pedro Alves
2007-10-24 22:38                                       ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox