public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
* Dwarf expertise needed
@ 2007-06-19 15:22 Sami Wagiaalla
  2007-06-19 15:46 ` Sami Wagiaalla
  0 siblings, 1 reply; 19+ messages in thread
From: Sami Wagiaalla @ 2007-06-19 15:22 UTC (permalink / raw)
  To: frysk

So I have been stuck on a bug to do with inlined functions for a bit. 
Here goes:

Attached are two programs funit-scopes.c, and funit-scopes-works.c. My 
original test case was simmilar to funit-scopes.c. What I would do is 
run the program until it crashes, get a stack back trace, go one frame 
out of the inner most frame, subptract 1 from the pc so that it is 
pointing at something before the return instruction.

Using that frame address I look at the debug info. I get a Die, ask the 
Die for its scopes, and explore upwards in the hierarchy.

For funit-scopes-works.c i get this:
   DW_TAG_inlined_subroutine name: second
   DW_TAG_compile_unit name:

For funit-scopes.c I cannot even get a die corresponding to the frame 
address (I have verified that frame address is between hight_pc, and 
low_pc for that particular expansion of that inlined function ).

Tow questions:
Why doesnt funit-scopes.c work ?
and
Why does funit-scopes-works.c not print the tag for the subroutine 
within wich the function has been inlined ?

funit-scopes is in cvs, and so is TestFrameScopes.java which performs 
the above test.

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

* Re: Dwarf expertise needed
  2007-06-19 15:22 Dwarf expertise needed Sami Wagiaalla
@ 2007-06-19 15:46 ` Sami Wagiaalla
  2007-06-19 18:28   ` Sami Wagiaalla
  0 siblings, 1 reply; 19+ messages in thread
From: Sami Wagiaalla @ 2007-06-19 15:46 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

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

Now the are attached

[-- Attachment #2: funit-scopes.c --]
[-- Type: text/x-csrc, Size: 163 bytes --]

#include <stdlib.h>

void crash(int param1){
  int* a = 0;
  a[0] = param1;
}

inline void second(int w){
  crash(0);
}

int main(){

  second(0);

  return 0;
}


[-- Attachment #3: funit-scopes-works.c --]
[-- Type: text/x-csrc, Size: 192 bytes --]

#include <stdlib.h>

void crash(int param1){
  int* a = 0;
  a[0] = param1;
}

inline void second(int w){
  crash(0);
}

void first(){
  second(0);
}

int main(){

  first(0);

  return 0;
}


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

* Re: Dwarf expertise needed
  2007-06-19 15:46 ` Sami Wagiaalla
@ 2007-06-19 18:28   ` Sami Wagiaalla
  2007-06-19 21:11     ` Sami Wagiaalla
  0 siblings, 1 reply; 19+ messages in thread
From: Sami Wagiaalla @ 2007-06-19 18:28 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

By the way the only difference between the is that in one main calls 
first calls secon calls crash. And in the working one main calls second 
calls crash.

Sami Wagiaalla wrote:
> Now the are attached
> ------------------------------------------------------------------------
>
> #include <stdlib.h>
>
> void crash(int param1){
>   int* a = 0;
>   a[0] = param1;
> }
>
> inline void second(int w){
>   crash(0);
> }
>
> int main(){
>
>   second(0);
>
>   return 0;
> }
>
>   
> ------------------------------------------------------------------------
>
> #include <stdlib.h>
>
> void crash(int param1){
>   int* a = 0;
>   a[0] = param1;
> }
>
> inline void second(int w){
>   crash(0);
> }
>
> void first(){
>   second(0);
> }
>
> int main(){
>
>   first(0);
>
>   return 0;
> }
>
>   

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

* Re: Dwarf expertise needed
  2007-06-19 18:28   ` Sami Wagiaalla
@ 2007-06-19 21:11     ` Sami Wagiaalla
  2007-06-19 21:27       ` Roland McGrath
  0 siblings, 1 reply; 19+ messages in thread
From: Sami Wagiaalla @ 2007-06-19 21:11 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

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

This is a run of the above test-case with more details:

There are two issues:
get_addrdie() does not return the correct die:

calling get_addrdie() with address 0x8048369
returned die: DW_TAG_compile_unit name: 
/to/scratch/swagiaal/frysks/frysk.patches/frysk-core/frysk/pkglibdir/funit-scopes.c

But it can be seen from the attached relevenat debug info that the 
address actually falls within the expanded instance of the inlined function.

The other issue is that in the test case where it works the complete 
hierarchy of scopes is not returned. Is there a bug or what is the 
correct way of getting the hierarchy of scopes that a die belongs to ? 
Frysk uses dwarf_getscopes()
>>   
>> ------------------------------------------------------------------------
>>
>> #include <stdlib.h>
>>
>> void crash(int param1){
>>   int* a = 0;
>>   a[0] = param1;
>> }
>>
>> inline void second(int w){
>>   crash(0);
>> }
>>
>> void first(){
>>   second(0);
>> }
>>
>> int main(){
>>
>>   first(0);
>>
>>   return 0;
>> }


[-- Attachment #2: debug_info --]
[-- Type: text/plain, Size: 1406 bytes --]


The section .debug_info contains:

  Compilation Unit @ offset 0x0:
   Length:        227
   Version:       2
   Abbrev Offset: 0
   Pointer Size:  4
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
     DW_AT_stmt_list   : 0	
     DW_AT_high_pc     : 0x80483aa	
     DW_AT_low_pc      : 0x8048344	
     DW_AT_producer    : (indirect string, offset: 0xbc): GNU C 4.1.1 20070105 (Red Hat 4.1.1-51)	
     DW_AT_language    : 1	(ANSI C)
     DW_AT_name        : (indirect string, offset: 0x62): /to/scratch/swagiaal/frysks/frysk.patches/frysk-core/frysk/pkglibdir/funit-scopes.c	
[...]

 <1><9d>: Abbrev Number: 7 (DW_TAG_subprogram)
     DW_AT_external    : 1	
     DW_AT_name        : (indirect string, offset: 0x5b): second	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 8	
     DW_AT_inline      : 3	(declared as inline and inlined)
 <1><a6>: Abbrev Number: 4 (DW_TAG_subprogram)
     DW_AT_sibling     : <ce>	
     DW_AT_external    : 1	
     DW_AT_name        : (indirect string, offset: 0xb6): first	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 12	
     DW_AT_low_pc      : 0x8048353	
     DW_AT_high_pc     : 0x8048370	
     DW_AT_frame_base  : 0x2c	(location list)
 <2><be>: Abbrev Number: 8 (DW_TAG_inlined_subroutine)
     DW_AT_abstract_origin: <9d>	
     DW_AT_low_pc      : 0x8048365	
     DW_AT_high_pc     : 0x804836a	
     DW_AT_call_file   : 1	
     DW_AT_call_line   : 13	


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

* Re: Dwarf expertise needed
  2007-06-19 21:11     ` Sami Wagiaalla
@ 2007-06-19 21:27       ` Roland McGrath
  2007-06-19 21:31         ` Sami Wagiaalla
  2007-06-19 21:58         ` Sami Wagiaalla
  0 siblings, 2 replies; 19+ messages in thread
From: Roland McGrath @ 2007-06-19 21:27 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

> get_addrdie() does not return the correct die:

The libdw and libdwfl functions called "addrdie" give you the CU containing
that address, as they are described to do.  It sounds like you are
expecting something different.

> The other issue is that in the test case where it works the complete 
> hierarchy of scopes is not returned. Is there a bug or what is the 
> correct way of getting the hierarchy of scopes that a die belongs to ? 
> Frysk uses dwarf_getscopes()

dwarf_getscopes is the right call to use to get specific information about
a PC address, which it sounds like you expected is what "addrdie" meant.

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=230235 is outstanding
and I have not had the chance to look into it.  It is probably related.

To test dwarf_getscopes, please run tests/addrscopes from your elfutils
build, i.e.:

	./tests/addrscopes -e executable-file 0x123 0x456 

if 0x123 and 0x456 are the PC values of interest.

Put the exact command line you used in the bug report and attach your
actual executable file (not just source).  


Thanks,
Roland

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

* Re: Dwarf expertise needed
  2007-06-19 21:31         ` Sami Wagiaalla
@ 2007-06-19 21:31           ` Roland McGrath
  2007-07-17 17:07             ` Sami Wagiaalla
  2007-06-19 21:38           ` Sami Wagiaalla
  1 sibling, 1 reply; 19+ messages in thread
From: Roland McGrath @ 2007-06-19 21:31 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

> Okay it sounds like I missunderstood what addrdie does. I guess what I 
> am trying to do is find the narrowest scope which contains the given pc. 
> Is there a way to get all dies whos ranges contain the pc maybe ? The 
> problem I am trying to solve is given a pc find the inlined/concrete 
> function that contains it.

This is what dwarf_getscopes is for.

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

* Re: Dwarf expertise needed
  2007-06-19 21:27       ` Roland McGrath
@ 2007-06-19 21:31         ` Sami Wagiaalla
  2007-06-19 21:31           ` Roland McGrath
  2007-06-19 21:38           ` Sami Wagiaalla
  2007-06-19 21:58         ` Sami Wagiaalla
  1 sibling, 2 replies; 19+ messages in thread
From: Sami Wagiaalla @ 2007-06-19 21:31 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk


>> get_addrdie() does not return the correct die:
>>     
>
> The libdw and libdwfl functions called "addrdie" give you the CU containing
> that address, as they are described to do.  It sounds like you are
> expecting something different.
>   
Okay it sounds like I missunderstood what addrdie does. I guess what I 
am trying to do is find the narrowest scope which contains the given pc. 
Is there a way to get all dies whos ranges contain the pc maybe ? The 
problem I am trying to solve is given a pc find the inlined/concrete 
function that contains it.

Thanx,
  Sami

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

* Re: Dwarf expertise needed
  2007-06-19 21:31         ` Sami Wagiaalla
  2007-06-19 21:31           ` Roland McGrath
@ 2007-06-19 21:38           ` Sami Wagiaalla
  1 sibling, 0 replies; 19+ messages in thread
From: Sami Wagiaalla @ 2007-06-19 21:38 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: Roland McGrath, frysk

Sami Wagiaalla wrote:
>
>>> get_addrdie() does not return the correct die:
>>>     
>>
>> The libdw and libdwfl functions called "addrdie" give you the CU 
>> containing
>> that address, as they are described to do.  It sounds like you are
>> expecting something different.
>>   
> Okay it sounds like I missunderstood what addrdie does. I guess what I 
> am trying to do is find the narrowest scope which contains the given 
> pc. Is there a way to get all dies whos ranges contain the pc maybe ? 
> The problem I am trying to solve is given a pc find the 
> inlined/concrete function that contains it.
nm... i didnt realize you could use get_scopes with an address.... I'll 
update the bug
>
> Thanx,
>  Sami

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

* Re: Dwarf expertise needed
  2007-06-19 21:27       ` Roland McGrath
  2007-06-19 21:31         ` Sami Wagiaalla
@ 2007-06-19 21:58         ` Sami Wagiaalla
  1 sibling, 0 replies; 19+ messages in thread
From: Sami Wagiaalla @ 2007-06-19 21:58 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk


> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=230235 is outstanding
> and I have not had the chance to look into it.  It is probably related.
>
> To test dwarf_getscopes, please run tests/addrscopes from your elfutils
> build, i.e.:
>
> 	./tests/addrscopes -e executable-file 0x123 0x456 
>
> if 0x123 and 0x456 are the PC values of interest.
>
> Put the exact command line you used in the bug report and attach your
> actual executable file (not just source).  
>   
Done.. thanks Roland
  Sami

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

* Re: Dwarf expertise needed
  2007-06-19 21:31           ` Roland McGrath
@ 2007-07-17 17:07             ` Sami Wagiaalla
  2007-07-18  9:03               ` Roland McGrath
  0 siblings, 1 reply; 19+ messages in thread
From: Sami Wagiaalla @ 2007-07-17 17:07 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk

Roland McGrath wrote:
>> Okay it sounds like I missunderstood what addrdie does. I guess what I 
>> am trying to do is find the narrowest scope which contains the given pc. 
>> Is there a way to get all dies whos ranges contain the pc maybe ? The 
>> problem I am trying to solve is given a pc find the inlined/concrete 
>> function that contains it.
>>     
>
> This is what dwarf_getscopes is for.
>   
Okay so I have been looking at dwarf_getscopes.c trying to find a fix 
for  https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=230235.

Now i can fudge the function pc_record to return the results that I am 
expecting but it looks like it is trying to do something different from 
what I understand when it comes to inlined functions.

It looks like getscopes is trying to return the scopes from narrowest up 
to the scope before the concrete inlined instance then the abstract 
definition of the concrete instance, and then the scopes that contain 
that. Is this a correct understanding of the code ?

What I am expecting it to return is the the scopes from narrowest to and 
including the scope corresponding to the concrete inlined instance, then 
the function within which it has been inlined and the scopes containing 
that; as per the dwarf spec. Is this a correct understanding of what the 
function /should/ do ? And should I fix the function, write a parallel 
one that does what i want, or is there another code pathway to get it ?


Cheers,
   Sami Wagiaalla

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

* Re: Dwarf expertise needed
  2007-07-17 17:07             ` Sami Wagiaalla
@ 2007-07-18  9:03               ` Roland McGrath
  2007-07-18 15:38                 ` Sami Wagiaalla
  2007-07-19 15:40                 ` Sami Wagiaalla
  0 siblings, 2 replies; 19+ messages in thread
From: Roland McGrath @ 2007-07-18  9:03 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

> Okay so I have been looking at dwarf_getscopes.c trying to find a fix 
> for  https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=230235.

I have not had my head in that particular code in quite some time, and I
have not yet looked at all what's going on in Stan's test case.  Before any
bugs were reported, I already knew there were some issues with the function
from the time I wrote it, which relate to the distinction you are asking about.

> It looks like getscopes is trying to return the scopes from narrowest up 
> to the scope before the concrete inlined instance then the abstract 
> definition of the concrete instance, and then the scopes that contain 
> that. Is this a correct understanding of the code ?
> 
> What I am expecting it to return is the the scopes from narrowest to and 
> including the scope corresponding to the concrete inlined instance, then 
> the function within which it has been inlined and the scopes containing 
> that; as per the dwarf spec. Is this a correct understanding of what the 
> function /should/ do ? And should I fix the function, write a parallel 
> one that does what i want, or is there another code pathway to get it ?

I don't know why you call that "as per the dwarf spec".  (The spec says
what the format means, not what any function does.)

The chief purpose of dwarf_getscopes is to get the lexical scope DIEs
containing the PC, from innermost to outermost.  This means the literal
lexical scope, i.e. for C-like syntax { } groups in the text.  In the
case of a PC inside a concrete inlined instance, it's still the literal
lexical scope of that function.  The lexical scope as expressed by the
generic DWARF structure corresponds exactly to the identifier scope
rules of a simple language like C.  So this is what you need to pass to
dwarf_getscopevar to resolve a C identifier at the scope of this PC.
Take the example:

	static int cu_var = 1;
	inline int a_fn (int a_arg)
	{
	  static int a_var = 1;
 PC1-->	  return ++a_var + a_arg + ++cu_var;
	}

	int b_fn ()
	{
	  static int b_var = 2;
	  int c_fn ()
	  {
	    static int c_var = 3;
	    c_var += a_fn (b_var++);
 PC2-->	    return c_var;
	  }
	  return c_fn ();
	}

The DWARF structure here will look like (much omitted):

<CU>	compile_unit "foo.c"
		variable "cu_var"
<A>		subprogram "a_fn"	<-- abstract inlined instance
			formal_parameter "a_arg"    ^  <--
 				type	 	    |     `
			variable "a_var"    	    |     |
				type		    |	  |
				location 	    |     |
<B>		subprogram "b_fn"		    |     |
			variable "b_var"	    |     |
<C>			subprogram "c_fn"	    |     |
				frame_base	    |	  |
				variable "c_var"    |     |
<C_A>				inlined_subroutine -'     |  <-- concrete
					low_pc PC1        |  	 inlined
					formal_parameter -'	 instance
						location

(My pretty lines indicate DIEs with an abstract_origin ref to another DIE.)

For PC2, dwarf_getscopes should yield [<C>, <B>, <CU>].
For PC1, dwarf_getscopes should yield [<C_A>, <A>, <CU>].

<C_A> is physically inside <C>, but it is lexically where <A> is.  In the
scope context of PC1 (<C_A>), "a_var" is visible and "cu_var" is visible,
but "b_var" and "c_var" are not.  

<C_A> has its own DIE for "a_arg" because its DW_AT_location details are
specific to the concrete inlined instance.  (That one a partial DIE, it has
location but refers to its abstract counterpart for invariant attributes
like type.)  But <C_A> elides the "a_var" DIE entirely because it is the
same for all possible concrete instances of <A>.  This is why <A> appears
as a scope outside <C_A>, or rather, it's why <C_A> appears as a scope
inside <A>.  <C_A> is not really a lexical scope at all, just a physical
instance.  For naive uses like dwarf_getscopevar, it works fine to treat
<C_A> as a scope inside <A>.  But any sophisticated caller needs to check
each "scope" DIE in the array for actually being an inlined_subroutine,
meaning that its containing scope is not really a different scope, but the
two together describe one lexical scope.  e.g., something visualizing
scopes and showing all the identifiers defined in each scope would need to
grok this.

Now imagine "a_var" is called "b_var" and "cu_var" is called "c_var", so it
really matters which scope you mean when you ask for "c_var" by name.  You
can see why it's vital that for "identifiers visible at the PC1 context",
you not be looking at a list that includes <B> or <C>.

So that covers what "return scopes containing" should mean, and what
dwarf_getscopes is intended to do in the interface it has now.  Note that
this is only the beginning of the story for mapping an identifier in a
scope to a DIE in general, though it's the end of the story for C.  In a
language like C++, the literal lexical scope list from dwarf_getscopes
feeds into a language-specific identifier scope engine that knows that
the DIE for a method definition is a scope that can see identifiers from
its class as well as from its lexically containing scope (e.g. the
CU)--which is different from its class DIE being its lexical container,
which it may or may not be.

Now, the trouble with this highly sensical picture comes when you get to
the nitty-gritty of making use of the DIEs you found in those scopes.
It turns out that sometimes you need to know something about the
physical structure of the code, not just the semantic lexical scope.
Say you're at ye olde PC1 and you want to see "a_arg".  Great, it's in
<C_A>.  Now this bugger's location attribute says {DW_OP_fbreg(+24)}.
Well, whose frame_base did he mean?  He meant <C>'s.  But I just
convinced you that <C> better be nowhere in your handy list of DIEs to
consult!

If you take all this and contemplate all the permutations of inlining and
nested functions there could be, it's rather mindbending.  My mind was
bent in this way while writing the function, and I still kept thinking it
could be done with the simple interface yielding one ordered list of
DIEs.  In that frame of mind, I wrote and tweaked and rewrote to whatever
it actually does now, and goodness knows what exactly that came out to
be.  After a libdw with this interface got released, I realized it just
can't do it all for all cases with that interface.  I had other fish to
fry and let it lie, but knew I would have to revisit it and get it all
clear at some point.

Contemplating it now, I don't think it is really so quite confusing what's
required, at least for frame_base.  I probably need to think more about the
nested function cases, and might confuse myself again doing it.  I also
haven't thought of anything other than frame_base that a dwarf_getscopes
caller might need from a physically relevant but lexically disjoint DIE.
Something else I'm overlooking might have different requirements.  To get
the right frame_base, I think a straightforward change of the getscopes
interface can cover it.  As well as the array of lexical scope DIEs, it
would yield a parallel array of Dwarf_Die pointers.  Each scope[i]
corresponds to base_scope[i].  Locations from scope[i] are resolved in the
physical context of base_scope[i].  For simple cases, scope[i]==base_scope[i].
When scope[i] is an inlined_subroutine, base_scope[i] is the containing
subprogram that has the actual code.  So, in all cases, base_scope[i] is
where you need to look for a frame_base attribute when scope[i] leads you to
a location that uses frame_base.

But I'd like to try to think of other things than frame_base one might
need, and think through the nested function cases, before deciding what
exact change the interface should get.

Right now, if your test cases do not require the frame_base attribute,
then we can just work on fixing any bugs in the implementation of the
current definition of the dwarf_getscopes interface as I described it above.  

dwarf_getscopes has always been for the source-level semantic view of
lexical identifier scope.  For other purposes, you might instead be
looking for the physical structural view of the compiled code.  For
example, if you are displaying the running code in an inlined instance
and want to visualize "this code inlined into here", or are synthesizing
fictional call frames for a semantic backtrace including inlined calls.
(If you are only displaying the source location of the caller, you have
the call_{file,line,column} attributes at hand and don't need the
caller's DIE at all.)  dwarf_getscopes_die does exactly this, though its
name and comments would lead you to think it acts like dwarf_getscopes
when given a DIE that is part of a concrete inlined instance tree.
(That's what it probably should do, and there should be a different call
for the simple structural visitor.)  So with 0.128 code, you can use
dwarf_getscopes on a PC, then take a scope[i] of interest such as an
inlined_subroutine DIE, and pass it to dwarf_getscopes_die to see its
caller's scope context.


Thanks,
Roland

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

* Re: Dwarf expertise needed
  2007-07-18  9:03               ` Roland McGrath
@ 2007-07-18 15:38                 ` Sami Wagiaalla
  2007-07-18 22:43                   ` Roland McGrath
  2007-07-19 15:40                 ` Sami Wagiaalla
  1 sibling, 1 reply; 19+ messages in thread
From: Sami Wagiaalla @ 2007-07-18 15:38 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk

Roland,

First of all thank you for the thorough reply. I now see issues that I 
have not seen before.

Roland McGrath wrote:
>> What I am expecting it to return is the the scopes from narrowest to and 
>> including the scope corresponding to the concrete inlined instance, then 
>> the function within which it has been inlined and the scopes containing 
>> that; as per the dwarf spec. Is this a correct understanding of what the 
>> function /should/ do ? And should I fix the function, write a parallel 
>> one that does what i want, or is there another code pathway to get it ?
>>     
>
> I don't know why you call that "as per the dwarf spec".  (The spec says
> what the format means, not what any function does.)
>   
I just meant to say "scope" in the dwarf spec sense, as opposed to 
lexical scope.

[...]
> Contemplating it now, I don't think it is really so quite confusing what's
> required, at least for frame_base.  I probably need to think more about the
> nested function cases, and might confuse myself again doing it.  I also
> haven't thought of anything other than frame_base that a dwarf_getscopes
> caller might need from a physically relevant but lexically disjoint DIE.
> Something else I'm overlooking might have different requirements.  To get
> the right frame_base, I think a straightforward change of the getscopes
> interface can cover it.  As well as the array of lexical scope DIEs, it
> would yield a parallel array of Dwarf_Die pointers.  Each scope[i]
> corresponds to base_scope[i].  Locations from scope[i] are resolved in the
> physical context of base_scope[i].  For simple cases, scope[i]==base_scope[i].
> When scope[i] is an inlined_subroutine, base_scope[i] is the containing
> subprogram that has the actual code.  So, in all cases, base_scope[i] is
> where you need to look for a frame_base attribute when scope[i] leads you to
> a location that uses frame_base.
>
> But I'd like to try to think of other things than frame_base one might
> need, and think through the nested function cases, before deciding what
> exact change the interface should get.
>   
That is cool.

If it turns out that frame_base is the only instance then how about a 
function get_framebase that is smart enough to figure out where the 
correct frame base is. That way you help the client not make that 
mistake. Or get_* for each attribute that needs the abstract instance of 
the function.


> Right now, if your test cases do not require the frame_base attribute,
> then we can just work on fixing any bugs in the implementation of the
> current definition of the dwarf_getscopes interface as I described it above.  
>
> dwarf_getscopes has always been for the source-level semantic view of
> lexical identifier scope.  For other purposes, you might instead be
> looking for the physical structural view of the compiled code.  For
> example, if you are displaying the running code in an inlined instance
> and want to visualize "this code inlined into here", or are synthesizing
> fictional call frames for a semantic backtrace including inlined calls.
> (If you are only displaying the source location of the caller, you have
> the call_{file,line,column} attributes at hand and don't need the
> caller's DIE at all.)  dwarf_getscopes_die does exactly this, though its
> name and comments would lead you to think it acts like dwarf_getscopes
> when given a DIE that is part of a concrete inlined instance tree.
> (That's what it probably should do, and there should be a different call
> for the simple structural visitor.)  So with 0.128 code, you can use
> dwarf_getscopes on a PC, then take a scope[i] of interest such as an
> inlined_subroutine DIE, and pass it to dwarf_getscopes_die to see its
> caller's scope context.
>   
That will do, although I think there might be a bug there :(. Let me 
double check.

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

* Re: Dwarf expertise needed
  2007-07-18 15:38                 ` Sami Wagiaalla
@ 2007-07-18 22:43                   ` Roland McGrath
  2007-07-19 15:31                     ` Sami Wagiaalla
  0 siblings, 1 reply; 19+ messages in thread
From: Roland McGrath @ 2007-07-18 22:43 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

> First of all thank you for the thorough reply. I now see issues that I 
> have not seen before.

I think I'll have that on my tombstone. ;-)

> If it turns out that frame_base is the only instance then how about a 
> function get_framebase that is smart enough to figure out where the 
> correct frame base is. That way you help the client not make that 
> mistake. Or get_* for each attribute that needs the abstract instance of 
> the function.

For attributes in general it's easy, you just use dwarf_attr_integrate.
For elided children I don't have a handy helper yet, but it is
straightforward to follow the abstract_origin reference and go from there.

The frame_base case is on the other side of exactly the distinction I
pointed out.  It has nothing to do with the abstract instance, and only to
do with the physical parent of the particular concrete instance.  Figuring
it out requires a tree walk to find the parent.  

It makes sense to fetch that as part of the same operation as something
like getscopes primarily because that same tree walk is already being done.
I've imagined there might in future be some libdw optimizations that would
preserve some back-pointers to make it efficient to go up the tree, though
I certainly haven't figured out all the details of that.  So it might make
sense to use a separate call for this with the expectation that its
expensive repeat of the tree walk will be optimized in the future, but I'm
not quite sure.  I'd still like to contemplate the potential related cases
a bit more.

> That will do, although I think there might be a bug there :(. Let me 
> double check.

There is certainly a bug hit by Stan's test case, since it gets an error.


Thanks,
Roland

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

* Re: Dwarf expertise needed
  2007-07-18 22:43                   ` Roland McGrath
@ 2007-07-19 15:31                     ` Sami Wagiaalla
  2007-07-21  0:29                       ` Roland McGrath
  0 siblings, 1 reply; 19+ messages in thread
From: Sami Wagiaalla @ 2007-07-19 15:31 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk

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


>> That will do, although I think there might be a bug there :(. Let me 
>> double check.
>>     
>
> There is certainly a bug hit by Stan's test case, since it gets an error.
>   
So yes there is a bug, I have not checked to see if it is Stan's bug, 
but here it goes:

This is the test case that I am using:

inline void second(){
  int* a = 0;
  a[0] = 0;          <-------- pc
}

void first(){
  second();
}

int main(){
  first();
  return 0;
}

So if I try to dwarf_getscopes at pc i get 0 scopes returned. The 
problem is in the pc_record function from dwarf_getscopes.c:

>  /* Now we are in a scope that contains the concrete inlined instance.
>     Search it for the inline function's abstract definition.
>     If we don't find it, return to search the containing scope.
>     If we do find it, the nonzero return value will bail us out
>     of the postorder traversal.  */
>  return __libdw_visit_scopes (depth, die, &origin_match, NULL, &a);
> }
The problem is that if the die passed to __libdw_visit_scopes has no 
children, __libdw_visit_scopes returns -1 which means that pc_record 
returns -1 and the search aborts, and no scopes are returned.

The particular childless die in this case happens to be the one 
corresponding to main. I can fudge it by adding some variables to main 
and get the following scopes:

scopes[0] DW_TAG_lexical_block name:
scopes[1] DW_TAG_inlined_subroutine name: second
scopes[2] DW_TAG_compile_unit name: 
/to/scratch/swagiaal/frysks/frysk/frysk-core/frysk/pkglibdir/funit-scopes.c

I have attached two of possible patches:

patch1 just check for children before the call, patch2 takes the 
responsibility away from pc_record and relies on the later call to 
pc_origin in dwarf_getscopes:

[...]
int result = __libdw_visit_scopes (0, &cu, &pc_match, &pc_record, &a);

if (result == 0 && a.scopes != NULL)
  result = __libdw_visit_scopes (0, &cu, &origin_match, NULL, &a);
[...]

I personally like patch2 better. This way you only do two searches.

Thoughts ?

Thanks,
  Sami Wagiaalla

[-- Attachment #2: patch1 --]
[-- Type: text/plain, Size: 713 bytes --]

Index: libdw/dwarf_getscopes.c
===================================================================
RCS file: /cvs/frysk/frysk-imports/elfutils/libdw/dwarf_getscopes.c,v
retrieving revision 1.3
diff -u -r1.3 dwarf_getscopes.c
--- libdw/dwarf_getscopes.c	26 Apr 2007 15:18:42 -0000	1.3
+++ libdw/dwarf_getscopes.c	19 Jul 2007 15:22:53 -0000
@@ -170,6 +170,10 @@
     /* Not there yet.  */
     return 0;
 
+  struct Dwarf_Die_Chain child;
+  if (INTUSE(dwarf_child) (&die->die, &child.die) != 0)
+    return 0;
+
   /* Now we are in a scope that contains the concrete inlined instance.
      Search it for the inline function's abstract definition.
      If we don't find it, return to search the containing scope.

[-- Attachment #3: patch2 --]
[-- Type: text/plain, Size: 1073 bytes --]

Index: libdw/dwarf_getscopes.c
===================================================================
RCS file: /cvs/frysk/frysk-imports/elfutils/libdw/dwarf_getscopes.c,v
retrieving revision 1.3
diff -u -r1.3 dwarf_getscopes.c
--- libdw/dwarf_getscopes.c	26 Apr 2007 15:18:42 -0000	1.3
+++ libdw/dwarf_getscopes.c	19 Jul 2007 15:24:47 -0000
@@ -159,23 +159,8 @@
 	return -1;
       return 0;
     }
-
-
-  /* We've recorded the scopes back to one that is a concrete inlined
-     instance.  Now return out of the traversal back to the scope
-     containing that instance.  */
-
-  assert (a->inlined);
-  if (depth >= a->inlined)
-    /* Not there yet.  */
-    return 0;
-
-  /* Now we are in a scope that contains the concrete inlined instance.
-     Search it for the inline function's abstract definition.
-     If we don't find it, return to search the containing scope.
-     If we do find it, the nonzero return value will bail us out
-     of the postorder traversal.  */
-  return __libdw_visit_scopes (depth, die, &origin_match, NULL, &a);
+  
+  return 0;
 }
 
 

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

* Re: Dwarf expertise needed
  2007-07-18  9:03               ` Roland McGrath
  2007-07-18 15:38                 ` Sami Wagiaalla
@ 2007-07-19 15:40                 ` Sami Wagiaalla
  1 sibling, 0 replies; 19+ messages in thread
From: Sami Wagiaalla @ 2007-07-19 15:40 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk


> [...] if you are displaying the running code in an inlined instance
> and want to visualize "this code inlined into here",
In the future we are going to do that.
>  or are synthesizing
> fictional call frames for a semantic backtrace including inlined calls.
>   
This is what I am currently doing :).

But something else just occurred to me. The way I find a function 
(regular not inlined ) corresponding to a frame is I call 
dwarf_getscopes at frame address, then traverse up the scopes list until 
I hit the first DW_TAG_Subprogram. For this I will also need a physical 
scope list rather than a lexical one, because if a function in the list 
happens to be inlined between the narrowest scope and the Subprogram I 
will not find the reference to my Subprogram.

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

* Re: Dwarf expertise needed
  2007-07-19 15:31                     ` Sami Wagiaalla
@ 2007-07-21  0:29                       ` Roland McGrath
  2007-07-26 15:42                         ` Sami Wagiaalla
  0 siblings, 1 reply; 19+ messages in thread
From: Roland McGrath @ 2007-07-21  0:29 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

> This is the test case that I am using:
> 
> inline void second(){
>   int* a = 0;
>   a[0] = 0;          <-------- pc
> }
> 
> void first(){
>   second();
> }
> 
> int main(){
>   first();
>   return 0;
> }

You need to give me a binary, or at least exact compiler version, arch, and
options.  A binary is really better, so we can be sure what we are talking
about, can refer to precise addresses and DIEs, etc.


Thanks,
Roland

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

* Re: Dwarf expertise needed
  2007-07-21  0:29                       ` Roland McGrath
@ 2007-07-26 15:42                         ` Sami Wagiaalla
  2007-08-07  9:04                           ` Roland McGrath
  0 siblings, 1 reply; 19+ messages in thread
From: Sami Wagiaalla @ 2007-07-26 15:42 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk

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


> You need to give me a binary, or at least exact compiler version, arch, and
> options.  A binary is really better, so we can be sure what we are talking
> about, can refer to precise addresses and DIEs, etc.
>   
Sounds good,

I have attached the executable.

I am looking at this address 0x8048386:

./tests/addrscopes -e ../../frysk-core/frysk/pkglibdir/funit-scopes 
0x8048386
./tests/addrscopes: dwarf_getscopes: .debug_ranges section missing

Sami

[-- Attachment #2: funit-scopes --]
[-- Type: application/octet-stream, Size: 6653 bytes --]

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

* Re: Dwarf expertise needed
  2007-07-26 15:42                         ` Sami Wagiaalla
@ 2007-08-07  9:04                           ` Roland McGrath
  2007-08-09 17:06                             ` Sami Wagiaalla
  0 siblings, 1 reply; 19+ messages in thread
From: Roland McGrath @ 2007-08-07  9:04 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: frysk

> I am looking at this address 0x8048386:
> 
> ./tests/addrscopes -e ../../frysk-core/frysk/pkglibdir/funit-scopes 
> 0x8048386
> ./tests/addrscopes: dwarf_getscopes: .debug_ranges section missing
 
I have a fix for this case, but it is not exactly the same bug as Stan's case,
the oriiginal https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=230235
though you added your report there.

I'm still looking at the original test cases.


Thanks,
Roland

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

* Re: Dwarf expertise needed
  2007-08-07  9:04                           ` Roland McGrath
@ 2007-08-09 17:06                             ` Sami Wagiaalla
  0 siblings, 0 replies; 19+ messages in thread
From: Sami Wagiaalla @ 2007-08-09 17:06 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk

Roland McGrath wrote:
>> I am looking at this address 0x8048386:
>>
>> ./tests/addrscopes -e ../../frysk-core/frysk/pkglibdir/funit-scopes 
>> 0x8048386
>> ./tests/addrscopes: dwarf_getscopes: .debug_ranges section missing
>>     
>  
> I have a fix for this case, but it is not exactly the same bug as Stan's case,
> the oriiginal https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=230235
> though you added your report there.
>
> I'm still looking at the original test cases.
>   
Sweet!.. Yea there was a long period between when I edited the bug 
report and when I actually looked into it and realized its different.

Thanks,
  Sami

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

end of thread, other threads:[~2007-08-09 17:06 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-19 15:22 Dwarf expertise needed Sami Wagiaalla
2007-06-19 15:46 ` Sami Wagiaalla
2007-06-19 18:28   ` Sami Wagiaalla
2007-06-19 21:11     ` Sami Wagiaalla
2007-06-19 21:27       ` Roland McGrath
2007-06-19 21:31         ` Sami Wagiaalla
2007-06-19 21:31           ` Roland McGrath
2007-07-17 17:07             ` Sami Wagiaalla
2007-07-18  9:03               ` Roland McGrath
2007-07-18 15:38                 ` Sami Wagiaalla
2007-07-18 22:43                   ` Roland McGrath
2007-07-19 15:31                     ` Sami Wagiaalla
2007-07-21  0:29                       ` Roland McGrath
2007-07-26 15:42                         ` Sami Wagiaalla
2007-08-07  9:04                           ` Roland McGrath
2007-08-09 17:06                             ` Sami Wagiaalla
2007-07-19 15:40                 ` Sami Wagiaalla
2007-06-19 21:38           ` Sami Wagiaalla
2007-06-19 21:58         ` Sami Wagiaalla

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).