g++
построено с использованием моделей исключений DWARF2
, sjlj
или seh
. MinGW-builds предоставляют различные сборки g++
, которые имеют разные модели исключений. Я хотел бы иметь возможность определить из инструментальной цепочки gcc
, какую модель исключений используется. Есть ли аргумент g++
, который удалит модель исключения по умолчанию для компилятора?Получение существующей модели исключения GCC
ответ
Редактировать: Первоначально я тестировал флаги конфигурации, описанные в 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
Это неверно, как указано в [docs] (http://gcc.gnu.org/install/configure.html), по умолчанию (т.е. то, что используется, когда вы не используете любые опции '--enable' или' --disable') зависят от платформы. –
Спасибо, Джонатан. Все еще глядя на разработку модели исключения с помощью компиляции кода. –
@ JonathanWakely, я обновил ответ, извлекая проверку флага конфигурации, спасибо за помощь в этом. Я добавил несколько примеров компиляции фрагмента обработки исключений, который я нашел в скрипте конфигурации «stdlibC++», а затем просмотрел сборку, чтобы определить правильные базовые личности. Я использовал следующую ссылку: http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf –
Только дополнять вышеуказанные ответы, 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).
Похоже, вы можете определить, использует ли 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 –
Вы также можете проверить '--enable-sjlj-exceptions' в выводе 'gcc -v' –