2013-07-31 2 views
6

g++ построено с использованием моделей исключений DWARF2, sjlj или seh. MinGW-builds предоставляют различные сборки g++, которые имеют разные модели исключений. Я хотел бы иметь возможность определить из инструментальной цепочки gcc, какую модель исключений используется. Есть ли аргумент g++, который удалит модель исключения по умолчанию для компилятора?Получение существующей модели исключения GCC

+2

Похоже, вы можете определить, использует ли gcc 'sjlj', проверяя вывод компиляции сборки, ищущий' _Unwind_SjLj_Resume' или '_Unwind_Resume', так как это [сценарий конфигурации] (http://gcc.gnu.org /git/?p=gcc.git;a=blob_plain;f=libstdc%2B%2B-v3/configure;hb=HEAD) для 'libstdC++' does –

+0

Вы также можете проверить '--enable-sjlj-exceptions' в выводе 'gcc -v' –

ответ

9

Редактировать: Первоначально я тестировал флаги конфигурации, описанные в g++ -v. Как отмечает Джонатан Уэйкли в комментариях, это нехорошо сделать.

Проверку способ сделать это состоит в компиляции для сборки:

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

Результат g++ -S <filename> -o output.s имеют следующие ссылки исключения в них:

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 

Похоже, мы должны искать __gxx_personality_([a-z])(0-9]+), а затем сравнить первую группу захвата для:

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

Это неверно, как указано в [docs] (http://gcc.gnu.org/install/configure.html), по умолчанию (т.е. то, что используется, когда вы не используете любые опции '--enable' или' --disable') зависят от платформы. –

+0

Спасибо, Джонатан. Все еще глядя на разработку модели исключения с помощью компиляции кода. –

+1

@ JonathanWakely, я обновил ответ, извлекая проверку флага конфигурации, спасибо за помощь в этом. Я добавил несколько примеров компиляции фрагмента обработки исключений, который я нашел в скрипте конфигурации «stdlibC++», а затем просмотрел сборку, чтобы определить правильные базовые личности. Я использовал следующую ссылку: http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf –

0

Только дополнять вышеуказанные ответы, GCC имеет предопределенный макрос, позволяющий распознавать во время компиляции, используется ли модель SJLJ исключение:

__USING_SJLJ_EXCEPTIONS__

Этот макрос определяется значением 1, если компилятор использует старый механизм на основе setjmp и longjmp для обработки исключений.

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

Согласно документации, она доступна, начиная с версии 3.1.1; Я только что протестировал его на GCC 7.1 (под MinGW-w64).