Estoy interesado en un manejador de señal que pueda identificar la dirección de la instrucción que causó el problema.Obtener la dirección de error que generó una señal UNIX
que sé sobre siginfo_t
y __builtin_return_address
y ninguno parece funcionar:
#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";
}
Esto da salida a algo como:
0x10978 ~ 0x10a4c ~ 0x10a54
si:0
At: 0xfb945364
At: 0xfb939e64
At: 0x10a40
At: 0x10740
At: 0
At: Segmentation Fault
Así siginfo_t
es nulo y __builtin_return_address
está dando valores en algún lugar entre la etiquetas nombradas.
me esperaba tanto de estos para devolver el valor de &&before
. ¿Estoy usando estas funciones correctamente?
probado en Linux y SunOS 2.6.9-89.0.9.Elsmp.
Esta [respuesta] (http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes/1925461#1925461) a [Cómo generar una stacktrace cuando mi aplicación gcc C++ se cuelga] (http://stackoverflow.com/q/77005/203667) puede ser útil. – jschmier
Recuerde que otro proceso puede enviar una señal a este proceso, por lo que la 'dirección de falla' puede no decirle nada significativo. OTOH, ese es un evento bastante improbable. –
@Jonathan: con señales en tiempo real ('sigaction' con' SA_SIGINFO' y 'siginfo_t'), se requiere que el kernel proteja contra la falsificación. Hay un campo en 'siginfo_t' que le dice a la fuente de la señal, y' sigqueue' no puede falsificar la fuente como kernel. –