Pregunta

¿Cómo consigo una aplicación C ++ que incluye una biblioteca compartida hemos cargado para generar un volcado de memoria al estrellarse

Tengo una aplicación de C ++ que carga una biblioteca compartida ada, ada dentro del código me sale un error de desbordamiento de pila que provoca la terminación del programa junto con la salida de la consola:

raised STORAGE ERROR

No se genera ningún archivo de vaciado tú también me han emitido una "ulimit -c unlimited" antes de iniciar la aplicación.

Lo mismo sucede si envío una matanza SIGSEGV para la aplicación.

Envío de matanza SIGSEGV a otra aplicación que no utiliza la DLL ada genera un archivo de volcado de memoria sólo la forma en que yo quiero que.

Se han encontrado alguna información aquí: http: // objectmix. com / ADA / 301203-mosquito-fstack-check-does-work.html

ACTUALIZADO! Según lo mencionado por Adrien, no hay ninguna contradicción, -s establece el límite de la pila mientras que -c establece el límite del archivo central.

Sin embargo el problema sigue. Revisé las banderas en la construcción de la biblioteca de ADA y la fstack-cheque no se ha establecido la bandera, por lo que debe generar un volcado de memoria.

Althou no he probado todavía, parece un tanto extraña. Se menciona la opción de -fstack-cheque compilador + estableciendo la variable de GNAT_STACK_LIMIT pero al mismo tiempo se refiere al mandato ulimit que parece una contradicción, el establecimiento de "ulimit -c" es la única forma que conozco de conseguir un volcado de memoria que se genera en el momento del accidente, si esto se infiere con la opción fstack-cheque entonces tenemos una captura 22.

¿Fue útil?

Solución

Ahora, casi 2 años después (todavía que trabaja en la misma empresa que hizo Kristofer cuando él hizo la pregunta), se planteó la cuestión de nuevo - y, finalmente, creo que entiende por qué no se genera ningún núcleo-dump !!

El problema es causado por la ADA en tiempo de ejecución, que por defecto implementa un controlador de señal para algunos POSIX señales (para Linux: SIGABRT, SIGFPE, SIGILL, SIGSEGV y SIGBUS). Para GNAT / Linux el manejador de señal se llama __ gnat_error_handler en a-init.c , que es como la siguiente:

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);
 }

Este controlador es "proceso amplia", y será llamado por cualquier señal trigged, no importa de qué parte del proceso se origina a partir de (no importa si codificado en Ada / C / C ++ ...).

Cuando se llama, el controlador se eleva un Ada-excepción y deja que el tiempo de ejecución Ada para encontrar un controlador de excepciones apropiado - si no se encuentra dicho controlador (por ejemplo, cuando un SIGSEGV es generado por cualquier parte de la C ++ -. Código) , el tiempo de ejecución de Ada-cae de nuevo a apenas termine el proceso y acaba de salir de una impresión sencilla de __ gnat_error_handler (por ejemplo. "desbordamiento de pila (o acceso a la memoria errónea)").

http://www2.adacore.com/gap-static/ GNAT_Book / html / node25.htm

Para evitar Ada-tiempo de ejecución de manejo de una señal POSIX, y convertirlo a una Ada-excepción, es posible desactivar el beahviour predeterminado utilizando

Pragma Interrupt_State (Nombre => valor, Estado => SISTEMA | DURACIÓN | USUARIO);

por ejemplo. desactivar la manipulación de SIGSEGV, definir

Pragma Interrupt_State(SIGSEGV, SYSTEM);

en su código de Ada-- ahora será trigged el comportamiento predeterminado del sistema cuando se levantó una SIGSEGV, y un núcleo-dump se generará que le permite rastrear hasta el origen del problema

Creo que este es un tema muy importante ser consciente de la hora de mezclar Ada y C / C ++ en * NIX-plataformas, ya que puede inducir a error a pensar que los problemas orígenes de la Ada de código (ya que la copia impresa indica una excepción generado a partir de Ada) cuando la fuente real del problema reside en la C / C ++ - código ...

A pesar de que es probable que sea seguro para desactivar el modo predeterminado de tiempo de ejecución de Ada-SIGSEGV (supongo que ningún programador sano usando esto en cualquier error "espera" manipulación ... Bueno, puede utilizarse en el software de la aviación o similares, cuando algún tipo de "último recurso" funcionabilidad necesita ser mantenida para evitar algo realmente malo suceda ..) Creo que un poco de precaución debe tomarse a continuación, "anulando" manejo de la Ada-tiempo de ejecución para las señales.

Un problema puede ser la señal SIGFPE, que también plantea una Ada-Constraint_Error excepción por defecto. Este tipo de excepción puede ser utilizado por el Ada-código como un "comportamiento excpected". Desactivación SIGFPE por Pragma Interrupt_State puede afectar gravemente a la ejecución del Ada-código y accidente de su aplicación durante las "circunstancias normales" - por el contrario lo hará cualquier división por cero en la C / C ++ - código trig el mecanismo de manejo de Ada-excepción, y dejar sin ningún rastro real del origen del problema ...

Otros consejos

Esto me parece como un realmente un buen uso de su AdaCore apoyo. Usted no es responsable de encontrar un montón de gente fuera de esa compañía que está familiarizado con las consecuencias de las interacciones entre el tiempo de ejecución de Ada de GNU y C ++ 's.

Yo sugeriría para depurar el código Ada que trate de poner en un gestor de excepciones de última zanja alrededor de todo, que a su vez vuelca la pila de excepción. La mayoría de los proveedores tienen alguna manera de hacer eso, por lo general basa fuera de Ada.Exceptions.Exception_Information y Ada.Exceptions.Exception_Message.

una discusión desde una perspectiva de seguridad (la búsqueda de malware). Básicamente hay 10 señales que se pueden probar, SIGSEGV es sólo uno de ellos.

Parece que sólo tiene que llamar sigaction(SIGSEGV, 0, SIG_DFL); para restaurar el comportamiento de la señal por defecto.

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