Mi piacerebbe sapere come GCC implementa la gestione delle eccezioni per i programmi C++. Non sono riuscito a trovare un articolo di facile comprensione e auto-esplicativo sul Web (sebbene ci siano molti articoli di questo tipo per Visual C++). Tutto quello che so è che l'implementazione di GCC è chiamata gestione delle eccezioni DWARF.Implementazione gestione eccezioni GCC C++
Ho scritto un piccolo programma C++ e tradotto in assemblaggio con il comando:
g ++ main.cpp -S -masm = Intel -fno-DWARF2-CFI-asm
Il main.cpp e main.s I file sono indicati qui. Qualcuno potrebbe spiegare il contenuto del file main.s, in particolare le sezioni .gcc_except_table
e .eh_frame
linea per linea? (Il mio sistema operativo è Ubuntu 13.04 a 32 bit.) Grazie!
MAIN.CPP:
void f()
{
throw 1;
}
int main()
{
int j;
try {
f();
} catch (int i) {
j = i;
}
return 0;
}
main.s:
.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
GCC utilizza Itanium ABI, che [descrive come vengono gestite le eccezioni] (http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-throw). –
il link sopra è morto .. @KerrekSB – FaceBro
@FaceBro: OK, forse https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html –