public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Complex DWARF expressions
@ 2014-09-21 19:33 Eli Zaretskii
  2014-09-22  6:03 ` Yao Qi
  0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2014-09-21 19:33 UTC (permalink / raw)
  To: gdb

I was debugging a crash in an optimized program, and wanted to know
the value of some variable, but was greeted with "<optimized out>".
So I tried to see if the value is in a register, and this is what I
saw:

  (gdb) info address new_width
  Symbol "new_width" is multi-location:
    Range 0x100a847-0x100a8d9: a variable in $edx
    Range 0x100a8d9-0x100a8e6: a complex DWARF expression:
       0: DW_OP_breg3 176 [$ebx]

    Range 0x100a8e6-0x100a8ee: a complex DWARF expression:
       0: DW_OP_GNU_entry_value
	 2: DW_OP_reg2 [$edx]
       3: DW_OP_stack_value

    Range 0x100a8ee-0x100a955: a variable in $edx
    Range 0x100a955-0x100aaed: a complex DWARF expression:
       0: DW_OP_GNU_entry_value
	 2: DW_OP_reg2 [$edx]
       3: DW_OP_stack_value

    Range 0x100aaed-0x100aaf7: a variable in $edx
    Range 0x100aaf7-0x100ad4c: a complex DWARF expression:
       0: DW_OP_GNU_entry_value
	 2: DW_OP_reg2 [$edx]
       3: DW_OP_stack_value

"A variable in $edx" I understand, but what about the "complex DWARF
expression" parts?  Is there any way a mere mortal such as myself can
decipher this to the effect of understanding in which register or at
what address can I look up the value, assuming that I know at which PC
address the program stopped?

(Yes, I've looked at the DWARF Standard, but couldn't understand from
the description of these location descriptors how to convert them to
either a register or a memory address.)

TIA for any help.

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

* Re: Complex DWARF expressions
  2014-09-21 19:33 Complex DWARF expressions Eli Zaretskii
@ 2014-09-22  6:03 ` Yao Qi
  2014-09-22  6:17   ` Jan Kratochvil
  0 siblings, 1 reply; 7+ messages in thread
From: Yao Qi @ 2014-09-22  6:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

Eli Zaretskii <eliz@gnu.org> writes:

>     Range 0x100aaf7-0x100ad4c: a complex DWARF expression:
>        0: DW_OP_GNU_entry_value
> 	 2: DW_OP_reg2 [$edx]
>        3: DW_OP_stack_value
>
> "A variable in $edx" I understand, but what about the "complex DWARF
> expression" parts?  Is there any way a mere mortal such as myself can
> decipher this to the effect of understanding in which register or at
> what address can I look up the value, assuming that I know at which PC
> address the program stopped?
>
> (Yes, I've looked at the DWARF Standard, but couldn't understand from
> the description of these location descriptors how to convert them to
> either a register or a memory address.)

DW_OP_GNU_entry_value isn't in DWARF Standard and it is documented here
http://www.dwarfstd.org/ShowIssue.php?issue=100909.1

If I understand the doc above correctly, the entry above means if PC is
within range 0x100aaf7-0x100ad4c, the value of new_width is the value of
$edx at the moment entering this function.  IOW, to get value of
new_width, needs to unwind frame and read $edx.

-- 
Yao (齐尧)

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

* Re: Complex DWARF expressions
  2014-09-22  6:03 ` Yao Qi
@ 2014-09-22  6:17   ` Jan Kratochvil
  2014-09-22 18:21     ` Eli Zaretskii
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Kratochvil @ 2014-09-22  6:17 UTC (permalink / raw)
  To: Yao Qi; +Cc: Eli Zaretskii, gdb

On Mon, 22 Sep 2014 07:59:20 +0200, Yao Qi wrote:
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> >     Range 0x100aaf7-0x100ad4c: a complex DWARF expression:
> >        0: DW_OP_GNU_entry_value
> > 	 2: DW_OP_reg2 [$edx]
> >        3: DW_OP_stack_value
> >
> > "A variable in $edx" I understand, but what about the "complex DWARF
> > expression" parts?  Is there any way a mere mortal such as myself can
> > decipher this to the effect of understanding in which register or at
> > what address can I look up the value, assuming that I know at which PC
> > address the program stopped?
> >
> > (Yes, I've looked at the DWARF Standard, but couldn't understand from
> > the description of these location descriptors how to convert them to
> > either a register or a memory address.)
> 
> DW_OP_GNU_entry_value isn't in DWARF Standard and it is documented here
> http://www.dwarfstd.org/ShowIssue.php?issue=100909.1
> 
> If I understand the doc above correctly, the entry above means if PC is
> within range 0x100aaf7-0x100ad4c, the value of new_width is the value of
> $edx at the moment entering this function.  IOW, to get value of
> new_width, needs to unwind frame and read $edx.

But $edx at the caller would be usually callee-clobbered so one would not be
able to read the value.  This is why the caller's call instruction is described
by:

 <8><1663ca>: Abbrev Number: 24 (DW_TAG_GNU_call_site)
    <1663cb>   DW_AT_low_pc      : 0x814d44f
    <1663cf>   DW_AT_abstract_origin: <0x15e7bc>
 <9><1663d8>: Abbrev Number: 3 (DW_TAG_GNU_call_site_parameter)
    <1663d9>   DW_AT_location    : 1 byte block: 52     (DW_OP_reg2 (edx))
    <1663db>   DW_AT_GNU_call_site_value: 1 byte block: 30      (DW_OP_lit0)

So one finds matching DW_TAG_GNU_call_site and then one finds
DW_TAG_GNU_call_site_parameter with matching DW_AT_location there.

These rules have to be applied recursively, as in many cases there is for
example:

 <6><1669c2>: Abbrev Number: 3 (DW_TAG_GNU_call_site_parameter)
    <1669c3>   DW_AT_location    : 1 byte block: 51     (DW_OP_reg1 (ecx))
    <1669c5>   DW_AT_GNU_call_site_value: 7 byte block: f3 1 51 a ff ff 1a      (DW_OP_GNU_entry_value: (DW_OP_reg1 (ecx)); DW_OP_const2u: 65535; DW_OP_and)


Jan

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

* Re: Complex DWARF expressions
  2014-09-22  6:17   ` Jan Kratochvil
@ 2014-09-22 18:21     ` Eli Zaretskii
  2014-09-22 18:44       ` Jan Kratochvil
  0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2014-09-22 18:21 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: yao, gdb

> Date: Mon, 22 Sep 2014 08:16:54 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: Eli Zaretskii <eliz@gnu.org>, gdb@sourceware.org
> 
> But $edx at the caller would be usually callee-clobbered so one would not be
> able to read the value.  This is why the caller's call instruction is described
> by:
> 
>  <8><1663ca>: Abbrev Number: 24 (DW_TAG_GNU_call_site)
>     <1663cb>   DW_AT_low_pc      : 0x814d44f
>     <1663cf>   DW_AT_abstract_origin: <0x15e7bc>
>  <9><1663d8>: Abbrev Number: 3 (DW_TAG_GNU_call_site_parameter)
>     <1663d9>   DW_AT_location    : 1 byte block: 52     (DW_OP_reg2 (edx))
>     <1663db>   DW_AT_GNU_call_site_value: 1 byte block: 30      (DW_OP_lit0)
> 
> So one finds matching DW_TAG_GNU_call_site and then one finds
> DW_TAG_GNU_call_site_parameter with matching DW_AT_location there.
> 
> These rules have to be applied recursively, as in many cases there is for
> example:
> 
>  <6><1669c2>: Abbrev Number: 3 (DW_TAG_GNU_call_site_parameter)
>     <1669c3>   DW_AT_location    : 1 byte block: 51     (DW_OP_reg1 (ecx))
>     <1669c5>   DW_AT_GNU_call_site_value: 7 byte block: f3 1 51 a ff ff 1a      (DW_OP_GNU_entry_value: (DW_OP_reg1 (ecx)); DW_OP_const2u: 65535; DW_OP_and)

Why can't GDB apply all this, and show a value for a given PC?  We
don't really expect anyone but a few DWARF specialists to understand
all that you said above (I, for example, didn't understand any of it),
right?

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

* Re: Complex DWARF expressions
  2014-09-22 18:21     ` Eli Zaretskii
@ 2014-09-22 18:44       ` Jan Kratochvil
  2014-09-22 19:06         ` Eli Zaretskii
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Kratochvil @ 2014-09-22 18:44 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: yao, gdb

On Mon, 22 Sep 2014 20:21:14 +0200, Eli Zaretskii wrote:
> Why can't GDB apply all this, and show a value for a given PC?

There is some reason why GDB could not determine it, this is very normal
situation.  It would be really great if GDB could always display all values
for -O2 -g code but that can never be possible (without reducing runtime code
peformance and size).
To find out why use: (gdb) set debug entry-values 1

For example the call site may not have matching DW_AT_GNU_call_site_value
because the value is just no longer computable at the caller frame from any
data at that point of execution.  Entry values improved the number of cases
where the value is retrievable but it is still far from 100% retrievability.
One needs to use -O0 -g to get the values in 100% of cases.  Debug info never
degrades inferior runtime code performance or size to get better debug info.

Besides that there may be GDB bug.  And there is also at least one GCC bug:
	entry-value: Missing DW_AT_linkage_name for C<->C++ calls
	http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56502


Jan

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

* Re: Complex DWARF expressions
  2014-09-22 18:44       ` Jan Kratochvil
@ 2014-09-22 19:06         ` Eli Zaretskii
  2014-09-22 19:21           ` Jan Kratochvil
  0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2014-09-22 19:06 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: yao, gdb

> Date: Mon, 22 Sep 2014 20:44:12 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: yao@codesourcery.com, gdb@sourceware.org
> 
> On Mon, 22 Sep 2014 20:21:14 +0200, Eli Zaretskii wrote:
> > Why can't GDB apply all this, and show a value for a given PC?
> 
> There is some reason why GDB could not determine it, this is very normal
> situation.  It would be really great if GDB could always display all values
> for -O2 -g code but that can never be possible (without reducing runtime code
> peformance and size).

Are you saying that whenever GDB can successfully interpret this
information and extract a value, it simply shows that value?  If so, I
think we should add to the DWARF gobbledygook a note to the effect
that GDB wasn't able to glean the value from that info, and maybe even
say why (like what info was missing to interpret that).

If the computation is expensive, we could have an option to enable it.
There are situations in debugging when you'd kill to know the value of
some key variable, I'm sure you know this.

And btw, how did you get the information you showed, like this:

>  <8><1663ca>: Abbrev Number: 24 (DW_TAG_GNU_call_site)
>     <1663cb>   DW_AT_low_pc      : 0x814d44f
>     <1663cf>   DW_AT_abstract_origin: <0x15e7bc>
>  <9><1663d8>: Abbrev Number: 3 (DW_TAG_GNU_call_site_parameter)
>     <1663d9>   DW_AT_location    : 1 byte block: 52     (DW_OP_reg2 (edx))
>     <1663db>   DW_AT_GNU_call_site_value: 1 byte block: 30      (DW_OP_lit0)

Can GDB show it (and if so, by which command), or is this from objdump
or some such?

> For example the call site may not have matching DW_AT_GNU_call_site_value
> because the value is just no longer computable at the caller frame from any
> data at that point of execution.  Entry values improved the number of cases
> where the value is retrievable but it is still far from 100% retrievability.

We should say explicitly that GDB is unable to decypher the data,
otherwise what we show the user looks like a teaser.

> One needs to use -O0 -g to get the values in 100% of cases.

When I'm debugging a crash of an optimized binary, and don't yet have
a recipe to reproduce the crash, compiling without optimizations is
not a useful option.

Thanks.

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

* Re: Complex DWARF expressions
  2014-09-22 19:06         ` Eli Zaretskii
@ 2014-09-22 19:21           ` Jan Kratochvil
  0 siblings, 0 replies; 7+ messages in thread
From: Jan Kratochvil @ 2014-09-22 19:21 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: yao, gdb

On Mon, 22 Sep 2014 21:06:30 +0200, Eli Zaretskii wrote:
> Are you saying that whenever GDB can successfully interpret this
> information and extract a value, it simply shows that value?

Yes.


> If so, I think we should add to the DWARF gobbledygook a note to the effect
> that GDB wasn't able to glean the value from that info, and maybe even say
> why (like what info was missing to interpret that).
+
> We should say explicitly that GDB is unable to decypher the data,
> otherwise what we show the user looks like a teaser.

I find the current behavior the right one myself.  There is "info addr"
exactly for the cases of debugging GDB/GCC and/or disassembling inferior code
trying to extract as much information from the crashed state as possible.
Sure feel free to propose any UI changes for GDB.

Maybe "set debug entry-values" could be placed under more user
friendly "info ..." command but then its output would have to be improved from
the current set of scattered debug messages to something more formatted.


> If the computation is expensive, we could have an option to enable it.
> There are situations in debugging when you'd kill to know the value of
> some key variable, I'm sure you know this.

There is no reduction of reported info just to save some GDB computations.
GDB reports all it can.

In general lacking debug info is usually GCC's defect and not GDB's.


> And btw, how did you get the information you showed, like this:
> 
> >  <8><1663ca>: Abbrev Number: 24 (DW_TAG_GNU_call_site)
> >     <1663cb>   DW_AT_low_pc      : 0x814d44f
> >     <1663cf>   DW_AT_abstract_origin: <0x15e7bc>
> >  <9><1663d8>: Abbrev Number: 3 (DW_TAG_GNU_call_site_parameter)
> >     <1663d9>   DW_AT_location    : 1 byte block: 52     (DW_OP_reg2 (edx))
> >     <1663db>   DW_AT_GNU_call_site_value: 1 byte block: 30      (DW_OP_lit0)
> 
> Can GDB show it (and if so, by which command), or is this from objdump
> or some such?

I use "readelf -wi" myself, this is equivalent to "objdump -Wi" for non-ELF
DWARF files.  There is also "eu-readelf -winfo" with slightly different output
formatting.


Jan

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

end of thread, other threads:[~2014-09-22 19:21 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-21 19:33 Complex DWARF expressions Eli Zaretskii
2014-09-22  6:03 ` Yao Qi
2014-09-22  6:17   ` Jan Kratochvil
2014-09-22 18:21     ` Eli Zaretskii
2014-09-22 18:44       ` Jan Kratochvil
2014-09-22 19:06         ` Eli Zaretskii
2014-09-22 19:21           ` Jan Kratochvil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).