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 :

masquer un segv dans un fork


Sujet :

C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 40
    Points : 37
    Points
    37
    Par défaut masquer un segv dans un fork
    Bonjour à tous, et joyeux noël !

    Donc, je m'explique,
    je travaille en ce moment sur un petit projet, un minishell, et je voudrais que quand je lance un programme qui segv dans mon shell, il m'affiche un petit "Segmentation fault".

    voilà ce que j'ai essayer de faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if (fork() == 0)
        {
          signal(SIGSEGV, test_segv);
          if (execve(filename, argv, env) < 0)
            {
              my_printf("%s: command not found\n", argv[0]);
              exit(-1);
            }
        }
      else
        wait(NULL);
    test_segv affiche simplement "segmentation fault" sur la sortie d'erreur.
    Merci d'avance.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Hello,

    Il faut récupérer le statut de ton processus mort en donnant l'adresse d'une variable de type « int » à la place de NULL dans ton wait().

    De là, tu pourras utiliser WIFSIGNALED() pour savoir si ton fils a bien reçu un signal qui a causé sa fin et, le cas échéant, WTERMSIG() pour connaître son numéro et vérifier s'il est égal à SIGSEGV.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 40
    Points : 37
    Points
    37
    Par défaut
    j'ai pas le droit a wifsignaled et wtermsig :/
    j'ai réussi à capter le signal le mon programme pere pour remplacer mon ctrl+c par un "\n"
    mais la quand j'utilise signal dans mon programme fils, il ne me cache pas le prochain signal :/

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Citation Envoyé par nemesis57 Voir le message
    j'ai pas le droit a wifsignaled et wtermsig :/
    Comment ça, tu n'as « pas le droit » à WIFSIGNALED et WTERMSIG ?? C'est la manière normale d'évaluer les causes de la fin d'un processus !

    Si tu n'en as « pas le droit », j'en conclus que cet un exercice scolaire. En tout état de cause, soit il y a quelque chose que tu n'as pas compris dans l'énoncé, soit c'est ton prof' qui mélange des choses (et ce ne serait pas la première fois que cela arrive).

    j'ai réussi à capter le signal le mon programme pere pour remplacer mon ctrl+c par un "\n" mais la quand j'utilise signal dans mon programme fils, il ne me cache pas le prochain signal :/
    Et c'est normal. Pour « catcher » un signal, il faut installer un gestionnaire (handler) de signal. J'ajoute qu'attraper SIGSEGV est une TRÈS MAUVAISE IDÉE ! Il existe bien une bibliothèque pour ce faire et cela peut y avoir un intérêt dans des cas précis, mais c'est très rare et rattraper SIGSEGV pour le principe, c'est plus signe que l'on a pas vraiment compris de quoi il s'agit.

    Explique-nous plus en détails quelle est la problématique de ton projet et où tu veux en venir en détails.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 40
    Points : 37
    Points
    37
    Par défaut
    la problematique de mon projet est expliquée dans mon premier message:
    je dois faire un shell
    dans mon shell je peux lancer des binaires ceux dans la variable d'environnement PATH mais aussi nimporte quel autre binaire.
    Le soucis c'erst que je lance un programme qui segv dans mon shell, je voudrais qu'il lance une fonction (c'est pour ca que je me sers de signal)
    comme je disais, avec signal j'ai déjà réussi a remplacer les SIGINT par des \n mais j'arrive pas, à choper le SIGSEGV du processus fils
    non je ne veux pas cacher le SIGSEGV de mon programme, mais celui du processus fils (lancé dans mon shell) qui pourrait evantuellement segv

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Lorsque tu utilises signal() ou sigaction(), tu installes avant tout un gestionnaire pour le processus lui-même. Un fils créé avec fork va hériter de ces gestionnaires mais ils seront réinitialisés lorsque tu lanceras un programme avec un exec (et heureusement).

    On ne cache ni son propre signal ni celui de son processus fils et, surtout, ce n'est pas le processus incriminé qui va renvoyer lui-même un message. Le shell est là pour lancer des applications et surveiller leur évolution, ne serait-ce que pour rendre la main à l'utilisateur au bon moment. C'est donc bien au shell d'informer ce dernier qu'un processus est mort et de dire pourquoi.

    Ensuite, on ne cache pas un SEGV sans savoir exactement ce que l'on fait. Il ne s'agit pas d'une erreur système mais d'une exception levée par le micro-processeur pour dire que le programme contient du code compilé qui, à un moment donné, a essayé d'écrire à un endroit interdit. Il ne faut donc pas rendre la main à un code défectueux par nature. La cause n'a rien à voir avec celle des autres signaux.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 40
    Points : 37
    Points
    37
    Par défaut
    désolé pour la faute de frappe, je veux pas cacher mais catcher
    enfaite dans mon shell quand je mance un programme qui segv, il me reaffiche le prompte sans rien marquer
    la seule chose que je voulais faire c'etait afficher segv quand programme segv

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Citation Envoyé par nemesis57 Voir le message
    désolé pour la faute de frappe, je veux pas cacher mais catcher enfaite dans mon shell quand je mance un programme qui segv, il me reaffiche le prompte sans rien marquer la seule chose que je voulais faire c'etait afficher segv quand programme segv
    J'ai bien compris, oui. Es-tu sûr, toi, d'avoir bien saisi le sens de mes commentaires ?

    Ce n'est pas au programme fautif d'afficher un message quand il plante, puisqu'il plante. C'est à ton Shell de détecter la mort de son fils, d'en déterminer les raisons, et d'afficher le message en conséquence.

    Donc, invoquer signal() depuis ton processus père (le Shell) ne servira à rien puisque ce n'est pas lui qui recevra le signal en question (et qu'il est préférable de toutes façons de ne pas intercepter un SIGSEGV). C'est avec wait(), que tu appelles déjà, que tu sera prévenu de la fin de ton processus fils. Et wait() est capable de te renvoyer un code de statut. C'est lui qu'il faut interpréter si ton programme est mort suite à une segfault.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 40
    Points : 37
    Points
    37
    Par défaut
    Merci, en fait c'est bon, je le suis renseigné, et on le droit a WTERMSIG. Merci de ton aide

    Par contre, j'ai un autre souci : je veux masquer le SIGINT de mon shell pour que lorsque je tape Ctrl + C, ça ne le quitte pas. Là, j'ai fait ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    rrd = 1;
      while (rrd)
        {
          my_bzero(str, 256);
          my_putstr("$>");
          signal(SIGINT, hide_sigint);
          rrd = read(0, str, 256);
          str[rrd - 1] = 0;
          minishell(str, &lenv, home);
        }
    … et hide_sigint fait un « /n ».

    Ça marche très bien, sauf que le souci, c'est lorsque je lance mon shell dans mon shell, signal fait n'importe quoi (Je SIG_DFL bien avant le fork).

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Citation Envoyé par nemesis57 Voir le message
    Ça marche très bien, sauf que le souci, c'est lorsque je lance mon shell dans mon shell, signal fait n'importe quoi (Je SIG_DFL bien avant le fork).
    Mais encore ?

Discussions similaires

  1. Masquer l'application dans la barre des tâches
    Par jmjmjm dans le forum Composants VCL
    Réponses: 2
    Dernier message: 28/11/2016, 12h50
  2. Masquer l'aborescence dans l'url
    Par Yoshidu62 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 11
    Dernier message: 10/04/2006, 15h57
  3. Comment masquer la saisie dans un Memo???
    Par Jayceblaster dans le forum Delphi .NET
    Réponses: 1
    Dernier message: 04/04/2006, 16h19
  4. Masquer des champs dans un formulaire
    Par crazykingpin dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 30/12/2005, 15h29
  5. Réponses: 1
    Dernier message: 05/11/2004, 17h15

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