对于DW_AT_high_pc和gcc 4.8.2,DWARF信息似乎是错误的

时间:2013-11-20 13:20:22

标签: c gcc objdump dwarf

作为DWARF的新手,我尝试了代码in this page(代码为here),但是当我启动它时,我得到了:

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

问题是,form显示attrs[i]的{​​{1}}不是地址(设置为7而不是1)。 对attrs[i]函数

进行tracedprog objdump的探讨
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> 对我来说似乎不正确,因为它只有两个八位字节。

供我参考,我用{<1}}编译:

DW_AT_high_pc

修改这似乎是tracedprog问题,因为其他计算机上没有问题。我正在使用$> gcc -g tracedprog2.c -o tracedprog

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

要对由gcc&gt; = 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;
    }
}          

答案 2 :(得分:0)

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