Теперь, почти через 2 года (все еще работая в той же компании, что и Кристофер, когда он задал вопрос), снова был поднят вопрос - и, наконец, я понимаю, что понимаю, почему не создается дамп ядра !!
Проблема вызвана временем выполнения Ada, которое по умолчанию реализует обработчик сигналов для некоторых сигналов POSIX (для Linux: SIGABRT, SIGFPE, SIGILL, SIGSEGV и SIGBUS). Для GNAT / linux обработчик сигнала называется __ gnat_error_handler в a-init.c , который выглядит примерно так:
static void
__gnat_error_handler (int sig)
{
struct Exception_Data *exception;
char *msg;
static int recurse = 0;
...
switch (sig)
{
case SIGSEGV:
if (recurse)
{
exception = &constraint_error;
msg = "SIGSEGV";
}
else
{
...
msg = "stack overflow (or erroneous memory access)";
exception = &storage_error;
}
break;
}
recurse = 0;
Raise_From_Signal_Handler (exception, msg);
}
Этот обработчик является «широким процессом» и будет вызываться любым запускающим сигналом, независимо от того, из какой части процесса он исходит (независимо от того, закодирован ли он в Ada / C / C ++ ...).
При вызове обработчик вызывает исключение Ada и оставляет его во время выполнения Ada, чтобы найти подходящий обработчик исключения - если такой обработчик не найден (например, когда SIGSEGV генерируется любой частью кода C ++) среда выполнения Ada отступает, чтобы просто завершить процесс и просто оставить простую распечатку из __gnat_error_handler (например, «переполнение стека (или ошибочный доступ к памяти)»).
http://www2.adacore.com/gap-static/GNAT_Book/html/node25.htm
Чтобы запретить Ada-runtime обрабатывать POSIX-сигнал и преобразовать его в Ada-исключение, можно отключить beahviour по умолчанию с помощью
pragma Interrupt_State (Name => value, State => SYSTEM | RUNTIME | USER); ,
например. чтобы отключить обработку SIGSEGV, определите
Pragma Interrupt_State(SIGSEGV, SYSTEM);
в вашем Ада-коде - теперь поведение системы по умолчанию будет срабатывать при поднятии SIGSEGV, и будет сгенерирован дамп ядра, который позволит вам отследить источник проблемы!
Я думаю, что это очень важная проблема, о которой следует помнить при смешивании Ada и C / C ++ на * NIX-платформах, так как это может ввести вас в заблуждение, что проблемы возникают из-за кода Ada (поскольку распечатка указывает на исключение генерируется из Ada), когда реальный источник проблемы лежит в C / C ++ - код ...
Хотя, вероятно, безопасно отключить обработку SIGSEGV по умолчанию во время выполнения Ada (я думаю, ни один здравомыслящий программист не использовал бы это в какой-либо "ожидаемой" обработке ошибок ... Ну, может быть, используется в авиационном программном обеспечении или подобном, когда какой-то Функциональность "последней инстанции" должна поддерживаться, чтобы избежать чего-то действительно плохого ...) Я думаю, что нужно быть немного осторожнее, чтобы затем "переопределить" обработку Ada-runtime для сигналов.
Одной из проблем может быть сигнал SIGFPE, который также вызывает исключение Ada Constraint_Error по умолчанию. Этот тип исключения может использоваться Ада-кодом как «ожидаемое поведение».
Отключение SIGFPE с помощью Pragma Interrupt_State может серьезно повлиять на выполнение Ada-кода и привести к сбою приложения в «нормальных обстоятельствах» - с другой стороны, любое деление на ноль в C / C ++ - код вызовет механизм обработки Ada-исключений, и оставить вас без каких-либо реальных следов происхождения проблемы ...