From: Luis Machado <luisgpm@linux.vnet.ibm.com>
To: gdb-patches@sources.redhat.com
Subject: [patch] Backtrace prints wrong argument value
Date: Wed, 25 Apr 2007 19:13:00 -0000 [thread overview]
Message-ID: <1177527233.12599.42.camel@localhost> (raw)
[-- 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));
next reply other threads:[~2007-04-25 18:54 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-25 19:13 Luis Machado [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1177527233.12599.42.camel@localhost \
--to=luisgpm@linux.vnet.ibm.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox