Turing : options de débogage des compilateurs IBM

Dans une phase de débogage, les options suivantes peuvent être d'une aide précieuse  :

  • -g (option activée par défaut à l'IDRIS) génère une table des symboles (numéro de ligne, variables…) qui pourra être exploitée par un débogueur par la suite. Elle permet aussi de générer les numéros d'instructions dans les tracebacks. Attention : exception parmi les compilateurs, cette option n'inhibe pas l'optimisation mais au contraire conserve le niveau d'optimisation demandé. Aussi pensez à tester la persistance de votre bogue sans optimisation (ou avec un niveau d'optimisation inférieur).
  • -qfullpath inscrit les chemins d'accès aux fichiers source et d'include dans les fichiers objets (doit être combinée avec -g). Elle permet au débogueur de trouver automatiquement les fichiers sources.
  • -O0 -qnohot -qnosmp -qstrict permet d'inhiber toute optimisation.
  • -qoptdebug permet de conserver le niveau d'optimisation. Pour chaque fichier source, un fichier (ayant l'extension .optdbg) est généré. Il contient un pseudocode optimisé pouvant être lu par un débogueur.
  • -qinitauto=motif initialise au préalable la mémoire correspondant aux variables temporaires à l'aide du motif précisé (ou à zéro si -qinitauto seul) :
    • motif=FFFFFFFF pour mettre les flottants simple et double précision à NaNq.
  • -C (seulement en Fortran) génère un signal SIGTRAP lorsqu'un tableau est adressé en dehors de ses bornes (bound checking). Pour intercepter ce signal l'option -qsigtrap décrite ci-dessous est nécessaire.
  • -qcheck=bounds (seulement en C/C++) vérifie si l'on n'adresse pas un tableau en dehors de ses bornes (bounds checking).
  • -qcheck=nullptr (seulement en C/C++) vérifie la validité des adresses contenues dans les variables de type pointeur.
  • -qcheck=divzero (seulement en C/C++) permet de détecter les divisions entières par zéro.
  • -qcheck=all (seulement en C/C++) regroupe les 3 options ci-dessus.
  • -qflttrap=overflow:underflow:nanq:zerodivide:qpxstore:enable permet de détecter les exceptions (overflow, underflow, NaNq, division par zéro et NaNs sur l'unité vectorielle QPX). En Fortran, il faut obligatoirement spécifier -qsigtrap pour intercepter les exceptions.
  • -qsigtrap (seulement en Fortran) intercepte le signal SIGTRAP émis suite à une exception ou à un débordement de tableau et interrompt l'exécution avec impression d'une traceback (voir aussi l'option -g).
  • -qsave (seulement en Fortran) force le mode d'exécution statique. Sur Turing, par défaut, nous sommes en mode stack (recommandé mais révélateur d'erreurs de programmation cachées par le mode statique !) ; les variables locales sont alors stockées temporairement dans la zone mémoire dite stack. Si cette option provoque un retour à la normale, il faut sûrement incriminer des variables locales non initialisées ou non sauvegardées à tort (cf. attribut SAVE), comme les compteurs incrémentés à chaque appel de procédure.
  • -qkeepparm pour obliger le compilateur à conserver dans le stack les valeurs des arguments d'appel (certaines optimisations peuvent changer cela). Celles-ci seront ainsi récupérables dans n'importe quel débogueur.
  • -qdbxextra (seulement en C/C++) inclut toutes les définitions de type enum, struct, union dans les fichiers objet pour qu'elles puissent être exploitées par un débogueur (doit être combinée avec -g).

Il existe aussi une option -qlanglvl pour vérifier la conformité du source à une norme Fortran ou C/C++. Par exemple -qlanglvl=95std pour la norme Fortran 95 et -qlanglvl=stdc99 pour la norme C99.

Exemple de gestion de débordement de tableaux :

$ mpixlf95_r -g -C -qsigtrap debordement.f90
$ runjob --np 1024 --ranks-per-node 16 : ./my_exe my_arg1 my_arg2
  
  Signal received: SIGTRAP - Trace trap
    Fortran language trap: subscript out of bounds
  
  Traceback:
    Offset 0x00000090 in procedure debord, near line 6 in file debordement.f90
    --- End of call chain ---

Exemple utilisant toutes les options décrites en Fortran :

$ mpixlf95_r -g -qsigtrap -qoptdebug -qfullpath -C -qinitauto=7FBFFFFF 
                       -qflttrap=overflow:underflow:zerodivide:invalid:qpxstore:enable 
                       -qsigtrap -qkeepparm -qlanglvl=95std test.f90

En C et en C++ :

$ mpixlc_r -g -qoptdebug -qcheck=all -qinitauto=7FBFFFFF 
              -qflttrap=overflow:underflow:zerodivide:invalid:qpxstore:enable 
              -qfloat=nans:spnans -qkeepparm -qdbxextra -qfullpath source.c
  
$ mpixlcxx_r -g -qqoptdebug -qcheck=all -qinitauto=7FBFFFFF 
                -qflttrap=overflow:underflow:zerodivide:invalid:qpxstore:enable 
                -qfloat=nans:spnans -qkeepparm -qdbxextra -qfullpath source.C