Pregunta

La mayor parte del tiempo mi programa GLIB funciona bien. Sin embargo, cuando los registros como

** (proceso:pid): Mensaje (recurrido): bla lah blah

Aparece, el programa abortará.

GLIB Manual dice que G_LOG_FLAG_RECURSION se considera fatal de forma predeterminada.

¿Pero no puedo entender qué significa "mensajes recursivos"? ¿Cuándo ocurrirá el mensaje recurrido?

Gracias

¿Fue útil?

Solución

Skimming a través de Glib/GMessages.c me da la fuerte impresión de que G_LOG_FLAG_RECURSION está establecido si g_logv() necesita registrar un error en sí.

Considere quedarse sin memoria; Cuando falla un intento de asignación de memoria, el programa intentará registrar la falla de asignación de memoria y probablemente salir. Cuando la rutina de registro intenta asignar memoria para registrar el mensaje, probablemente fallará. Por lo tanto, las rutinas de registro realizan un seguimiento de cómo se han llamado 'profundo' y cambian la estrategia de asignación de memoria (se asignan en la pila en lugar de en el montón), si se trata de una llamada de registro recursiva.

Cada vez que las rutinas de registro reciben un mensaje de error y desearían registrar el error, algo De Verdad Está sucediendo mal, por lo que tiene sentido tratar de iniciar sesión con otro mecanismo y luego salir.

Por lo tanto, probablemente solo esté viendo un síntoma lejano del problema real. Podrías usar ltrace(1) Para tratar de detectar el problema, o puede habilitar los vertederos de núcleo (ulimit -c unlimited) e intente encontrar la cadena de llamadas que hace que el programa se bloquee usando GDB's bt dominio.

Otros consejos

Tenga en cuenta que una llamada recursiva a una rutina de registro G_* también puede ocurrir si está registrando un controlador personalizado (con g_log_set_handler) y ese manejador (o una de sus calores) intenta registrar un error con una llamada a una rutina G_*.

También tenga en cuenta que GLIB decidió que cualquier recursión también debería ser fatal (incluso si no es infinito de un solo nivel de profundidad). Esto ciertamente tiene sentido para el caso descrito en la respuesta de la recursión de Sarnold sobre la falla interna, pero podría no ser obvio cuando se trata de solucionar el problema en el caso de un controlador personalizado que se recurre. Entonces, GLIB detecta la recursión tan pronto como la primera llamada recursiva a G_*; Ni siquiera llega a verificar si su controlador personalizado está adjunto. Por lo tanto, nunca verá una llamada recursiva a su manejador. Todo esto significa que los esfuerzos como no registrar cuidadosamente el manejador dentro del cuerpo del manejador (y cosas similares) son inútiles.

Debe asegurarse absolutamente de que nada en la pila de llamadas de su controlador personalizado llamará a una rutina G_* (que puede ser complicada si controle las llamadas al código externo y complica cosas como tratar de entregar el mensaje de registro a un destino remoto o algo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top