This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Crash Feature to print dwarf debugging information


Sharyathi Nagesh wrote:
>    Since I was not able to find a good documentation I was not able to 
> validate the code design. If some one can review and provide me guidance 
> it will help me immensely.
>     Challenges are
>     a. Efficient way of accessing the function/subprogram DIE (Debug 
> Information Entry) in an executable that contains multiple Complier 
> Units (CU)
>     b. Is the sequence of dwarf API calls appropriate

I think you shouldn't be using <libdwarf.h>, but rather <libdw.h>.

In fact, you might want to look at libdwfl, which might be a better 
match for what you do.  I know it supports common core files directly, 
but I don't how and if vmcore files differ from that, so you may end up 
having to write some support code yourself.  I don't know much about 
this library though, so will stick with <libdw.h>.

Also, use <gelf.h>, it will let you handle 32bit as well as 64bit ELF 
data structures transparently.

dwarf_begin_elf will give you Dwarf *dbg that you can work with further. 
  You can that use dwarf_nextcu to iterate CUs and dwarf_offdie to get 
CU DIE of each CU:

	Dwarf_Off cu_off = 0, next_off;
	size_t header_size;
	while (!dwarf_nextcu (dbg, cu_off, &next_off, &header_size,
			      NULL, NULL, NULL)) {
		Dwarf_Die cudie;
		if (!dwarf_offdie (dbg, cu_off + header_size, &cudie))
			return 0;

		/* per-CU processing here, for example: */
		int each_fun (Dwarf_Die *die, void *spaces) {
			Dwarf_Attribute attr;
			if (dwarf_attr (die, DW_AT_name, &attr) != NULL)
				printf ("%s%s\n", spaces,
					dwarf_formstring (&attr)
					?: "???");
			return DWARF_CB_OK;
		}
		each_fun (&cudie, "");
		dwarf_getfuncs (&cudie, each_fun, "  ", 0);

		cu_off = next_off;
	}

The example above will list names of all CUs and for each of them give a 
list of functions defined therein.  each_fun is a callback, which I 
abuse to also print out CU names.  You would put your per-function 
processing there and likely not call it for CU DIE itself.

>     c. Scalability of the application, especially architecture dependency

The above should work pretty much everywhere.

> 2. Converting the address mentioned in DW_AT_location to actual address 
> of the local variable/arguments. System tap function 
> literal_stmt_for_local() has an implementation for this, I am going 
> thorough this some help in this direction will help me immensly.

I don't know any deep secrets about this.  dwarf_getlocation_addr looks 
to me like the right function to call to get hands on stream of location 
operands for given DIE.  The address argument that it needs is, I think, 
the instruction pointer (the location of the variable changes depending 
on where in code you are;  it can be a register here, stack over there, 
etc.)

dwfl_module_return_value_location from libdwfl looks like an interesting 
alternative to me.

You would still need to write evaluator for DW_AT_location.  I think 
some things in that are pretty easy, namely general arithmetic, but most 
of the interesting stuff involves reading register values, and that's 
pretty specific for your problem domain.  That's actually something that 
peeking in systemtap sources might help with.

> 3. Converting the address generated from DW_AT_location to actual 
> address in vmcore dump. I am assuming the address we get from the dwarf 
> tag will be a virtual address and that needs to be mapped to a location 
> at vmocre file. crash tool has a routine readmem(), I am currently 
> looking into it for probable solution.

That's something I can't help with at all.

As a sidenote, in your code you seem to be doing a lookup by name.  If 
you are trying to annotate a stack trace (which I don't know if you do), 
I would think that you would do lookup by address.  That is, given stack 
trace of PCs that you have somehow obtained from the core file, call 
dwarf_addrdie to get CU DIE that covers given PC, and then use that with 
dwarf_getscopes to get "stack" of DIEs around that PC.  Then find 
closest function DIE in that stack, iterate its arguments, evaluate 
their location expressions to find values, etc.

Hope that helps,
PM

Attachment: signature.asc
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]