IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

Signaux: abandon incompréhensible et indéboguable du programme.


Sujet :

Linux

  1. #1
    Membre averti

    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2013
    Messages
    182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Pérou

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2013
    Messages : 182
    Points : 375
    Points
    375
    Par défaut Signaux: abandon incompréhensible et indéboguable du programme.
    Bonjour,

    J’écris un logiciel qui émule une machine qui a existé il y a maintenant plus de 25 ans. Il s’agit d’un ordinateur à base de MC6801/3 (un ancien processeur / microcontroleur 8 bits de Motorola) qui opérait l’OS Flex2.

    Un bout de code fourche (fork) puis chaque branche ouvre un terminal (xterm, urxvt ou autre konsole), l’un exécutant l’émulateur avec son moniteur-débugger et l’autre simulant simplement une VT52. J’usqu’à maintenant, pas de problème, et le projet est bien avancé, bien qu'il reste beaucoup à faire. Il existe une commande du débogeur/moniteur qui permet de générer une interruption du processeur émulé (NMI ou IRQ), et cette partie se passe bien.

    J’ai voulu être interrompu régulièrement (comme le matériel d’antan) et ai utilisé setitimer() pour ça. Mode ITIMER_REAL → SIGALRM. Tout fonctionne bien si ce n’est que le programme d’émulation s’arrête. J’ai beau chercher à savoir pourquoi, rien n’y fait : je ne trouve pas. Je ne sais pas où me mettre (avec le débogeur DDD) pour voir d’où vient le problème. J’imagine qu’un autre signal (d’erreur, probablement) est généré et que le handler par défaut de ce signal provoque l’abandon, mais je n’imagine pas de solution pour intercepter afin de débugger.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
      pthread_mutex_t tiMut=PTHREAD_MUTEX_INITIALIZER;
      sig_atomic_t mSC=0;
     
      static void EmuEndPeriod (void) { // void (and !int sig) To escape the warning
      /// **************************************************************************
      /* The handler is invoqued with SIGALRM (|SIGPROF|SIGVTALRM) signa. The
      kBitIRQ of _6303.IrqFlgs or kBitNMI of _6303.IrqFlgs will be set to initiate
      an interrution while stepping. As in the real word, it is the responsability
      of the emulated program to "acknowledge" the concerned bit. */
      pthread_mutex_lock(&tiMut); //sig=0; // To escape the warning
      mSC+=1; // EmuIsGone ? _6303.IrqFlgs|=kBitNMI :0; // Sets the bit NMI
      pthread_mutex_unlock(&tiMut);
      }
     
      int EmuStep (void) {
      /// **************************************************************************
      // Returns 0 if the opcode [_EmuGetMem(_6303.Pc)] is invalide
    …
      pthread_mutex_lock(&tiMut);
      if ((i=mSC))
        mSC=0;
      pthread_mutex_unlock(&tiMut);
        if (i) {
          if (gTimer2_NMI) {
            if(!(gRunner2-=i) || gRunner2&kBit(15)) { // Expiration if virtualy <0
              gRunner2=gTimer2_NMI+gRunner2; // Re-init the timer
              _6303.IrqFlgs|=kBitNMI; // Sets the bit NMI
            }
          }
          if (gTimer4_IRQ) {
            if(!(gRunner4-=i) || gRunner4&kBit(15)) { // Expiration if 0
              gRunner4=gTimer4_IRQ+gRunner4; // Re-init the timer
              _6303.IrqFlgs|=kBitIRQ; // Sets the bit IRQ
            }
          }
        }
    /** Interruption treatment is placed here to permit the execution of at least
        one instruction after the registers had been pushed in stack.
        One of the 10 bits corresponding to the IRQ is set somewhere in this function
        (see EmuSpcActLeave(), above). See IrqFlgs definition NOTE */
        if (_6303.IrqFlgs) { // All bits
          if (_6303.IrqFlgs&kBitRST) { // Immediat and unconditional action
            _6303.IrqFlgs&=~kBitRST;
            EmuReset();
            return(1);
            }
          else if ((_6303.IrqFlgs&kBitNMI) && // NMInterrupt request
                   ((_6303.IrqPre^_6303.IrqFlgs)&kBitNMI)) // Falling edge (↑ indeed)
            EmuEnterIt(Vect_NMI);
          else if ((_6303.IrqFlgs&kBitIRQ) && (!(_6303.Cc&kI)))
            EmuEnterIt(Vect_IRQ);
        }
        _6303.IrqPre=_6303.IrqFlgs; // Note of the current state (solely for NMI)
    L’"allumage" du timer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
      const struct itimerval gPeriod={{ 2, 10000 }, { 2, 10000 }};
     
      void SetFreeRunner (void) {
      /// **************************************************************************
      // ITIMER_REAL:SIGALRM | ITIMER_VIRTUAL:SIGVTALRM | ITIMER_PROF:SIGPROF
      static struct sigaction sa; // http://mtodorovic.developpez.com/linux/programmation-avancee/?page=page_8
        memset(&sa, 0, sizeof (sa));
        sa.sa_handler=(void(*)(int))&EmuEndPeriod;
        sigaction(SIGALRM, &sa, NULL);
        if (setitimer(ITIMER_REAL, &gPeriod, NULL)<0) //
          PerrExit("setitimer() a provoqué une erreur", 1);
      }
    Vous aurez compris que ma question est : savez-vous comment je pourrais me sortir de là ?

    À noter que je placerai le tout en ligne et sous licence GNU. S'il vous tente de jeter un œil sur le projet, faites le moi savoir.

    Je vous remercie pour l'attention que vous aurez porté à ce post.
    Cordialement

    Merci à Jérome.

  2. #2
    Membre averti

    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2013
    Messages
    182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Pérou

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2013
    Messages : 182
    Points : 375
    Points
    375
    Par défaut
    Bonjour,

    J'avais déjà vu ça, mais zappé pour une mauvaise raison. C'est ici que ça quitte, sur le premier exit(). Et silencieusement à cause du EXIT_SUCCESS.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
      int GetCFrom (IOnum from, char *buff) {
      /// **************************************************************************
      fd_set  set;
      struct timeval tiOut={0};
      int rcvd;
        if (FdIsValid(from)) {
          FD_ZERO(&set); // Effacement de tout descripteur de l'ensemble "set"
          FD_SET(from, &set); // Ajouter le descripteur de cette entrée
          if (select(from+1, &set, NULL, NULL, &tiOut) < 0) // Sélection parmis ceux du jeu "set"
            exit(EXIT_SUCCESS); // Sortie normale (le pipe a été rompu)?
          if (FD_ISSET(from, &set)) { // Si l'entrée du pipe ne bloquera pas
            if ((rcvd=read(from, buff, 1))!=1) // Lire ce qui y est disponible
              exit(EXIT_SUCCESS); // Sortie normale (le pipe a été rompu)?
            return(*buff);
          }
        }
      return(-1);
      }
    Pourquoi l'utilisation de setitimer() causerait cette erreur ? Parce qu'il génère un signal, pour le moins ! Il m'aura suffit de lire cette page.

    C'est pas fini. Et je dois sérieusement retoucher mon code. Mais au moins, tout espoir n'est pas perdu!

    Paulo

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 22/04/2014, 09h15
  2. Programmation Système : Signaux
    Par fred44ooo dans le forum Linux
    Réponses: 7
    Dernier message: 04/05/2010, 09h13
  3. programmation des signaux avec c
    Par nanouchou dans le forum Linux
    Réponses: 12
    Dernier message: 09/01/2009, 16h57
  4. Programmation systeme en C et les signaux
    Par Traboulidon dans le forum Réseau
    Réponses: 27
    Dernier message: 06/02/2007, 10h32
  5. Réponses: 4
    Dernier message: 12/11/2006, 18h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo