Necesito imprimir el seguimiento de la pila desde un manejador de señal de la aplicación C++ multiproceso de 64 bits que se ejecuta en Linux. Aunque encontré varios ejemplos de código, ninguno de ellos compila. Mi punto de bloqueo es obtener la dirección de la persona que llama (el punto donde se generó la señal) de la estructura ucontext_t. Toda la información que pude encontrar apunta al registro de EIP como uuctext.gregs [REG_EIP] o ucontext.eip. Parece que ambos son específicos de x86. Necesito un código compatible con 64 bits para las CPU Intel y AMD. ¿Alguien puede ayudar?Impresión del seguimiento de pila desde un manejador de señal
Respuesta
La forma más habitual de conseguir un seguimiento de pila es tomar la dirección de un variable local, a continuación, añadir un poco de número mágico a la misma, dependiendo de cómo el compilador genera código (que puede depender de las opciones de optimización utilizados para compilar el código), y trabajar desde allí. Todo el mismo sistema depende, pero posible si sabes lo que estás haciendo.
Si esto funciona en un controlador de señal es otra cuestión. No conozco la plataforma que describes, pero muchos sistemas instalan una pila separada para los manejadores de señal, sin ningún enlace a la pila interrumpida en la memoria accesible para el usuario.
¿Quiere decir que no hay un enlace de regreso a la pila interrumpida? –
@wood_brian No está en la memoria accesible para el usuario. (El sistema operativo obviamente conserva la información de alguna manera). –
Usted escribió estática interrumpida. Pensé que te referías a la pila interrumpida. –
hay una función glibc traza inversa. La página man enumera un ejemplo de la llamada:
#define SIZE 100
void myfunc3(void) {
int j, nptrs;
void *buffer[100];
char **strings;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
would produce similar output to the following: */
strings = backtrace_symbols(buffer, nptrs);
if (strings == NULL) {
perror("backtrace_symbols");
exit(EXIT_FAILURE);
}
for (j = 0; j < nptrs; j++)
printf("%s\n", strings[j]);
free(strings);
}
Consulte la página de manual para obtener más contexto.
es difícil decir si realmente se garantiza que funcione desde un manejador de señal, ya que posix solo enumera unas pocas funciones de reentrada que están garantizadas para funcionar. Recuerde: se puede llamar a un manejador de señal mientras el resto de su proceso está justo en el medio de una llamada malloc.
Mi supongo es que normalmente funciona, pero puede fallar de vez en cuando. Para la depuración esto puede ser suficiente.
- 1. ejecución del manejador de señal predeterminado
- 2. Encontrar el seguimiento de la pila real de Java desde un seguimiento de la pila de JavaScript
- 3. Cómo escribir un manejador de señal para atrapar SIGSEGV?
- 4. Seguimiento de orígenes de señal UNIX?
- 5. Error de seguimiento de pila
- 6. Acceso a datos compartidos desde un controlador de señal
- 7. La captura de señal dentro de su propio manejador
- 8. ¿Por qué no se llama mi manejador de señal?
- 9. ¿Cómo se quita un manejador de señales
- 10. Imprimir un seguimiento de pila de otro hilo
- 11. ¿CÓMO determinar si el código se está ejecutando en el contexto del manejador de señal?
- 12. ¿Por qué manejador de señal va al bucle infinito? - SIGSEGV
- 13. Cómo obtener el seguimiento de la pila de un hilo
- 14. Obtención de seguimiento de pila de Perl Error "Memoria insuficiente"
- 15. ¿Cómo hacer un buen uso del seguimiento de la pila (desde el núcleo o el volcado del núcleo)?
- 16. Obtención de un seguimiento de pila de SBT con Scala
- 17. forja de un seguimiento de la pila en Java
- 18. Cómo salida de un seguimiento de pila profunda en Node.js?
- 19. Impresión desde un servicio .NET
- 20. Excepción sin seguimiento de pila en Java
- 21. Objective-C Seguimiento de la pila
- 22. programación C# obtener Seguimiento de la pila
- 23. Acceso al manejador de subprocesos de UI desde un servicio
- 24. ¿Cómo puedo obtener el seguimiento de la pila lua desde un archivo central utilizando gdb
- 25. Obteniendo el seguimiento de pila para un error al ejecutar código desde la consola en Chrome
- 26. ¿Qué significa esto en un seguimiento de pila?
- 27. ¿Cómo obtengo un seguimiento de pila en OCaml?
- 28. Excepción recurrente sin un seguimiento de pila: ¿cómo restablecerlo?
- 29. Necesito ayuda para descifrar un seguimiento de la pila C#
- 30. "Excepción al cargar la aplicación" sin un seguimiento de pila
No me sorprendería si no fuera posible. ¿Has intentado hacerlo en 32 bits? Además, ¿qué distro? –
En 64 bits, el registro es RIP. Seguro que estará allí en alguna parte. –
Es Red Hat 4.1.2-50. No puede ser una aplicación de 32 bits ya que trabajamos con áreas de memoria grande de hasta 60+ GB – GMichael