10

GCC が C++ プログラムの例外処理をどのように実装しているか知りたいです。Web 上には、わかりやすくて自明な記事は見つかりませんでした (ただし、Visual C++ に関する記事はたくさんあります)。私が知っているのは、GCC の実装が DWARF 例外処理と呼ばれているということだけです。

小さな C++ プログラムを作成し、次のコマンドでアセンブリに変換しました。

g++ main.cpp -S -masm=intel -fno-dwarf2-cfi-asm

main.cppおよびmain.sファイルはここで提供されます。main.s ファイルの内容、特にセクション.gcc_except_table.eh_frame行ごとに説明してください。(私のOSはUbuntu 13.04 32ビットです。)ありがとう!

main.cpp:

void f()
{
    throw 1;
}

int main()
{
    int j;
    try {
        f();
    } catch (int i) {
        j = i;
    }   
    return 0;
}

メイン:

.file "main.cpp"
.intel_syntax noprefix
.text
.globl  _Z1fv
.type   _Z1fv, @function
_Z1fv:
.LFB0:
    push    ebp
.LCFI0:
    mov ebp, esp
.LCFI1:
    sub esp, 24
    mov DWORD PTR [esp], 4
    call    __cxa_allocate_exception
    mov DWORD PTR [eax], 1
    mov DWORD PTR [esp+8], 0
    mov DWORD PTR [esp+4], OFFSET FLAT:_ZTIi
    mov DWORD PTR [esp], eax
    call    __cxa_throw
.LFE0:
    .size   _Z1fv, .-_Z1fv
    .globl  main
    .type   main, @function
main:
.LFB1:
    push    ebp
.LCFI2:
    mov ebp, esp
.LCFI3:
    and esp, -16
    sub esp, 32
.LEHB0:
    call    _Z1fv
.LEHE0:
.L7:
    mov eax, 0
    jmp .L9
.L8:
    cmp edx, 1
    je  .L6
    mov DWORD PTR [esp], eax
.LEHB1:
    call    _Unwind_Resume
.LEHE1:
.L6:
    mov DWORD PTR [esp], eax
    call    __cxa_begin_catch
    mov eax, DWORD PTR [eax]
    mov DWORD PTR [esp+24], eax
    mov eax, DWORD PTR [esp+24]
    mov DWORD PTR [esp+28], eax
    call    __cxa_end_catch
    jmp .L7
.L9:
    leave
.LCFI4:
    ret
.LFE1:
    .globl  __gxx_personality_v0
    .section    .gcc_except_table,"a",@progbits
    .align 4
.LLSDA1:
    .byte   0xff
    .byte   0
    .uleb128 .LLSDATT1-.LLSDATTD1
.LLSDATTD1:
    .byte   0x1
    .uleb128 .LLSDACSE1-.LLSDACSB1
.LLSDACSB1:
    .uleb128 .LEHB0-.LFB1
    .uleb128 .LEHE0-.LEHB0
    .uleb128 .L8-.LFB1
    .uleb128 0x1
    .uleb128 .LEHB1-.LFB1
    .uleb128 .LEHE1-.LEHB1
    .uleb128 0
    .uleb128 0
.LLSDACSE1:
    .byte   0x1
    .byte   0
    .align 4
    .long   _ZTIi
.LLSDATT1:
    .text
    .size   main, .-main
    .section    .eh_frame,"a",@progbits
.Lframe1:
    .long   .LECIE1-.LSCIE1
.LSCIE1:
    .long   0
    .byte   0x1
    .string "zPL"
    .uleb128 0x1
    .sleb128 -4
    .byte   0x8
    .uleb128 0x6
    .byte   0
    .long   __gxx_personality_v0
    .byte   0
    .byte   0xc
    .uleb128 0x4
    .uleb128 0x4
    .byte   0x88
    .uleb128 0x1
    .align 4
.LECIE1:
.LSFDE1:
    .long   .LEFDE1-.LASFDE1
.LASFDE1:
    .long   .LASFDE1-.Lframe1
    .long   .LFB0
    .long   .LFE0-.LFB0
    .uleb128 0x4
    .long   0
    .byte   0x4
    .long   .LCFI0-.LFB0
    .byte   0xe
    .uleb128 0x8
    .byte   0x85
    .uleb128 0x2
    .byte   0x4
    .long   .LCFI1-.LCFI0
    .byte   0xd
    .uleb128 0x5
    .align 4
.LEFDE1:
.LSFDE3:
    .long   .LEFDE3-.LASFDE3
.LASFDE3:
    .long   .LASFDE3-.Lframe1
    .long   .LFB1
    .long   .LFE1-.LFB1
    .uleb128 0x4
    .long   .LLSDA1
    .byte   0x4
    .long   .LCFI2-.LFB1
    .byte   0xe
    .uleb128 0x8
    .byte   0x85
    .uleb128 0x2
    .byte   0x4
    .long   .LCFI3-.LCFI2
    .byte   0xd
    .uleb128 0x5
    .byte   0x4
    .long   .LCFI4-.LCFI3
    .byte   0xc5
    .byte   0xc
    .uleb128 0x4
    .uleb128 0x4
    .align 4
.LEFDE3:
    .ident  "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
    .section    .note.GNU-stack,"",@progbits
4

2 に答える 2