4

作为 DWARF 的新手,我尝试了此页面中提供的代码(代码在此处),但是当我启动它时,我得到:

$> ./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]不是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.

4

3 回答 3

4

DW_AT_high_pc在由 gcc >= 4.8 编译的二进制文件上使用 libdwarf 而不覆盖默认的 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;
    }
}          
于 2016-09-15T18:59:41.933 回答
3

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

于 2013-11-20T14:28:32.973 回答
1

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

于 2014-04-04T13:24:51.973 回答