2013-11-20 104 views
3

作为一个新手侏儒,我试过的代码提交in this page(代码here),但是当我启动它,我得到:DWARF信息似乎是错误的DW_AT_high_pc用gcc 4.8.2

$> ./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 

后调试会话,这个问题似乎来自管线78:

else if (attrcode == DW_AT_high_pc) 
     dwarf_formaddr(attrs[i], &highpc, 0); 

问题是,的attrs[i]form显示attrs[i]不是地址(它被设置为7代替1)。 探索tracedprogobjdump它给出对于do_stuff功能:

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

在此输出,DW_AT_high_pc似乎不正确的我,因为它只有两个字节长。

供您参考,我编tracedprog有:

$> gcc -g tracedprog2.c -o tracedprog 

编辑这似乎是一个gcc问题,因为有另一台机器上没有问题。我正在使用gcc 4.8.2

回答

2

我发现了这个问题。从gcc 4.8开始,默认DWARF版本为4.为了使我的程序正常工作,我必须编辑tracedprog-gdwarf-2标志。

0

作为参考,在DWARF 4中,DW_AT_high_pc可以是类常量。在这种情况下,该值是与low_pc的偏移量。引用的代码不处理这个问题。

2

要在gcc> = 4.8编译的二进制文件上使用带有libdwarf的DW_AT_high_pc而不覆盖默认的DWARF版本,必须在提取值之前检查属性的形式。

根据DWARF信息的版本,DW_AT_high_pc属性可以是DW_FORM_addr表单或DW_FORM_data8表单。每个表单都有自己的提取功能。

下面是如何检查属性的形式的示例:

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; 
    } 
}