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

問題は、formof attrs[i]showsattrs[i]がアドレスではないことです (1 ではなく 7 に設定されています)。それを使って探索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>

この出力では、DW_AT_high_pc長さが 2 オクテットしかないため、私には正しくないようです。

参考までに、私は次のようにコンパイルtracedprogしました。

$> gcc -g tracedprog2.c -o tracedprog

gcc別のマシンでは問題がないため、編集は問題のようです。を使用してgcc 4.8.2います。

4

3 に答える 3

4

DW_AT_high_pcデフォルトの DWARF バージョンをオーバーライドせずに gcc >= 4.8 でコンパイルされたバイナリで libdwarfを使用するには、値を抽出する前に属性の形式をチェックする必要があります。

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 に答える