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

Fortran Discussion :

Origine d'une violation d'accès


Sujet :

Fortran

  1. #1
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut Origine d'une violation d'accès
    Salut à tous,

    J'ai un problème de violation d'accès dans un code assez gros (10 000 lignes).

    La situation est la suivante :

    - Je n'ai aucun warning ou erreur à la compilation, que ce soit gfortran ou Intel Fortran

    - Avec gfortran, je n'arrive pas à reproduire la violation d'accès

    - Avec Intel Fortran (environnement Visual Studio qui me sert de debugger au besoin), je n'arrive pas à reproduire la violation d'accès lorsque les optimisations sont désactivées. Dès que je les active, paf, violation d'accès, mais du coup la ligne d'erreur indiquée est plus ou moins arbitraire (les infos de debug doivent plus vraiment être utilisables)

    Je peux activer un certain nombre de checks de runtime, mais par exemple, je ne peux pas activer le check stack frame (qui désactive les optis donc plus d'access violation). Les autres checks eux ne relèvent pas d'erreur

    Du coup je ne sais pas comment m'y prendre pour trouver la source de l'erreur.

    Les seules infos que j'ai, c'est donc ce qu'il dit, à savoir

    "Exception non générée à 0x0030264c dans machin.exe : 0xC0000005 : Violation d'accès lors de l'écriture à l'emplacement 0x38f07b1a."

    La ligne d'arrêt du curseur étant le début d'une entry (entry PRSADI de la subroutine PRSAD).

    Quand je regarde le code machine, que je demande l'emplacement 0x0030264c, il m'affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0030264C   call          TXS_AXS(2C31D0H)
    et il remplace l'adresse "0x0030264c" dans le champ de recherche par "PRSAD(void)"

    Pour l'emplacement 0x38f07b1a, il m'affiche :
    Sans remplacer l'adresse dans le champ de recherche.

    A noter :

    - TXS_AXS est une toute petite routine géométrique (elle prend comme arguments une matrice 3x3 et un vecteur 3), qui est appelée à de nombreux endroits dans le code. Il n'y a aucune erreur ou risque dans celle-ci, elle est vraiment très courte (~10 lignes) et tout y est bien déclaré. En revanche peut-être bien sûr qu'un des appels à cette routine contient une erreur ? Mais je les ai parcourus, je n'ai pas l'impression...

    - TXS_AXS n'est pas appelée dans PRSAD (aucune des ENTRY)

    - PRSAD elle-même semble ok (pas de variable en argument d'une entry qui serait utilisée par une autre entry sans être aussi un argument, tableaux déclarés, ...)

    Si vous avez des idées, je suis preneur...

    Merci

  2. #2
    Membre averti
    Homme Profil pro
    [SciComp]
    Inscrit en
    Août 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : [SciComp]

    Informations forums :
    Inscription : Août 2013
    Messages : 134
    Points : 323
    Points
    323
    Par défaut
    Bonjour,

    J'ai déjà vu ça il y a quelques années dans un vieux code qui n'a plus fonctionné avec ifort alors qu'il avait été utilisé avec succès avec gfortran, pgf, et d'autres (avec probablement des versions précédentes d'ifort avant d'ailleurs...) ; avec une error de segmentation au runtime qui pointait sans tambours ni trompettes. J'avais contourné le problème avec des changements mineurs dans les appels.

    Pourriez-vous mettre plus de précisions, comme par exemple, si c'est f77-like :
    utilisez-vous des common blocks dans le bout de code qui plante (variables en argument appelées ou utilisées dans la routine) ? Si oui, quel type de variable comprote(nt)-t-il(s) (types de variable homogènes dans le bloc ou pas) ? comment sont appelées les variables ?
    => Bref un header minimal (variables) de la routine de départ et de la routine appelée, de l'appel etc...

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Ce type d'erreur est effectivement très difficile à trouver.

    Tu devrais essayer avec un 3ième compilateur. Une version essai 30 jours ou quelque chose du genre.

    Une autre piste possible : j'ai souvent obtenu des résultats intéressants en insérant des writes dans le code. L'information ne venait pas de ce qui était imprimé, mais de la réorganisation du code compilé que provoquait l'ajout des writes : ça changeait le comportement du programme et je pouvait déduire où se trouvait l'erreur.

  4. #4
    Nouveau membre du Club
    Inscrit en
    Octobre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 48
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par xflr6 Voir le message
    Pourriez-vous mettre plus de précisions, comme par exemple, si c'est f77-like :
    utilisez-vous des common blocks dans le bout de code qui plante (variables en argument appelées ou utilisées dans la routine) ? Si oui, quel type de variable comprote(nt)-t-il(s) (types de variable homogènes dans le bloc ou pas) ? comment sont appelées les variables ?
    => Bref un header minimal (variables) de la routine de départ et de la routine appelée, de l'appel etc...
    Le problème est justement que je ne sais pas quel est le bout de code qui plante. Si je le savais, il n'y aurait plus de problème !

    Citation Envoyé par Sylvain Bergeron Voir le message
    Une autre piste possible : j'ai souvent obtenu des résultats intéressants en insérant des writes dans le code. L'information ne venait pas de ce qui était imprimé, mais de la réorganisation du code compilé que provoquait l'ajout des writes : ça changeait le comportement du programme et je pouvait déduire où se trouvait l'erreur.
    Je conçois le principe mais je ne comprends pas bien comment l'appliquer. Imaginons j'ajoute un write à la ligne x, et je constate que ça plante idem, ou que ça ne plante plus.

    Quelle déduction concrète puis-je faire dans un cas comme dans l'autre ? Si ça ne plante plus, alors "c'est par là que ça se passe" ? Ou peut-on être plus précis ?

  5. #5
    Membre averti
    Homme Profil pro
    [SciComp]
    Inscrit en
    Août 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : [SciComp]

    Informations forums :
    Inscription : Août 2013
    Messages : 134
    Points : 323
    Points
    323
    Par défaut
    Citation Envoyé par ParkerL31884 Voir le message
    Le problème est justement que je ne sais pas quel est le bout de code qui plante. Si je le savais, il n'y aurait plus de problème !
    Visiblement, c'est PRSAD OU TXS_AXS...

    Si tu es sûr de tes routines, et tu en a l'air, il faut que tu saches à quel appel la/les routine/s plante/nt. La méthode naïve qui consiste à appeler l'indien en faisant des signaux de fumées (traduire : ajouter un print indiquant la routine appelée et éventuellement un compteur si plusieurs appels au sein d'une mm routine, avant chaque call de PRSAD ou les autres routines susceptibles de poser pb), style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print *, "PRSAD from routinededepart, call#", i
    )
    n'est peut-être pas optimale mais rudement efficace pour identifier un pb, ou plutôt pour savoir à quel endroit précis dans le code il intervient lorsque des routines sont appelées des myriades de fois sans planter que que tout à coup... plouf.

    Pour des problèmes un peu Sioux de réarrangement mémoire avec les optimisations faites par le compilateur... ça peut aider.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 488
    Points : 593
    Points
    593
    Par défaut
    Bonjour,

    Plutôt que d'utiliser des print, autant passer par un débogueur (par ex. gdb), et bien vérifier l'état et le contenu des variables au plus près du plantage.

    D'expérience, lorsque dans un code séquentiel il y a des plantages pseudo-erratiques du style de celui décrit ici, c'est majoritairement parce qu'il y a quelque part en amont (et pas forcément juste quelques lignes en amont) un mauvais appel (au sens: agruments fourni à l'appel d'une routine différents de ceux qu'elle attends). Malheureusement, (dans la limite de mes connaissances) il n'y a que le compilo xlf qui propose une option pour automatiquement vérifier cela. Il y a aussi gfortran qui peut faire cette vérification à la compilation, mais seulement pour des routines inclues dans un même fichier source.

  7. #7
    Membre averti
    Homme Profil pro
    [SciComp]
    Inscrit en
    Août 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : [SciComp]

    Informations forums :
    Inscription : Août 2013
    Messages : 134
    Points : 323
    Points
    323
    Par défaut
    Oui pour gdb, mais d'une part les options de debug éteignent en général les optimisations (risque de ne plus voir le pb), et d'autre part, je ne sais pas si passer un code sans flags de debug puisse dire qque chose d'intelligible. Mais après, si on n'essaie pas, c'est clair qu'on ne sait pas...

Discussions similaires

  1. Réponses: 3
    Dernier message: 29/05/2007, 17h18
  2. Réponses: 1
    Dernier message: 02/08/2006, 17h37
  3. Violation d'acces lors d'une destruction d'un composant
    Par Rayek dans le forum Composants VCL
    Réponses: 15
    Dernier message: 23/11/2005, 11h37
  4. [VCL] TImage.Create(AOwner) renvoie une Violation d'accès
    Par prgasp77 dans le forum Composants VCL
    Réponses: 10
    Dernier message: 23/01/2005, 17h14

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