при вызове с любым ненулевым аргументом предполагает существование цепочки указателя кадра. Это не требуется для x86-64, и даже если вы заставите компилятор сгенерировать его, специальный фрейм "вызывающего сигнала обработчика", который генерирует ядро, разорвет цепочку.
интересует обработчик сигнала, который может идентифицировать адрес инструкции, вызвавшей проблему.
Я знаю оsiginfo_t
а также__builtin_return_address
и ни то, ни другое не работает
#include <iostream>
#include <signal.h>
void handler (int, siginfo_t *, void *);
int main ()
{
begin:
std :: cerr << &&begin << " ~ " << &&before << " ~ " << &&after << "\n";
struct sigaction s;
s .sa_flags = SA_SIGINFO;
sigemptyset (& s .sa_mask);
s .sa_sigaction = handler;
sigaction (SIGSEGV, &s, NULL);
int * i = NULL;
before:
*i = 0;
after:
std :: cout << "End.\n";
}
void handler (int, siginfo_t *si, void *)
{
std :: cerr << "si:" << si -> si_addr << "\n";
std :: cerr << "At: " << __builtin_return_address (0) << "\n";
std :: cerr << "At: " << __builtin_return_address (1) << "\n";
std :: cerr << "At: " << __builtin_return_address (2) << "\n";
std :: cerr << "At: " << __builtin_return_address (3) << "\n";
std :: cerr << "At: " << __builtin_return_address (4) << "\n";
std :: cerr << "At: " << __builtin_return_address (5) << "\n";
}
Это выводит что-то вроде:
0x10978 ~ 0x10a4c ~ 0x10a54
si:0
At: 0xfb945364
At: 0xfb939e64
At: 0x10a40
At: 0x10740
At: 0
At: Segmentation Fault
Такsiginfo_t
NULL и__builtin_return_address
где-то дает значениямежду названные ярлыки.
Я ожидал, что оба из них вернут значение&&before
, Я правильно использую эти функции?
Протестировано на Linux 2.6.9-89.0.9. Elsmp и SunOS.