begin process at 2012 05 30 08:48:27
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C

 > 

Divers

 > 

Divers

 > 

Segfault


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Segfault

mercredi 14 octobre 2009 à 23:12:56 | Segfault

victorcoasne

Membre Club
Bonjour,

J'essaye d'éliminer un maximum toutes les erreurs de segfault pouvant intervenir dans mes classes et je butte sur un point.

Pour comprendre j'ai fait un code de démonstration :
Code C/C++ :
#include <cstdlib>
#include <iostream>

using namespace std;

class A
{
    public:
        virtual void methode1() = 0;
};

class B: public A
{
    public:
        void methode1()
        {
            if (this == NULL)
            {
                cout << "INSTANCE INVALIDE" << endl;
            }
            else
            {
                cout << "INSTANCE VALIDE" << endl;
            }
        }
        
        void methode2()
        {
            if (this == NULL)
            {
                cout << "INSTANCE INVALIDE" << endl;
            }
            else
            {
                cout << "INSTANCE VALIDE" << endl;
            }
        }
};

inline B& invalide()
{
    return ( *( (B*)NULL ) );
}

int main(int argc, char *argv[])
{
    B b;
    
    cout << "\n-- INSTANCE VALIDE --" << endl;
    b.methode2();
    b.methode1();
    
    cout << "\n-- INSTANCE INVALIDE --" << endl;
    invalide().methode2();
    invalide().methode1(); // Plantage ici
    
    system("PAUSE");
    return EXIT_SUCCESS;
}


Si vous avez des idées ou mieux la solution, je prends.

Merci d'avance et bonne prog,
@++

Victor
mercredi 14 octobre 2009 à 23:20:43 | Re : Segfault

victorcoasne

Membre Club
Bonjour,

On peut maintenant y ajouter des exceptions :
Code C/C++ :
#include <cstdlib>
#include <iostream>

using namespace std;

class A
{
    public:
        virtual void methode1() = 0;
};

class B: public A
{
    public:
        void methode1()
        {
            if (this == NULL)
            {
                cout << "INSTANCE INVALIDE" << endl;
                throw 0;
            }
            else
            {
                cout << "INSTANCE VALIDE" << endl;
            }
            cout << "METHODE 1" << endl;
        }
        
        void methode2()
        {
            if (this == NULL)
            {
                cout << "INSTANCE INVALIDE" << endl;
                throw 0;
            }
            else
            {
                cout << "INSTANCE VALIDE" << endl;
            }
            cout << "METHODE 2" << endl;
        }
};

inline B& invalide()
{
    return ( *( (B*)NULL ) );
}

int main(int argc, char *argv[])
{
    B b;
    
    cout << "\n-- INSTANCE VALIDE --" << endl;
    b.methode2();
    b.methode1();
    
    cout << "\n-- INSTANCE INVALIDE --" << endl;
    try
    {
        invalide().methode2();
    }
    catch(...)
    {
        cout << "EXCEPTION METHODE 2" << endl;
    }
    try
    {
        invalide().methode1(); // Plantage ici
    }
    catch(...)
    {
        cout << "EXCEPTION METHODE 1" << endl;
    }
    
    system("PAUSE");
    return EXIT_SUCCESS;
}


Voici la sortie avant le plantage du programme :
Code :
-- INSTANCE VALIDE --
INSTANCE VALIDE
METHODE 2
INSTANCE VALIDE
METHODE 1

-- INSTANCE INVALIDE --
INSTANCE INVALIDE
EXCEPTION METHODE 2


Merci et bonne prog,
@++

Victor
jeudi 15 octobre 2009 à 00:34:51 | Re : Segfault

CptPingu

Administrateur CodeS-SourceS
Ce genre d'erreur fait partit de celle qui ne devrait pas arriver. Personnellement, j'utilise des assert.


Code C/C++ :
#include <cassert>

assert(this);
jeudi 15 octobre 2009 à 18:21:59 | Re : Segfault

victorcoasne

Membre Club

Bonjour,

> Ce genre d'erreur fait partit de celle qui ne devrait pas arriver.
C'est pour ça que je veux générer une erreur sans faire planter le programme si jamais ça arrive.

assert n'est qu'une macro qui affiche un message d'erreur insuffisant au niveau compréhension pour un utilisateur lambda.

Si tu as d'autres idées, fais moi signe.

Merci de ton aide.

Bbonne prog,
@++

Victor
jeudi 15 octobre 2009 à 18:38:32 | Re : Segfault

CptPingu

Administrateur CodeS-SourceS

assert n'est qu'une macro qui affiche un message d'erreur insuffisant au niveau compréhension pour un utilisateur lambda.


Tu n'as donc pas compris assert.

Je vais m'expliquer. Il y a deux types d'erreur:
- L'erreur possible. C'est à dire, une erreur qui est "normale". Exemple classique: impossibilité d'ouvrir un fichier.
On utilise pour cela une gestion d'erreur. (code de retour, exceptions, ...).
- L'erreur qui ne doit pas arriver. Généralement, c'est un bug de l'application. Exemple typique: oublie d'allouer une classe.
Ce type d'erreur ne doit pas faire partie de l'application, et en ce sens être corrigée. C'est en ça qu'"assert" est utile. Ca te permet en mode debug, de t'assurer de la robustesse de ton code. Si un assert est déclenché, tu as immédiatemment la ligne et le fichier ou s'est produit le problème. Avoir un code bourré d'assert est gage de qualité, et de robustesse.
Ce n'est pas absolument pas destiné à un utilisateur. D'ailleurs, en mode release, les assert sont automatiqument effacés !

Il faut bien différencier ces deux cas, et le code d'exemple que tu as écrit, est clairement dans le second cas.
jeudi 15 octobre 2009 à 19:33:53 | Re : Segfault

victorcoasne

Membre Club
Bonjour,

Je suis d'accord avec toi mais imaginons que tu fasse une classe qui risque d'être maltraitée par d'autres développeur.

Si tu place des assert et que le développeur n'a jamais eu le cas d'un segfault (parce qu'il n'a pas prévu tous les cas), c'est l'utilisateur en release qui va voir son programme planter et le développeur ne sait pas quoi faire.
Si le développeur lui affiche une erreur dîte technique (dû à une mauvaise programmation qui s'oppose à applicative où l'utilisateur est en cause) l'utilisateur peut continuer à utiliser l'application ou pas mais le développeur saura qu'est-ce qui ne va pas et où.

Merci et bonne prog,
@++

Victor
jeudi 15 octobre 2009 à 22:24:17 | Re : Segfault

CptPingu

Administrateur CodeS-SourceS
Réponse acceptée !
Ce n'est pas vraiment possible. Si le programme plante, il plante !
Tu ne peux pas vraiment gérer ça. En effet, l'utilisateur qu'il voit: "segfault" ou "Un problème technique est survenue, merci de contacter etc...", il ne pourra pas faire grand chose.

Lorsque ce type d'erreur survient, on demande généralement au client de:
- Décrire ce qu'ils ont fait, pour reproduire le problème.
- Récupérer le core dump, qui contient la stack trace des derniers événement avant erreur.

Je comprends ton besoin, mais avec ta technique, tu vas inutilement complexifier le code. C'est beaucoup trop intrusif. Si c'est vraiment ce que tu veux, dans ce cas, fait toi une classe "SandBox" qui entoure chacun des classes, et en cas d'erreur affiche une erreur contenant le nom de la classe en cause (pas top, et encore trop intrusif à mon goût).

Une deuxième technique, utilisé notamment en java, est de créer un logger. Tu logges tout ce que tu peux, et en cas d'erreur, tu met simplement un "try{}catch(...){}" dans ton "main()", et tu propose à l'utilisateur d'envoyer le dit rapport.

PS:
Un autre moyen d'attraper un "segfault", est de se lier a ce signal:

Code C/C++ :
#include <iostream>
#include <csignal>
#include <cstdlib>

void onError(int)
{
  // Prevent infinite recursion if onError() causes another segfault
  std::signal(SIGSEGV, SIG_DFL);

  std::cout << "Segfault spotted !" << std::endl;
  std::abort();
}

int main ()
{
  std::signal(SIGSEGV, onError);
  int *p = 0;
  *p = 0; // Segfault

  return 0;
}


Il n'y a de toute façon pas de solution miracle :)
samedi 17 octobre 2009 à 10:17:38 | Re : Segfault

victorcoasne

Membre Club
Réponse acceptée !
Bonjour,

Ce code m'a l'air intéressant pour ce que je veux.

Sinon j'ai lu que les fonctions virtuelles sont liés (grâce à une VTABLE) à l'exécution et non à la compilation. Ce qui fait que le corps de la méthode n'est pas appelée avant que le programme plante.

Donc à part catcher un segfault, on ne peux pas faire grand chose.

Merci pour ton aide.

Bonne prog,
@++

Victor


Cette discussion est classée dans : instance, cout, endl, invalide, methode1


Répondre à ce message

Sujets en rapport avec ce message

probleme sur une classe [ par NerOcrO ] Voici mon code :#include #include class Chanson //classe Chanson{ public: int Duree; char TypeDeFichier[3], Auteur[50], Titre[50], Interprete[50 Pas De Solution??? [ par PsyCaDi ] Bonjour,Voilà, je veux faire un truc tout con avec des tableaux mais ça ne marche pas. Quelqu'un peut-il me dire ce qui n'est pas bon (sauf moi, ça je que des boucles. [ par pratix ] Salut à tous.Je post mon prg cherchenbr modifié (voir sujet précédent ''int main" ).Programme compilé avec visual C++ 06. ( zéro erreur )j'ai essay caractere speciaux a afficher en boucle [ par ranouf ] #include void main (){ cout cout cout}comment faire pour automatiser cette tache ?j'aurai besoin de savoir a koi correspon c++ algo [ par altay ] L'analyste programmeur a 3 dimensionest ce que quelqu'un pourrait me faire l'algo de ce code merci d'avance :#pragma hdrstop#include #include algo C++ [ par altay ] L'analyste programmeur a 3 dimensionest ce que quelqu'un pourrait me faire l'algo de ce code merci d'avance :#pragma hdrstop#include #include fichier exel (lecture et ecriture) [ par rissorg ] Bonjour a tous!j'essaye de faire un programme qui doit lire differents fichiers exel ,comparer les donnees lu au donnees contenu dans un fichier text imcomprehension const_cast [ par omi ] Je ne comprennait pas l'utilité de const_cast alors j'ai pris un exemple : const int cst = 20;int *z = const_cast(&cst);*z = 30;cout cout << bind bought bought lier [ par JoebarGlut ] Salut, j'ai un piti problem de bind, kelkun peut il m'eclairer ?j'explik : (c'est un client qui se metamorphose en serveur ou en client suivant ce qu' besoin d'eclaircissement sur les classes et pointeurs [ par oliarn ] bonjour,je fais un programme en c++ pour la fac e tj'aimerai savoir comment manipuler mes classes dans mon programmes.voila une fonction par exemple m


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 4,852 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales