Oracle Pro*C/OCI устанавливает обработчики для SIGSEGV/SIGABRT и друзей - почему и как отключить?
При использовании Pro*C (встроенного препроцессора SQL от Oracle для C-Code) или OCI я заметил, что процедура connect/init устанавливает некоторые обработчики сигналов.
Это означает, что перед
EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbspec ;
или
OCIEnvNlsCreate()
Я могу убедиться, что, например, эти сигналы имеют следующие обработчики:
No NAME Pointer SA_SIGINFO SIG_DFL SIG_IGN
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
1 SIGHUP (nil) false true false
2 SIGINT (nil) false true false
3 SIGQUIT (nil) false true false
4 SIGILL (nil) false true false
5 SIGTRAP (nil) false true false
6 SIGABRT (nil) false true false
7 SIGBUS (nil) false true false
8 SIGFPE (nil) false true false
9 SIGKILL (nil) false true false
10 SIGUSR1 (nil) false true false
11 SIGSEGV (nil) false true false
12 SIGUSR2 (nil) false true false
13 SIGPIPE (nil) false true false
14 SIGALRM (nil) false true false
После оператора connect/init таблица выглядит следующим образом:
No NAME Pointer SA_SIGINFO SIG_DFL SIG_IGN
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
1 SIGHUP (nil) false true false
2 SIGINT 0x7eff9e60bdac true false false
3 SIGQUIT 0x7eff9ea17f9c true false false
4 SIGILL 0x7eff9ea17f9c true false false
5 SIGTRAP 0x7eff9ea17f9c true false false
6 SIGABRT 0x7eff9ea17f9c true false false
7 SIGBUS 0x7eff9ea17f9c true false false
8 SIGFPE 0x7eff9ea17f9c true false false
9 SIGKILL (nil) false true false
10 SIGUSR1 (nil) false true false
11 SIGSEGV 0x7eff9ea17f9c true false false
12 SIGUSR2 (nil) false true false
13 SIGPIPE 0x1 true false true
14 SIGALRM (nil) false true false
где 0x7eff9e60bdac обозначает sslsshandler()
и 0x7eff9ea17f9c обозначает skgesig_sigactionHandler()
- оба символа определены в libclntsh.so.11.1
- библиотека времени выполнения Oracle.
Я обеспокоен этими обработчиками сигналов Oracle, потому что кажется, что они вводят некоторое недетерминированное поведение. Это означает, что в зависимости от ОС, аппаратного обеспечения и вида сбоя / прерывания я наблюдал следующее поведение:
- ужасная трассировка стека, которая не содержит много полезной информации
- прямой выход из программы с exit-status 1 - без записи файла ядра и сообщения об ошибке
- прямой выход из программы со статусом выхода 0 (sic!)
Особенно последнее поведение гротескно.
Таким образом, я заинтересован в:
- мотивация - почему эти обработчики сигналов установлены Oracle?
- как их отключить? - по крайней мере для сигналов, которые дают основной файл по умолчанию - потому что для моего варианта использования я хочу ядро в этих обстоятельствах (во время разработки) или для надежного и информативного статуса выхода в производстве
- Безопасно ли переписывать обработчик сигналов Oracle, например, через
act.sa_handler = SIG_DFL; sigaction(SIGABRT, &act, 0);
? - Каковы недостатки сброса SIGABRT/SIGSEGV и друзей в SIG_DFL после подключения?
2 ответа
Соображения по поводу обработки сигналов и диагностической структуры: диагностическая структура OCI устанавливает обработчики сигналов, которые могут влиять на любую обработку сигналов, которую вы используете в своем приложении. Вы можете отключить обработку сигнала OCI, установив
DIAG_SIGHANDLER_ENABLED=FALSE
в файле sqlnet.ora. Обратитесь к разделу " Диагностика ошибок в OCI " в Руководстве по программированию интерфейса вызовов Oracle.
Пожалуйста, попробуйте настроить эту переменную среды в файле sqlnet.ora
Я бы залатал Oracle .so
файл для замены sigaction
строка с nosigactn
и сделайте неоперативную функцию в вашей программе под названием nosigactn
с той же подписью, что и sigaction
,