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

C Discussion :

reprendre en séquence après un SIGFPE


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut reprendre en séquence après un SIGFPE
    bonjour,
    j'ai bricolé pour un projet une plateforme munie de jauges de pression.
    L'aspect bricole de l'électronique + la longueur des fils pas vraiment blindé font que de temps en temps je lis une valeur nulle en sortie du DAC. Le signal étant toujours parasité malgré le filtrage.
    Et dans mon calcul, j'effectue donc de temps en temps une division par 0.
    J'ai mis en place un gestionnaire sur SIGFPE mais pour l'instant, je le termine par un exit() pour ne pas reboucler en permanence dans le gestionnaire.
    Or, si je détecte une lecture à 0, ça ne me gêne pas, je passe à la suivante sans en tenir compte.

    Test unitaire sur lequel je travaille la question:
    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
     
    void gestion_sigfpe(int n)
    {
        nb++;
        printf("sigfpe %d\n",n );
        //exit(-1);
    }
     
    //dans mon main:
    struct sigaction segv_s;
     
    fpe_s.sa_handler = gestion_sigfpe;
    fpe_s.sa_flags=0;
    sigaction(SIGFPE,&fpe_s,0);
     
    i = 752;
    calcul = (225 * i)/jaugeValue;
    printf("On continue en séquence\n");
    je ne reviens jamais à "on continue en séquence".
    Ce que je veux est-il possible?

    Merci.

  2. #2
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonsoir,
    Citation Envoyé par rdtech Voir le message
    je ne reviens jamais à "on continue en séquence".Ce que je veux est-il possible? Merci.
    Il existe une possibilité, celui d'un saut non-local ; cela vous permettra d'ignorer le signal SIGFPE et de reprendre l'exécution du programme à un emplacement donnée ce qui donne l'exemple ci-dessous.
    Cependant, n'ayant pas le code source dans sa totalité, je ne peux que l'interpréter sur la base de votre exemple.
    Attention tout de même au fait d'ignorer des signaux comme SIGFPE ou SIGSEV; car le comportement du programme peut être indéterminé.

    Code C : 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
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <signal.h>
    #include <setjmp.h>
     
     
    sigjmp_buf jmp_context;
     
    void signal_handler( int flags ){
     
        siglongjmp( jmp_context, 1 );
        /*    echec du saut    */
        if( SIG_ERR == signal(flags, SIG_DFL) ){
            (void)fprintf(stderr, "Error(%d)\t:%s\n", errno,
                strerror(errno) );
            abort(); /* core dump    */
        }
        (void)raise( flags );
    }
     
     
    int main( void ){
     
        int jaugeValue = 10;
        struct sigaction sig;
     
        sig.sa_flags = 0;
        sig.sa_handler = signal_handler;
        sigfillset( &sig.sa_mask );
        sigaction( SIGFPE, &sig, NULL );
     
        for( ;; ){
            if( 0 != sigsetjmp(jmp_context, 1) )
                (void)fprintf(stderr, "Div zero !!!!\n");
     
            /* Test capture    */
            for( int i = 0; ((2*i)/--jaugeValue) != -1; i++ ){
                (void)puts("next calcul..");
            }
            break;
        }
     
        return EXIT_SUCCESS;
    }

    À bientôt.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  3. #3
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut
    Bonjour et merci pour cette réponse.
    Pourquoi l'utilisation de signal() dans le gestionnaire alors que certaines docs la donne comme obsolète?

  4. #4
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par rdtech Voir le message
    Bonjour et merci pour cette réponse.
    Pourquoi l'utilisation de signal() dans le gestionnaire alors que certaines docs la donne comme obsolète?
    Parce qu'il n'a jamais été précisé dans votre dernier message de ne pas utiliser signal() et aussi parce que j'utilise signal() pour ignorer un signal et rétablir par la suite le comportement par défaut; l'exemple est donc là pour vous montrer que c'est possible sans trop d'efforts répondant ainsi à votre question "je ne reviens jamais à "on continue en séquence". Ce que je veux est-il possible?"

    Oui signal est déprécié, mais ça reste tout de même un l'appel système simple pour l'installation d'un gestionnaire de façon rapide pour la gestion d'un signal; même si, cette dépréciation se base sur le fait qu'il peut potentiellement y avoir une incompatibilité entre les systèmes d'exploitation de la famille Unix qui ne permet pas au gestionnaire de rester en place après avoir été invoqué, mais également le fait qu'il peut ne pas délivrer le signal (je vous laisse le soin d'ajouter _XOPEN_SOURCE et de comprendre pourquoi il est dit déprécié ou obsolète). Ceci dit, rien ne vous empêche de remplacer signal() par un autre gestionnaire de signal comme sigaction() ou tout autre pour la gestion de vos signaux.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

Discussions similaires

  1. Reprendre un site après plantage.
    Par mormach dans le forum Dreamweaver
    Réponses: 2
    Dernier message: 26/05/2008, 19h39
  2. Thread, reprendre la main après un sleep
    Par Invité1 dans le forum Concurrence et multi-thread
    Réponses: 5
    Dernier message: 07/04/2008, 21h55
  3. Reprendre le code après une instruction stop
    Par sash6 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 15/11/2007, 16h07
  4. [DOS] Reprendre la main après le lancement d'un programme
    Par kimz dans le forum Scripts/Batch
    Réponses: 9
    Dernier message: 28/05/2007, 23h58
  5. Réponses: 3
    Dernier message: 28/11/2006, 12h38

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