2013-07-31 10 views
6

g++ jest zbudowane przy użyciu modelu wyjątku DWARF2, sjlj lub seh. MinGW-builds udostępnia różne kompilacje g++, które mają różne modele wyjątków. Chciałbym być w stanie określić z modelu narzędziowego gcc jaki model wyjątku jest używany. Czy istnieje argument g++, który zrzuci domyślny model wyjątku kompilatora?Uzyskiwanie bieżącego modelu wyjątku GCC

+2

Wygląda na to, że możesz sprawdzić, czy gcc używa 'sjlj', sprawdzając wynik kompilacji złożenia, szukając' _Unwind_SjLj_Resume' lub '_Unwind_Resume', ponieważ to właśnie [skrypt konfiguracyjny] (http://gcc.gnu.org) /git/?p=gcc.git;a=blob_plain;f=libstdc%2B%2B-v3/configure;hb=HEAD) dla 'libstdC++' robi –

+0

Możesz również sprawdzić wyjątki '--enable-sjlj -' w wyjściu 'gcc -v' –

Odpowiedz

9

Edytuj: Oryginalnie testowałem flagi konfiguracji opisane w g++ -v. Jak zauważa Jonathon Wakely w komentarzach, jest to niezbyt dobra sprawa:.

sposób kontroli, aby to zrobić jest skompilować do montażu:

struct S { ~S(); }; 
void bar(); 
void foo() { 
    S s; 
    bar(); 
} 

Wynik g++ -S <filename> -o output.s mają następujące referencje wyjątków w nich

MinGW-4.8.1-x86-posix-sjlj:

.def ___gxx_personality_sj0; .scl 2; .type 32; .endef 
.def __Unwind_SjLj_Register; .scl 2; .type 32; .endef 
.def __Unwind_SjLj_Unregister; .scl 2; .type 32; .endef 
.def __Unwind_SjLj_Resume; .scl 2; .type 32; .endef 

MinGW-4.8.1-x86-posix-dwarf:

.def ___gxx_personality_v0; .scl 2; .type 32; .endef 
.def __Unwind_Resume; .scl 2; .type 32; .endef 

MinGW-4.8.1-x64-win32-sjlj:

.def __gxx_personality_sj0; .scl 2; .type 32; .endef 
.def _Unwind_SjLj_Register; .scl 2; .type 32; .endef 
.def _Unwind_SjLj_Unregister; .scl 2; .type 32; .endef 
.def _Unwind_SjLj_Resume; .scl 2; .type 32; .endef 

MinGW-4.8.1-x64-posix-seh:

.def __gxx_personality_seh0; .scl 2; .type 32; .endef 
.def _Unwind_Resume; .scl 2; .type 32; .endef 

MinGW-4.8.1-x64-posix-sjlj:

.def __gxx_personality_sj0; .scl 2; .type 32; .endef 
.def _Unwind_SjLj_Register; .scl 2; .type 32; .endef 
.def _Unwind_SjLj_Unregister; .scl 2; .type 32; .endef 
.def _Unwind_SjLj_Resume; .scl 2; .type 32; .endef 

FC17-g++-4.7.2-x64:

.cfi_personality 0x3,__gxx_personality_v0 
.globl __gxx_personality_v0 
call _Unwind_Resume 

Wygląda na to powinniśmy szukać __gxx_personality_([a-z])(0-9]+) a następnie porównać pierwszą grupę do przechwytywania:

  • v = dwarf
  • seh = seh
  • sj = sjlj
+0

To jest niepoprawne, jak mówi [docs] (http://gcc.gnu.org/install/configure.html), domyślne (tj. co jest używane, gdy nie używasz wszelkie opcje '--enable' lub' --disable') zależą od platformy. –

+0

Dzięki, Jonathan. Nadal rozważa opracowanie modelu wyjątku przez skompilowanie kodu. –

+1

@ JonathanWakely, zaktualizowałem odpowiedź, sprawdzając flagę konfiguracji, dzięki za pomoc w tym. Dodałem kilka przykładów kompilacji fragmentu obsługi wyjątku, który znalazłem w skrypcie konfiguracyjnym 'stdlibC++', a następnie przyjrzałem się zestawowi, aby ustalić prawidłowe osobowości podstawowe. Użyłem tego jako odniesienia: http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf –

0

Wystarczy uzupełnić powyższe odpowiedzi, GCC posiada predefiniowane makra pozwalające rozpoznać w czasie kompilacji czy modelu wyjątek SJLJ jest stosowany:

__USING_SJLJ_EXCEPTIONS__

To makro jest zdefiniowane, o wartości 1, jeśli kompilator używa starego mechanizmu opartego na setjmp i longjmp do obsługi wyjątków.

Zobacz https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

Zgodnie z dokumentacją, jest dostępny od wersji co najmniej 3.1.1; Właśnie przetestowałem go na GCC 7.1 (pod MinGW-w64).

Powiązane problemy