As a newbie to DWARF, I tried the code presented in this page (code is here) but when I launch it I get:
$> ./dwarf_get_func_addr tracedprog
DW_TAG_subprogram: 'do_stuff'
abort() in libdwarf. No error argument, no handler.
zsh: abort (core dumped) ./dwarf_get_func_addr tracedprog
After a debugging session, the problem appears to come from line 78:
else if (attrcode == DW_AT_high_pc)
dwarf_formaddr(attrs[i], &highpc, 0);
The problem is, the form
of attrs[i]
shows attrs[i]
is not an address (it is set to 7 instead of 1).
Exploring tracedprog
with objdump
it gives, for do_stuff
function:
<1><73>: Numéro d'abréviation: 4 (DW_TAG_subprogram)
<74> DW_AT_external : 1
<74> DW_AT_name : (chaîne indirecte, décalage: 0x55): do_stuff
<78> DW_AT_decl_file : 1
<79> DW_AT_decl_line : 4
<7a> DW_AT_prototyped : 1
<7a> DW_AT_low_pc : 0x400500
<82> DW_AT_high_pc : 0x3f
<8a> DW_AT_frame_base : 1 bloc d'octets: 9c (DW_OP_call_frame_cfa)
<8c> DW_AT_GNU_all_tail_call_sites: 1
<8c> DW_AT_sibling : <0xb9>
In this output, DW_AT_high_pc
doesn't seem correct to me as it is only two octets long.
For your reference, I compiled tracedprog
with:
$> gcc -g tracedprog2.c -o tracedprog
Edit it seems to be a gcc
issue as there is no issue on another machine. I am using gcc 4.8.2
.
To use DW_AT_high_pc
with libdwarf on a binary compiled by gcc >= 4.8 without overriding the default DWARF version one has to check the form of the attribute before extracting the value.
Depending on the version of the DWARF information, the DW_AT_high_pc
attribute can be either a DW_FORM_addr
form or a DW_FORM_data8
form. Each form has its own extracting function.
Here is an example of how to check the form of the an attribute:
void print_attribute(Dwarf_Attribute a)
{
Dwarf_Half form;
Dwarf_Error err;
Dwarf_Half attrcode;
unsigned int offset = 0;
Dwarf_Addr addr;
dwarf_whatform(a, &form, &err);
switch(form)
{
case DW_FORM_addr:
dwarf_formaddr(a, &addr, &err);
printf("DW_FORM_addr: 0x%08llx\n", addr);
break;
case DW_FORM_data8:
dwarf_formudata(a, &offset , &err);
printf("DW_FORM_data8: 0x%08llx\n", offset);
break;
default:
break;
}
}
I found the issue. Starting from gcc 4.8
, default DWARF version is 4. To make my program work, I had to compile tracedprog
with -gdwarf-2
flag.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With