Question

Comment puis-je obtenir une application C ++, y compris une bibliothèque partagée ada chargée pour générer un fichier core lors d'un plantage ?

I ai une application C ++ qui charge une bibliothèque partagée ada, à l'intérieur du code ada j'obtenir une erreur de débordement de pile qui provoque la fin du programme en même temps que la sortie de la console:

raised STORAGE ERROR

Aucun fichier de vidage de base est généré même tu j'ai publié un « ulimit -c unlimited » avant de lancer l'application.

Même chose si j'envoie une mise à mort SIGSEGV à l'application.

Envoi kill SIGSEGV à une autre application qui n'utilise pas la dll ada génère un fichier de vidage de base juste la façon dont je veux.

trouvé quelques informations ici: http: // objectmix. com / ada / 301203-moucheron-fstack-check-t-work.html

À JOUR! Comme mentionné par Adrien, il n'y a pas de contradiction, -s définit la limite de la pile tandis que -c définit la limite de fichier de base.

Mais le problème reste. J'ai vérifié les drapeaux lors de la construction de la bibliothèque de ada et fstack vérification drapeau n'a pas été défini, il devrait donc générer une décharge de base.

althou Je ne l'ai pas encore essayé, il semble un peu étrange. Il mentionne l'option du compilateur -fstack-check + définissant la variable GNAT_STACK_LIMIT mais en même temps, fait référence à la commande ulimit qui semble être une contradiction, la mise en « ulimit -c » est la seule façon que je connaisse obtenir une décharge de base à générer au moment de l'accident, si ce infère avec l'option fstack vérification alors nous avons une prise 22.

Était-ce utile?

La solution

Maintenant, presque 2 ans plus tard (en travaillant dans la même entreprise que Kristofer a fait quand il a posé la question), était la question posée à nouveau - et, enfin, je pense que je comprend pourquoi pas-core dump est généré !!

Le problème est dû à la gestion du temps, qui par défaut Ada met en oeuvre un gestionnaire de signal pour des signaux POSIX (pour Linux: SIGABRT, SIGFPE, SIGILL, SIGSEGV et SIGBUS). Pour GNAT / linux le gestionnaire de signal est appelé __ gnat_error_handler un init.c , qui ressemble à ceci:

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

Ce gestionnaire est « large processus », et sera appelé par tout signal trigged, peu importe de quelle partie du procédé, il provient (peu importe si codé en Ada / C / C ++ ...).

Lorsqu'elle est appelée, le gestionnaire monte une Ada-exception et laisse à l'exécution Ada pour trouver un gestionnaire d'exception approprié - si aucun gestionnaire se trouve (par exemple, lorsqu'un SIGSEGV est généré par une partie du C ++ -. Code) , l'Ada-exécution revient à mettre fin à tout le processus et il suffit de laisser une impression simple à partir de __ gnat_error_handler (par exemple. "débordement de pile (ou accès mémoire erronée)").

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

Pour éviter Ada-exécution de la manipulation d'un signal POSIX et de le convertir à une Ada-exception, il est possible de désactiver le beahviour par défaut en utilisant

pragma Interrupt_State (nom => valeur, Etat => SYSTEM | RUNTIME | USER); ,

par exemple. pour désactiver le traitement des SIGSEGV, définir

Pragma Interrupt_State(SIGSEGV, SYSTEM);

dans votre Ada code - maintenant le comportement par défaut du système sera trigged lorsqu'un SIGSEGV est élevé, et une décharge de base sera généré qui vous permet de tracer jusqu'à l'origine du problème

Je pense que cela est une question tout à fait important d'être conscient du moment où le mélange Ada et C / C ++ sur * NIX-plates-formes, car il peut vous induire en erreur de penser que les origines des problèmes du code Ada (depuis la sortie imprimée indique une exception générée à partir de Ada) lorsque la source réelle du problème réside dans le C / C ++ - code ...

Bien qu'il soit probablement sûr de désactiver le traitement par défaut Ada-runtime de SIGSEGV (je suppose aucun programmeur sain d'esprit en utilisant ceci dans une gestion des erreurs « prévu » ... Eh bien, peut-être utilisé dans le logiciel aéronautique ou similaire, quand une sorte de « dernier recours » functionallity doit être maintenu pour éviter quelque chose de vraiment mauvais de se produire ..) je suppose une mise en garde peu devrait être prise alors « remplaçant » la manipulation Ada-exécution pour les signaux.

Une question peut être le SIGFPE signal, ce qui soulève également une Ada Constraint_Error-exception par défaut. Ce type d'exception peut être utilisé par le code Ada comme un « comportement excpected ». La désactivation SIGFPE par Pragma Interrupt_State peut sérieusement affecter l'exécution du code Ada et planter votre application lors des « circonstances normales » - d'autre part, sera une division par zéro dans le C / C ++ - Code trig le mécanisme de traitement Ada-exception, et vous laisser sans aucune trace réelle de l'origine du problème ...

Autres conseils

Cela me semble comme un vraiment bon usage pour votre AdaCore . Vous n'êtes pas responsable de trouver beaucoup de gens en dehors de cette société qui sont familier avec les conséquences des interactions entre l '. Le temps d'exécution de Gnu Ada et C ++

Je suggère pour le débogage du code Ada que vous essayez de mettre dans un gestionnaire d'exception dernière chance autour de tout, ce qui vide la pile d'exception. La plupart des fournisseurs ont une certaine façon de le faire, le plus souvent basé sur des Ada.Exceptions.Exception_Information et Ada.Exceptions.Exception_Message.

J'ai trouvé une discussion du point de vue de la sécurité (trouver des logiciels malveillants). Fondamentalement, il y a 10 signaux que vous pouvez essayer, SIGSEGV est seulement l'un d'entre eux.

Il semble que vous pouvez simplement appeler sigaction(SIGSEGV, 0, SIG_DFL); pour restaurer le comportement du signal par défaut.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top