(dbx) whereDans ce cas, le programme test s'est planté à la ligne 44 du fichier source test.c en cours d'exécution de la routine foo2, appelée à la ligne 38 de la routine foo, elle-même appelée à la ligne 55 de la function main. Par la suite on utilisera d'autres commandes de dbx pour obtenir les valeurs de variables et connaitre les raisons du plantage.
> 0 foo2(i = 5) ["/usr/tmp/test.c":44, 0x1000109c]
1 foo(i = 4) ["/usr/tmp/test.c":38, 0x1000105c]
2 main(argc = 1, argv = 0xffffffad78) ["/usr/tmp/test.c":55, 0x10001104]
3 __start() ["/shamu/crt1text.s":137, 0x10000ee4]
_____________________________________
dbx [options] [object_file [corefile] ]
Options de dbx
Les options suivantes peuvent être transmises lors de l'appel
à
dbx. Elles sont décrites dans la suite de cette
section :
Option | Description |
-c file | sélectionne un autre fichier de commande que le fichier .dbxinit lors du lancement de dbx |
-d | fournit des informations de lancement au shell lorsqu'un programme est lancé avec la commande run |
-e num | choisit une taille plus grande (num donnée en octets) pour la pile d'évaluation (la valeur par défaut est 20000 octets). Il faut relancer dbx avec cette option si le message d'erreur too large to evaluate apparait |
-i | utilise le mode interactif. Cette option permet d'entrer des valeurs comme un fichier d'entrée. Le caractère # n'est alors plus considéré comme un commentaire |
-I dir | spécifie le répertoire dans lequel dbx doit chercher les fichiers source. Mettre une option -I par répertoire si plusieurs répertoires source doivent être spécifiés |
-k | permet le déboguage du kernel |
-N | initialise à 1 la variable $nonstop : l'attachement à un processus ne l'arrête pas |
-P name | débogue le processus de nom name |
-p pid | débogue le processus spécifié par son pid |
-R | autorise les points d'arrêt (breakpoints) dans rld |
-r program [args] | exécute le programme appelé program lors du lancement de dbx avec les arguments args spécifiés. Le fichier .dbxinit est lu et exécuté après l'object_file. On ne peut pas spécifier de fichier core avec l'option -r |
Spécifier un fichier objet et un fichier core
L'object_file est le nom de l'exécutable que l'on veut
déboguer. Il comprend le code que dbx exécute et la
table des symboles qui contient les noms des variables et procédures
et la correspondance entre le code objet et le code source dans les fichiers
source.
Un corefile (fichier core) est produit (core dumped)
lorsque l'exécution ne se termine pas normalement. A l'aide du nom
du fichier core, dbx permet de connaitre l'état mémoire
du programme et l'endroit où l'erreur est survenue. On peut alors
connaitre la pile d'appels des fonctions et les valeurs de variables pour
déterminer la raison du plantage sans pour autant poursuivre l'exécution
au-delà du crash. Si l'on ne spécifie pas de corefile,
dbx
cherche dans le répertoire courant un fichier appelé
core.
Si un fichier core est présent ou s'il semble en être
un, dbx se comportera comme si ce fichier
core lui avait
été spécifié.
On peut spécifier l'object_file et le corefile
soit comme arguments lors du lancement de dbx soit u travers de
commandes lorsque l'on est dans dbx, en mode prompt.
Le prompt de dbx
Une fois dbx lancé, celui-ci affiche l'invite suivante
:
(dbx)On peut modifier cet affichage en changeant la valeur de la variable $prompt.
Spécifier des fichiers avec des commandes dbx
Les commandes de dbx, givenfile et corefile, permettent
de préciser respectivement le fichier objet et le fichier core en
cours d'exécution de dbx.
givenfile [file] | |
si un nom de fichier est donné, dbx tue le processus en cours et charge l'exécutable de nom file et les informations de déboguage y figurant. Dans le cas contraire, dbx affiche le nom du programme en cours de déboguage sans l'altérer | |
corefile [file] | |
si un nom de fichier est donné, dbx utilise les informations présentes dans ce fichier core. Dans le cas contraire, dbx affiche le nom du fichier core en cours d'utilisation sans l'altérer |
run [run-args] | |
la commande run démarre l'exécution du programme et lui transmet les arguments éventuellement fournis. La commande utilise le shell courant (valeur dans la variable d'environnement $SHELL) pour exécuter la commande run. La même syntaxe que dans un shell classique est supportée, i.e. les substitutions par ? ou * dans les noms de fichiers, les redirections des entrées et sorties standards |
Une commande run doit apparaitre seule sur une ligne, ne peut
être suivie par une autre commande dbx (séparée
par un point-virgule) et doit se finir par un retour chariot.
rerun [run-args] | |
la commande rerun sans argument répète la dernière commande run si elle existe. Autrement elle est équivalente à la commande run sans argument |
Exemple :
Le programme sort reçoit un fichier en entrée
et produit un fichier trié en sortie; on peut spécifier les
fichiers d'entrée et de sortie par redirection ou par arguments
en ligne de commande.
En ligne de commande, on a ainsi au choix :
% sort -i input -o outputSi l'on débogue le programme sort, les commandes équivalentes de dbx sont :
% sort < input2 > output2
(dbx) run -i input -o outputSi l'on exécute ces commandes dans l'ordre proposé, on peut répéter la dernière commande run en utilisant la commande rerun :
(dbx) run < input2 > output2
(dbx) rerun
help | affiche les commandes supportées par dbx |
help keyword | affiche des informations relatives à l'argument keyword, tel que alias, help, most_used, quit, playback, record, etc ... |
help all | ffiche la totalité du fichier d'aide de dbx |
En tapant help all, dbx affiche le contenu du fichier d'aide en utilisant la commande dont le nom figure dans la variable $pager de dbx. Ce fichier d'aide est assez gros et peut être difficile à lire même avec la commande more. On peut ainsi spécifier $pager pour employer pour un éditeur de texte particulier. Par exemple pour vi, il faut mettre la ligne suivante dans le fichier .dbxinit :
set $pager = "vi"Il suffit de quitter l'éditeur pour revenir dans dbx.
(dbx) when at "myfile.c":37 {print a ; where ; print b}
(dbx) alias foll "print *(struct list *) $p ; \
set $p = (int)((struct list *) ($p))->next"
sh | appel à un shell |
sh command | exécute la commande en argument dans le shell crée |
La commande suivante permet d'afficher la fin du fichier datafile :
(dbx) sh tail datafile
(dbx) quit
_____________________________________
Par défaut, la liste des répertoires connus de dbx ne contient que le répertoire courant (répertoire de lancement de dbx) et le répertoire du fichier objet (s'il est différent du précédent). A chaque recherche, dbx parcourt cette liste dans l'ordre dans lequel les répertoires ont été insérés.
Spécifier des répertoires source par argument
On peut spécifier des répertoires supplémentaires
lors du lancement de dbx avec l'option -I, une occurence
par répertoire à ajouter.
Spécifier des répertoires source avec des commandes
dbx
Les commandes dir et use permettent de spécifier
des répertoire source alors que dbx est lancé.
dir [dir ...] | |
si on fournit un ou plusieurs répertoires, dbx les ajoute à la fin de la liste des répertoires source. Sans argument, dbx affiche la liste de répertoires | |
use [dir ...] | |
si on fournit un ou plusieurs répertoires, dbx remplace la liste des répertoires source avec ces répertoires. Sans argument, dbx affiche la liste des répertoires |
Ces deux commandes acceptent les chemins relatifs et absolus mais ne reconnaissent pas le caractère tilde (~) ou les variables d'environnement (e.g. $HOME/src).
Modification de path
Les informations de déboguage pour les programmes compilés
avec l'option -g contiennent le chemin complet vers les fichiers
sources. Par défaut, dbx utilise ces chemins pour chercher
les fichiers sources. Cependant, si on débogue un programme compilé
à un autre endroit et que l'on souhaite spécifier un nouveau
chemin vers les fichiers source, on peut faire une modification des chemins.
Ainsi on peut remplacer un élément d'un chemin par un autre
élément afin que dbx trouve les fichiers.
dir elt1:elt2 | |
la commande dir (ou use) permet de modifier des répertoires et de spécifier un nouveau chemin vers les sources. dbx substitue elt2 à elt1 |
Par exemple le code source d'un programme compilé est /x/y/z/kk.c et le source a été déplacé dans /x/y/zzz/kk/kk.c. La commande dir (ou use) permet de modifier le chemin :
(dbx) dir /z/:/zzz/kk/Le nouveau chemin est alors /x/y/zzz/kk/kk.c .
(dbx) file procedure.cGénéralement le programme que l'on débogue a son code source dans plusieurs fichiers. dbx sélectionne automatiquement le bon fichier et la section du code examiné. Ainsi, de nombreuses commandes dbx re-initialisent le fichier source courant, de manière implicite.
(dbx) fileOn peut aussi changer le fichier source courant par :
procedure.c
(dbx) func procedure
list | affiche $listwindow lignes de source à partir de la ligne courante du code source (ou à partir de la ligne du programcounter - pc ) |
list exp | affiche $listwindow lignes de source à partir de la ligne donnée par l'expression exp |
list exp1:exp2 | affiche exp2 lignes à partir de la ligne exp1 |
list exp1,exp2 | affiche le code source entre les lignes exp1 et exp2 incluses |
list func | affiche $listwindow lignes à partir de la procedure func |
list func,exp | affiche le code source entre les procédures func et exp incluses |
list func:exp | affiche exp lignes à partir de func |
Le symbole > à gauche d'une ligne indique la ligne courante.
Le symbole * indique la position courante du pc.
listinlines | affiche la liste des routines inlinées avec les adresses de début et de fin |
listinlines func | affiche toutes les instances inlinées de la routine func avec leurs adresses de début et de fin |
/[reg_exp] | recherche en avant de l'expression régulière rep_exp dans le fichier source courant à partir de la ligne courante. Si dbx atteint la fin du fichier sans trouver l'expression, il poursuit à partir du début de celui-ci. dbx affiche la ligne source correspondant à la première occurrence trouvée. Sans argument, dbx fait une recherche en avant de la dernière expression fournie |
?[rep_exp] | recherche en arrière de l'expression régulière rep_exp dans le fichier source courant à partir de la ligne courante. Si dbx atteint le début du fichier sans trouver l'expression, il poursuit à partir de la fin de celui-ci. dbx affiche la ligne source correspondant à la première occurrence trouvée. Sans argument, dbx fait une recherche en arrière de la dernière expression fournie |
Recherche en avant de la prochaine occurrence de la chaine "errno" :
(dbx) /errnoRecherche en arrière de la précédente occurence de "img" ou "Img" :
(dbx) ?[iI]mg
edit | la commande edit appelle un éditeur de texte (vi par défaut) pour le fichier source courant. Si la variable $editor de dbx est renseignée avec un nom d'éditeur de texte, celui-ci est alors employé. Si elle n'est pas renseignée, dbx vérifie la variable d'environnement $EDITOR et, si elle est renseignée, appelle cet éditeur de texte. Quitter l'éditeur renvoie dans dbx |
edit file | appelle l'éditeur de texte avec le fichier file |
edit procedure | appelle l'éditeur de texte pour le fichier qui contient le code source de la routine spécifiée. Toutefois, on ne peut visualiser que des routines que dbx peut trouver à partir d'un nom simple : routines dans la pile activée et procédures globales uniquement |
On peut aussi utiliser la commande edit pour concevoir des scripts dbx.
_____________________________________
dbx possède une importante liste de variables prédéfinies
pour controler de nombreuses commandes. Une variable dbx n'a pas
de type fixe, on peut assigner à une variable une valeur de n'importe
quel type même si elle avait auparavant une valeur d'un autre type.
Cependant, une variable prédéfinie par dbx possède
un type prédéfini fixe.
Presque tous les mots peuvent être utilisés comme nom
de variables dbx. Une bonne règle est de mettre un caractère
dollar ($) comme premier caractère de toutes les variables dbx
pour éviter les conflits avec les variables du programme. Toutes
les variables prédéfinies par dbx commencent par un
caractère $.
Les paragraphes qui suivent ne s'appliquent que sur les variables dbx et pas les variables du programme débogué.
Initialisation de variables dbx
La commande set permet d'affecter une valeur à une variable
dbx,
la définissant si elle n'existait pas.
set var = exp | définit (ou redéfinit) la variable dbx spécifiée var et lui affecte la valeur fournie par l'expression exp |
On peut connaitre la valeur d'une variable dbx à l'aide de la commande print, par exemple :
(dbx) set $k = 1Dans l'exemple précédent, dbx réalise une division entière puisque $k et la constante 11 sont de type entier. Si on assigne une valeur de type réelle à $k et que l'on re-évalue l'expression à nouveau, dbx réalise une division réelle :
(dbx) print $k
1
(dbx) set $k = $k + 23
(dbx) print $k
24
(dbx) print $k / 11
2
(dbx) set $k = 24.0Il est recommandé de faire commencer toute variable dbx par un caractère $ pour éviter toute confusion avec une variable du programme. En effet une variable dbx sans le caractère $ masque la variable du programme qui a le même nom. Le seul moyen de voir la variable du programme est de détruire la variable dbx au moyen de la commande unset.
(dbx) print $k
24.0
(dbx) print $k / 11
2.1818181818181817
Listage de variables dbx
La commande set sans argument entraine l'affichage de toutes
les variables dbx actuellement définies, les variables prédéfinies
incluses. Exemple de résultat partiel :
(dbx) set
$addrfmt "0x%x"
$addrfmt64 "0x%llx"
$assignverify 1
$casesense 2
$ctypenames 1
$curevent 3
$curline 44
$curpc 268439708
...
$stacktracelimit 1024
$stdc 0
$stepintoall 0
$tagfile "tags"
destruction de variables dbx
La commande unset permet de détruire une variable dbx
(dbx) unset $k
Examen de l'historique
dbx stocke toutes les commandes entrées dans une liste.
La valeur de la variable $lines de dbx détermine le
nombre de commandes stockées dans cette liste. La valeur par défaut
est 100. La commande history permet d'afficher cette liste. Par
exemple, après la mise en place d'un point d'arrêt (breakpoint),
le lancement du programme et l'examen de quelques variables, l'historique
des commandes ressemble à :
(dbx) history
1 set $prompt = "(dbx)"
2 set $page = 0
3 set $pimode = 1
4 stop in main
5 history
Répétition de commande
On peut exécuter n'importe quelle commande contenue dans l'historique,
il suffit de la faire précéder d'un point d'exclamation (!)
:
!! | répète la dernière commande. Si la valeur de la variable $repeatmode de dbx est égale à 1, un retour chariot sur une ligne vide est alors équivalent à !!. Par défaut, $repeatmode vaut 0 |
!string | répète la plus récente commande qui commence par la chaine string |
!integer | répète la commande qui est associée au numéro integer dans l'historique |
!-integer | répète la commande présente integer places avant la commande courante; ainsi !-1 exécute la dernière commande, !-2 l'avant-dernière |
On peut utiliser la commande !! pour faire du pas à pas dans le programme; ainsi l'exemple suivant permet d'avancer dans l'exécution du programme par pas de 5 lignes :
(dbx) next 5Un autre usage pratique est le rappel d'une commande par le début de son nom. Cela s'applique jusqu'à ce qu'une commande plus récente avec le même début de nom soit entrée.
...
(dbx) !!
(!! = next 5)
L'éditeur d'historique
L'éditeur d'historique, hed, permet d'utiliser l'éditeur
de texte référencé sur n'importe quelle commande présente
dans l'historique de dbx. Lors de l'appel à hed, dbx
copie une partie ou la totalité de l'historique dans un fichier
temporaire que l'on peut éditer. En quittant l'éditeur, les
commandes laissées dans le fichier temporaire sont alors automatiquement
exécutées par dbx.
Si la variable $editor de dbx est renseignée avec
un nom d'éditeur de texte, celui-ci est alors employé. Si
elle n'est pas renseignée, dbx vérifie la variable
d'environnement $EDITOR et, si elle est renseignée, appelle cet
éditeur de texte, autrement vi est pris par défaut.
La syntaxe pour la commande hed est :
hed | édite uniquement la dernière ligne de l'historique (i.e. la dernière commande exécutée) |
hed num1 | édite la ligne num1 de l'historique |
hed num1,num2 | édite les lignes de l'historique comprises entre la ligne num1 et la ligne num2 incluses |
hed all | édite la totalité de l'historique |
Par défaut, dbx n'affiche pas les commandes exécutées
suite à l'utilisation de hed (la variable prédéfinie
$pimode vaut 0). Si $pimode vaut 1, dbx affiche les commandes
lorsqu'il les exécute.
Listage des aliases
On peut afficher l'ensemble des aliases avec la commande alias
:
alias | affiche tous les aliases existants |
alias name | affiche la définition de l'alias name |
Création d'aliase de commandes
On définit de nouveaux aliases avec la commande alias
:
alias name command | |
définit name comme un alias de command | |
alias name "string" | |
définit name comme un alias de string. Avec cette forme de la commande alias, on peut mettre des arguments de commandes | |
alias name (arg1 [,...argN]) | |
définit name comme un alias de string. arg1 à argN sont des arguments de l'alias, apparaissant dans la définition string. Lorsque l'on utilise l'alias, on doit fournir des valeurs pour ces arguments, que dbx substitue alors à string |
La forme la plus simple d'un alias est la redéfinition d'une commande dbx avec un nom plus court, c'est le cas pour un bon nombre d'aliases prédéfinis :
(dbx) alias gf givenfileDes définitions plus complexes d'aliases nécessitent plus que le nom de la commande. Dans ces cas, il faut alors inclure toute la définition de l'alias dans des double quotes ("). Il faut utiliser le caractère antislash (\) pour inclure le caractère double quote comme partie de la définition de l'alias. Par exemple, on peut définir un alias court pour afficher la valeur d'une variable que l'on examine fréquemment :
(dbx) alias gf
"givenfile"
(dbx) gf
No current givenfile
(dbx) alias pa "print \"a = \", a"On peut aussi définir un alias à qui on doit transmettre des arguments. Lorsque l'on utilise l'alias il faut inclure des valeurs pour les arguments. dbx substitue alors les valeurs fournies aux arguments de la définition de l'alias :
(dbx) alias pa
"print "a = ", a"
(dbx) pa
a = 3
(dbx) alias p(arg1, arg2, arg3, arg4) "print '|arg1|arg2|arg3|arg4|'"L'alias p reçoit 4 arguments et les affiche avec des barres verticales (|) de part et d'autre :
(dbx) alias p
(arg1, arg2, arg3, arg4) "print '|arg1|arg2|arg3|arg4|'"
(dbx) p(1,2,3,4)Dans cet exemple, dbx a préservé les espaces insérés lors de l'appel à l'alias.
(dbx) p( first, second, 3rd,4)
| first| second| 3rd|4|
(dbx) p(a,,b,c)
|a||b|c|
(dbx) p(,first missing, preceding space, )
||first missing| preceding space| |
Destruction d'aliases de commandes
La commande unalias détruit l'alias fourni en argument.
On peut détruire des aliases prédéfinis mais ils sont
restaurés lors de la prochaine session dbx.
Enregistrement des commandes entrées
La commande record input démarre la session d'enregistrement
des commandes entrées. Une fois cela fait, toutes les commandes
données à dbx sont copiées dans le fichier
spécifié. Si ce fichier existe déjà, dbx
ajoute les informations à la fin de celui-ci. On peut avoir simultanément
plusieurs sessions d'enregistrement.
A chaque session d'enregistrement est assigné un numéro
lorsque l'on l'initialise. Ce numéro est utile pour arrêter
l'enregistrement avec la commande unrecord.
Ensuite, la commande playback input appliquée au fichier
de commandes crée permet d'exécuter à nouveau toutes
les commandes s'y trouvant.
(dbx) record input scriptSi aucun nom de fichier n'est spécifié, dbx crée un fichier temporaire dans le répertoire /tmp. Le nom de ce fichier est stocké dans la variable $defaultin que l'on peut connaitre en faisant :
[4] record input script (0 lines)
(dbx) print $defaultinIl est préférable de spécifier un nom de fichier car les fichiers temporaires de dbx sont détruits en fin de session de déboguage.
Fin d'une session d'enregistrement
Pour terminer une session d'enregistrement (d'input ou d'output),
il faut utiliser la commande unrecord :
unrecord session1 [, session2 ...] | |
termine les sessions spécifiées et ferme leur fichier respectif | |
unrecord all | termine toutes les sessions et ferme tous les fichiers |
Par exemple, la commande suivante arrête la session 4 :
(dbx) unrecord 4la commande suivante arrête toutes les sessions :
(dbx) unrecord allLa commande status ne fournit pas d'information sur les sessions d'enregistrement.
Exécution d'enregistrements des commandes entrées
On utilise la commande playback input pour exécuter les
commandes enregistrées avec la commande record input. Deux
aliases existent pour la commande playback input : pi et
source.
Si on ne spécifie pas de nom de fichier, dbx utilise le fichier
temporaire courant crée par la commande record input. Si
la variable $pimode de dbx est non nulle alors les commandes
exécutées sont affichées. La valeur par défaut
est zéro.
Enregistrement des affichages
On utilise la commande record output pour démarrer une
session d'enregistrement des affichages dans dbx. Durant une telle
session, dbx copie sa sortie écran vers un fichier. Si le
fichier spécifié existe déjà, dbx ajoute
les informations à la fin de celui-ci. On peut démarrer autant
de sessions d'enregistrement que nécessaire.
Par défaut, les commandes entrées ne sont pas copiées
vers le fichier de sortie; si la variable $rimode est non nulle
alors dbx fait aussi une copie des commandes entrées.
A chaque session d'enregistrement est assigné un numéro
lorsque l'on l'initialise. Ce numéro est utile pour arrêter
l'enregistrement avec la commande unrecord.
La commande record output est très utile lorsque la sortie
écran est trop importante pour tenir dans un seul écran.
Dans dbx, on utilise la commande playback output pour visualiser
les informations enregistrées. Hors dbx, cela peut se faire
avec un éditeur de text comme vi.
Pour enregistrer les sorties dans un fichier appelé gaffa :
(dbx) record output gaffaPour enregistrer les commandes et les sorties :
(dbx) set $rimode = 1Si aucun nom de fichier n'est spécifié, dbx crée un fichier temporaire dans le répertoire /tmp qui sera détruit à la fin de la session dbx. Il est donc préférable de donner un nom à la commande record output. Le nom du fichier temporaire est stocké dans la variable $defaultout que l'on peut connaitre avec :
(dbx) record output gaffa
(dbx) print $defaultout
Exécution d'enregistrements des affichages
La commande playback output affiche les sorties enregistrées
avec la commande record output. Elle fonctionne de manière
analogue à la commande UNIX cat. Si on ne spécifie
pas de nom de fichier, dbx utilise le fichier temporaire courant
crée par la commande record output.
(dbx) playback output script
Liste des sessions d'enregistrements actives
La commande record affiche toutes les sessions record input
et record output actives :
(dbx) record
[4] record input /usr/demo/script (12 lines)
[5] record output /tmp/dbxoXa17992 (5 lines)
_____________________________________
Opérateurs
En général, dbx reconnait la plupart des opérateurs
du C, du Fortran 77 et du Pascal. dbx possède
aussi ses propres opérateurs. Les opérateurs suivent les
règles de priorité du C.
Opérateur | Description |
not | opérateur unaire renvoyant faux si l'opérande est vrai |
or | opérateur logique binaire renvoyant vrai si un des deux opérandes est vrai ou non nul |
xor | opérateur binaire renvoyant le OR exclusif de ses opérandes |
/ | opérateur binaire de division |
div | opérateur binaire divisant ses opérandes après leur conversion en entier |
mod | opérateur binaire renvoyant op1 modulo op2 |
#exp | opérateur unaire retournant l'adresse de la ligne source spécifiée par exp |
"file"#exp | opérateur unaire retournant l'adresse de la ligne source spécifiée par exp dans le fichier file |
proc#exp | opérateur unaire renvoyant l'adresse de la ligne source spécifiée par exp dans le fichier contenant la procédure proc |
L'opérateur # prend le numéro de ligne spécifié
par l'expression qui le suit et renvoie l'adresse de cette ligne de code
source. Si l'opérateur est précédé d'un nom
de fichier entre double quote ("), il renvoie l'adresse de la ligne
de code source du fichier spécifié. Si l'opérateur
#
est précédé par le nom d'une procédure alors
dbx
identifie le fichier source qui la contient et renvoie l'adresse de la
ligne de code source dans ce fichier.
Comme le caractère # indique le début d'une ligne
de commentaires dans les scripts dbx, il faut en mettre deux consécutifs
pour inclure l'opérateur # dans un tel script.
Opérateurs du langage C reconnus par dbx :
Type | Opérateurs |
Unaire | ! & + - * sizeof() |
Binaire | % << >> == <= >= != <> & && | || + - * / [] -> . |
Le OR exclusif du langage C, "^", n'est pas supporté par dbx; il faut employer l'opérateur xor de dbx.
Opérateurs du Pascal reconnus par dbx :
Type | Opérateurs |
Unaire | not ^ + - |
Binaire | mod = <= >= <> < > and or + - * / div [] |
Opérateurs du Fortran 77 et Fortran 90 reconnus
par dbx :
Type | Opérateurs |
Unaire | + - |
Binaire | + - * / % |
Les indices de tableaux en Fortran 77 ou Fortran 90 peuvent être mis dans des crochets, [ ], ou des parenthèses, ( ), et l'opérateur de sélection de champ, %, du Fortran 90 est reconnu. Par contre dbx ne reconnait pas les opérateurs logiques comme .or. ou .TRUE. .
Constantes
On peut utiliser des contantes numériques ou des chaines de
caractères mais les expressions ne peuvent pas contenir des constantes
définies par le #define du préprocesseur
du langage C.
On peut utiliser n'importe quelle constante valide entière ou flottante. Par défaut, dbx suppose que les constantes numériques sont décimales. On peut mettre en octal la base de représentation par défaut en affectant une valeur non nulle à la variable $octin. De même pour l'hexadécimal avec la constante $hexin. Si les deux sont définies alors $hexin a préséance.Constantes numériques
La plupart des expressions de dbx ne peuvent contenir des constantes chaines de caractères. Les commandes print et printf sont deux commandes de dbx qui acceptent des chaines de caractères comme arguments. On peut utiliser la commande set pour affecter une valeur chaine de caractères à une variable dbx.Constantes chaines de caractères
\\ \n \r \f \b \t \' \" \aDélimiter une chaine de caractères avec les simples quotes arrières (`) indique que l'ensemble de la chaine de caractères est le nom d'un élément du programme.
print [exp1 [, exp2, ...] ] | |
affiche les valeurs des expressions spécifiées | |
printd [exp1 [, exp2, ...] ] | |
affiche les valeurs des expressions spécifiées en décimal (pd est un alias pour printd) | |
printo [exp1 [, exp2, ...] ] | |
affiche les valeurs des expressions spécifiées en octal (po est un alias pour printo) | |
printx [exp1 [, exp2, ...] ] | |
affiche les valeurs des expressions spécifiées en hexadécimal (px est un alias de printx) |
Si la donnée affichée est de type pointer, dbx
utilise le format spécifié dans la variable $addrfmt
ou $addrfmt64 (uniquement pour les processus 64 bits).
printf string [, exp1 [, exp2, ...] ] | |
affiche les valeurs des expressions spécifiées dans le format spécifié par string |
(dbx) print (int) 'b'La syntaxe est la même que pour le transtypage en langage C.
98
(dbx) print (char) 67
'C'
Le nom complètement déterminé d'un élément
de programme permet de référencer des variables de même
nom au sein d'une procédure mais aussi des éléments
de programme à l'extérieur de la pile d'appels active.
dbx complète le nom avec le fichier, la procédure,
un bloc ou une structure.
mrx.main.iDans cet exemple i est le nom de la variable, main est une procédure dans laquelle elle apparait et mrx est le fichier source (sans l'extension) dans lequel la procédure est définie.
dbx fournit un nom spécial, __aout, pour la base de l'exécutable. Ainsi on peut utiliser __aout.main pour faire référence à la function C appelée main de l'exécutable. On peut aussi utiliser le nom de l'exécutable pour référencer une function. Pour les variables présentes dans les librairies dynamiques (objets DSO), la règle est la même : libc.strcpy fait référence à la function strcpy de la librairie libc.so.1 .
Enfin, on peut avoir des fichiers portant le même nom dans différents
répertoires. dbx lève l'ambiguité en préfixant
le nom complet par une étiquette numérique. Ainsi deux fichiers
myfile.c
seront référencés de manière globale dans le
programme par __aout._$1_myfile et __aout._$1_myfile. Les
commandes which et whereis permettent de connaitre cette
étiquette.
Portée d'une variable
On peut accéder à la valeur d'une variable uniquement
lorsque l'on se trouve dans sa portée (zone de visibilité),
i.e. si le bloc ou la procédure auquel elle est associée
est actif. Dans la pratique, cela signifie que les variables locales d'une
procédure ne sont visibles qu'à l'intérieur de cette
routine et à partir des procédures appelées par celle-ci.
Affichage de la valeur d'une variable
On peut afficher la valeur d'une variable à l'aide des commandes
printd,
printf,
printo
et printx.
Pour afficher un tableau dans son intégralité, il suffit
de donner son nom comme argument de la commande print :
(dbx) print arrayPour afficher un seul élément ...
(dbx) print array[5]Modification de la valeur d'une variable
assign variable = expressionassigne la valeur de expression à la variable du programme variablePar exemple
(dbx) assign x = 27Si dbx renvoie une erreur, types incompatibles, lors de l'assignation d'une valeur à un pointer, le transtypage permet de réalisation cette affectation.
27
(dbx) assign y = 37.5
37.5
Conflits entre nom de variables et mots-clés
Il est préférable de ne pas appeler des variables de
programme avec le nom de mots-clés dbx. Si c'est le cas,
la tentative d'utilisation de la variable dans une commande dbx
entraine une syntax error. On peut forcer dbx à la
traiter comme une variable en l'entourant de parenthèses :
(dbx) print inall, and, at, div, if, in, mod, not, or, pgrp, pid, sizeof, to, xor sont des nots-clés.
print in
^ syntax error
(dbx) print (in)
34
Distinction majuscules/minuscules
La sensibilité de dbx aux majuscules/minuscules dépend
de la valeur de la variable $casesense :
2 | le langage dans lequel la variable est définie est pris en compte (le langage C/C++ est sensible aux majuscules/minuscules ce qui n'est pas le cas de Pascal, Fortran) |
1 | la distiction est toujours faite |
0 | la distinction n'est jamais faite |
Il faut noter que les noms de fichiers sont toujours sensibles aux majuscules/minuscules
puisqu'il s'agit de noms de fichiers UNIX.
printenv | affiche la liste des variables d'environnement affectant le programme débogué |
setenv | idem que printenv |
setenv VAR | définit la variable VAR |
setenv VAR value | |
affecte la valeur value à la variable VAR, value n'étant pas une variable dbx | |
setenv VAR $var | |
affecte la valeur $var à la variable VAR, $var étant une variable dbx | |
setenv VAR "charstring" | |
affecte la chaine charstring à la variable VAR | |
unsetenv VAR | retire la variable d'environnement VAR |
La modification des variables d'environnement PAGER et EDITOR,
entraine un comportement non défini de dbx.
(dbx) whatis iPour une procédure, dbx renvoie le type retourné ainsi que la déclaration des différents arguments
int i;
(dbx) whatis foo
int foo(i)
int i;
(dbx) whatis main
int main (argc, argv)
int argc;
char** argv;
Affichage de traces dans la stack
La commande where affiche les traces de la stack, i.e.
les niveaux d'activation courants de la stack.
Si on compile un programme sans l'option -g ou avec l'option
-g0,
peu d'informations de déboguage sont présentes dans le fichier
objet et dbx connait juste le nombre d'arguments des routines au
lieu de la séquence d'appel complète des routines.
Déplacement dans la stack
Les commandes up et down permettent de se déplacer
entre les niveaux d'activation de la stack dont la syntaxe est la
suivante :
up [num] | remonte dans la stack du nombre de niveau spécifié, le défaut est un niveau |
down [num] | descend dans la stack de nombre de niveau spécifié, le défaut est un niveau |
Le fait de se déplacer dans la stack entraine une modification de la visibilité. En effet à moins de qualifier complètement une variable, dbx suppose toujours que les variables référencées sont locales au niveau d'activation courant.
Déplacement vers une routine spécifiée
La commande func permet de se déplacer au sein de la
stack
active. On peut spécifier le nouveau niveau d'activation avec soit
le nom de la routine soit le numéro du niveau d'activation.
func {activation_level | procedure} | |
change le niveau d'activation courant en utilisant soit le numéro du niveau soit le nom de la routine. En cas d'appels récursif, l'appel le plus récent est alors pris | |
func | affiche le nom de la routine correspondant au niveau d'activation |
Le fait de se déplacer dans la stack entraine une modification
de la visibilité. En effet à moins de qualifier complètement
une variable, dbx suppose toujours que les variables référencées
sont locales au niveau d'activation courant. De même, dbx
prend le fichier source contenant le code source de la routine comme fichier
source courant et se place sur la première ligne.
Si on utilise la commande func pour aller dans une routine qui
n'est pas dans la stack active, dbx ne change que le fichier
source courant et se place sur sa première ligne.
Affichage des informations du niveau d'activation
La commande dump affiche les informations des variables du niveau
d'activation
dump | affiche les informations des variables de la routine courante |
dump procedure | |
affiche les informations des variables de la routine spécifiée. Celle-ci doit être active | |
dump . | affiche les informations des variables de toutes les procédures de tous les niveaux d'activation |
Appels interactifs de functions
On peut appeler de manière interactive des routines du programme
au travers de dbx. Si la routine retourne une valeur, on peut utiliser
celle-ci au sein d'une expression dbx.
_____________________________________
Points d'arrêt inconditionnel
Pour mettre un point d'arrêt inconditionnel, il suffit de spécifier
l'endroit où l'on veut que le programme s'arrête à
l'aide d'une des formes de la commande stop :
stop at | met un point d'arrêt sur la ligne courante |
stop at line | met un point d'arrêt sur la ligne spécifiée |
stop in procedure | |
met un point d'arrêt dès l'entrée dans la procédure. L'exécution s'arrête pour tout clone ou inlining de la procedure | |
stop at file:line | |
met un point d'arrêt sur la ligne spécifiée du fichier spécifié |
Point d'arrêt conditionnel
Le point d'arrêt inconditionnel est la forme la plus simple du
point d'arrêt : le programme s'arrête à chaque passage.
D'un autre coté le point d'arrêt conditionnel arrête
le programme uniquement si une condition spécifiée est vérifiée.
Les deux conditions que l'on peut tester sont :
stop [expression|variable] | |
inspecte la valeur avant d'exécuter chaque ligne source. Si expression est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression est alors vue comme une adresse mémoire) | |
stop [expression|variable] at line | |
inspecte la valeur à la ligne source spécifiée : arrêt si elle a changé. Si expression est de type pointer, la donnée pointée est considérée; dans le cas contraire, dbx considère les 32bits se trouvant à cette adresse (expression est alors vue comme une adresse mémoire) | |
stop [expression|variable] in procedure | |
inspecte la valeur à chaque ligne source de la procédure spécifiée. Si expression est de type pointer, la donnée pointée est considérée; dans le cas contraire, dbx considère les 32bits se trouvant à cette adresse (expression est alors vue comme une adresse mémoire) |
Fast data breakpoints
On peut utiliser des points de suivi rapide, data breakpoints,
avec la commande stop. Un tel point suit une variable ou une adresse
mémoire spécifiée en limitant l'impact sur les performances
du programme débogué.
En effet, dbx utilise un mécanisme de verrouillage de
la mémoire virtuelle qui permet au programme de s'exécuter
normalement jusqu'à ce que la variable suivie change effectivement.
Le programme débogué s'arrête seulement lorsque
la page mémoire virtuelle contenant cette variable subit une opération
d'écriture. Si la valeur de la variable suivie ne change pas, dbx
continue l'exécution du processus, autrement dbx signale
la modification.
Sans ce mécanisme dbx vérifie la valeur après
chaque instruction ... et fait donc du pas à pas.
dbx a malgré tout besoin de ce mécanisme du pas à pas lorsque la commande stop contient une expression à suivre, telle que (global est une variable)
stop if global == 1La performance du programme débogué peut être fortement améliorée en ajoutant une variable à suivre dans la commande. Par exemple avec
stop global if global == 1Cela indique au débogueur de vérifier l'expression global == 1 seulement si la valeur de global a changé. Dans les cas ou l'expression à suivre ne dépend pas d'une variable particulière comme pour stop if global == 3 * x, le pas à pas est la seule approche pour aboutir.
Arrêt du programme si une expression est vraie
En incluant un test dans une commande stop, on peut faire arrêter
dbx
si la valeur d'une expression est vraie. On peut employer n'importe quelle
expression numérique valide pour le test. Si le résultats
de l'expression est non nul, l'expression est vraie et le test alors positif.
La fréquence à laquelle dbx vérifie la valeur
d'une variable ou d'une donnée en mémoire dépendent
de la manière dont le point d'arrêt a été mis
en place.
stop if expression | |
évalue l'expression avant d'exécuter chaque ligne source. L'exécution du code est alors très lente | |
stop at line if expression | |
évalue l'expression à la ligne spécifiée | |
stop in procedure if expression | |
évalue l'expression à chaque ligne source de la procédure spécifiée |
Points d'arrêt conditionnel combinant variable et tests d'expression
On peut créer des points d'arrêt conditionnel qui combine
à la fois une variable et des tests d'expression. Il faut alors
que toutes les composantes soient vraies pour que l'arrêt ait lieu.
Les formes suivantes de la commande stop combinent variable et tests d'expression
:
stop [expression1|variable] if expression2 | |
teste les deux conditions avant chaque ligne source : arrêt si les deux sont vérifiées. Si expression1 est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression1 n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression1 est alors vue comme une adresse mémoire) | |
stop [expression1|variable] at line if expression2 | |
teste les deux conditions à la ligne source spécifiée : arrêt si les deux sont vérifiées. Si expression1 est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression1 n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression1 est alors vue comme une adresse mémoire) | |
stop [expression1|variable] in procedure if expression2 | |
teste les deux conditions à chaque ligne source de la procédure spécifiée : arrêt si les deux sont vérifiées. Si expression1 est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression1 n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression1 est alors vue comme une adresse mémoire) |
cont | continue l'exécution avec la ligne courante |
cont [at|to] line | |
place un point d'arrêt temporaire sur la ligne source spécifiée puis reprend l'exécution sur la ligne courante. Lorsque le programme atteint ce point d'arrêt sur la ligne line, dbx stoppe le programme et détruit le point d'arrêt temporaire. Les mots-clés at et to sont équivalents | |
cont in procedure | |
place un point d'arrêt temporaire à l'entrée de la procédure spécifiée puis reprend l'exécution sur la ligne courante. Lorsque le programme atteint ce point d'arrêt dans procedure, dbx stoppe le programme et détruit le point d'arrêt temporaire |
Si le programme s'arrête parce que dbx reçoit un
signal destiné au programme, alors dbx renvoie le signal
lorsque l'on poursuit l'exécution (poursuite
après réception d'un signal).
trace variable | |
lorsque la valeur de variable change, dbx affiche l'ancienne et la nouvelle valeur | |
trace procedure | |
lors de l'entrée et de la sortie de la procédure, dbx affiche les valeurs des paramètres transmis | |
trace [expression|variable] at line | |
à chaque passage sur la ligne spécifiée, dbx affiche la valeur de variable si elle a changé. Si expression est de type pointer, la donnée pointée est considérée et inspectée jusqu'à ce qu'elle change. Si expression n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression est alors vue comme une adresse mémoire) | |
trace [expression|variable] in procedure | |
lorsque la valeur de variable change dans procedure, dbx affiche l'ancienne et la nouvelle valeur. Si expression est de type pointer, la donnée pointée est considérée et inspectée jusqu'à ce qu'elle change. Si expression n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression est alors vue comme une adresse mémoire) | |
trace [expression1|variable] at line if expression2 | |
affiche la valeur de variable (si différente) à chaque passage sur la ligne spécifiée et si expression2 est vraie. Si expression1 est de type pointer, la donnée pointée est considérée et inspectée jusqu'à ce qu'elle change. Si expression1 n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression1 est alors vue comme une adresse mémoire) | |
trace [expression1|variable] in procedure if expression2 | |
lorsque la valeur de variable change dans procedure, dbx affiche son ancienne et sa nouvelle valeur si expression2 est vraie. Si expression1 est de type pointer, la donnée pointée est considérée et inspectée jusqu'à ce qu'elle change. Si expression1 n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression1 est alors vue comme une adresse mémoire) |
Pour examiner les paramètres passés et les valeurs retournées par une function, on peut tracer cette function. Par exemple pour tracer la function foo
(dbx) trace fooLorsque l'on exécute le programme, dbx affiche les valeurs des arguments passés à foo à chaque appel et la valeur retournée en sortie
(dbx) runDans cet exemple la function foo reçoit 2 arguments : une chaine de caractères et un entier. En sortie, elle renvoie la valeur -1.
[3] calling foo(text=0x10000484 = "Processing... \n", i = 4) from function main
[4] foo returning -1 from foo
Lorsque l'on trace une variable il faut être attentif à
la confirmation que renvoie dbx : dbx peut ne pas avoir sélectionné
la bonne occurrence de la variable si le même nom est employé
à plusieurs endroits dans le programme. Dans ce cas il faut détruire
la trace (gestion des points d'arrêt,
traces et commandes conditionnelles) et en en créer une nouvelle
quitte à qualifier la variable.
when [expression|variable] {command-list} | |
inspecte la valeur avant d'exécuter chaque ligne source : si elle a changé alors exécute command-list. Si expression est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression est alors vue comme une adresse mémoire) | |
when [expression|variable] at line {command-list} | |
inspecte la valeur à la ligne source spécifiée : si elle a changé alors exécute command-list. Si expression est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression est alors vue comme une adresse mémoire) | |
when [expression|variable] in procedure {command-list} | |
inspecte la valeur à chaque ligne source de la procédure spécifiée : si elle a changé alors exécute command-list. Si expression est de type pointer, la donnée pointée est considérée; dans le cas contraire, dbx considère les 32bits se trouvant à cette adresse (expression est alors vue comme une adresse mémoire) | |
when if expression {command-list} | |
évalue expression avant d'exécuter chaque ligne source : si elle est vraie alors exécute command-list. L'exécution du programme est alors très lente | |
when at line if expression {command-list} | |
évalue expression sur la ligne source spécifiée : si elle est vraie alors exécute command-list | |
when in procedure if expression {command-list} | |
évalue expression à chaque ligne source de la procédure spécifiée : si elle est vraie alors exécute command-list | |
when [expression1|variable] if expression2 {command-list} | |
inspecte la valeur de variable. Si elle a changé et que expression2 est vraie alors exécute command-list. Si expression1 est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression1 n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression1 est alors vue comme une adresse mémoire) | |
when [expression1|variable] at line if expression2 {command-list} | |
inspecte la valeur de variable à chaque fois que la ligne source est exécutée. Si elle a changé et que expression2 est vraie alors exécute command-list. Si expression1 est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression1 n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression1 est alors vue comme une adresse mémoire) | |
when [expression1|variable] in procedure if expression2 {command-list} | |
inspecte la valeur de variable à chaque ligne source de procedure. Si elle a changé et que expression2 est vraie alors exécute command-list. Si expression1 est de type pointer, la donnée pointée est considérée et suivie jusqu'à ce qu'elle change. Si expression1 n'est pas de type pointer, dbx considère la donnée (32bits) se trouvant à l'adresse (expression1 est alors vue comme une adresse mémoire) |
Liste des points d'arrêt, traces et commandes conditionnelles
La commande status affiche l'ensemble des points d'arrêt,
traces et commandes conditionnelles qui sont crées et indique s'ils
sont activés ou désactivés.
Si on considère les commandes suivantes lors du déboguage
d'un programme appelé test :
(dbx) stop in fooLa commande status renvoie alors
Process 0: [3] stop in foo
(dbx) rerun
Process 22631 (test) started
[3] Process 22631 (test) stopped at [foo:38 ,0x10001050]
38 r = foo2(i+1)
(dbx) trace total
Process 22631: [4] trace total in foo
(dbx) when at 60 {print i,j }
Process 22631: [5] when at "/usr/var/tmp/dbx_examples/test.c":60 {print i,j }
(dbx) status
Process 22631: [3] stop in foo
Process 22631: [4] trace total in foo
Process 22631: [5] when at "/usr/var/tmp/dbx_examples/test.c":60 {print i,j }
Désactivation de points d'arrêt, traces et commandes
conditionnelles
La commande disable permet de désactiver temporairement
un point d'arrêt, une trace ou une commande conditionnelle, i.e.
le rendre inopérant et sans effect sur l'exécution du programme.
dbx
garde trace de toutes les informations concernant un point d'arrêt,
une trace ou une commande conditionnelle désactivé. La syntaxe
de cette commande est :
disable item [, item...] | |
désactive le(s) point(s) d'arrêt, trace(s), commandes conditionnelles spécifié(e)(s). Cette commande n'a pas d'effet sur un objet déjà désactivé. |
Pour désactiver la commande conditionnelle de l'exemple précédent, il suffit de faire
(dbx) disable 5Activation de points d'arrêt, traces et commandes conditionnelles
(dbx) status
Process 22631: [3] stop in foo
Process 22631: [4] trace total in foo
Process 22631: [5] (disabled) when at "/usr/var/tmp/dbx_examples/test.c":60 {print i,j }
enable item [, item...] | |
réactive le(s) point(s) d'arrêt, trace(s), commandes conditionnelles spécifié(e)(s). |
Pour réactiver la commande conditionnelle désactivée quelques lignes au-dessus, il suffit de faire
(dbx) enable 5
(dbx) status
Process 22631: [3] stop in foo
Process 22631: [4] trace total in foo
Process 22631: [5] when at "/usr/var/tmp/dbx_examples/test.c":60 {print i,j }
Destruction de points d'arrêt, traces et commandes conditionnelles
La commande delete permet de détruire des points d'arrêt,
traces ou commandes conditionnelles
delete {item [, item...] | all} | |
détruit le(s) point(s) d'arrêt, trace(s), commandes conditionnelles spécifié(e)(s). Le mot-clé all entraine la destruction de tous les points d'arrêt, traces et commandes conditionnelles |
Pour détruire le point d'arrêt et la trace de l'exemple précédent, il suffit de faire
(dbx) delete 3, 4
(dbx) status
Process 22631: [5] when at "/usr/var/tmp/dbx_examples/test.c":60 {print i,j }
Détection des signaux
La commande catch permet de dire à dbx d'arrêter
le programme lors de l'arrivée d'un signal précis. La commande
ignore
défait les effets de la commande catch. La syntaxe de ces
commandes est la suivante :
catch {signal|all} | |
dbx arrête le programme le signal spécifique. Si le mot-clé all est employé, dbx considère tous les signaux | |
ignore {signal|all} | |
dbx ignore le signal spécifié. Si le mot-clé all est employé, dbx ignore tous les signaux | |
catch | affiche la liste de tous les signaux reçus |
ignore | affiche la liste de tous les signaux ignorés |
On peut utiliser les noms et numéros des signaux données dans la manpage signal. en majuscules ou minuscules avec ou sans le préfixe SIG (à l'exception de SIGINT qui ne peut être abrégé en munuscules)
Si dbx doit arrêter un programme sur un signal donné, cela se fera quel que soit le moment où arrive le signal. Le programme ne reçoit le signal que lorsque l'on fait repartir le programme avec la commande cont. Si le programme a une routine qui gère les signaux, le signal est transmis au programme; autrement le programme ne voit pas le signal. On peut supprimer la transmission du signasl au programme en prenant les commandes step ou next au lieu de cont.
Poursuite de l'exécution après
réception d'un signal
La commande cont permet de poursuivre l'exécution après
réception d'un signal. On peut aussi utiliser la commande cont
pour envoyer un autre signal au programme que celui reçu initialement.
De plus, avec la même syntaxe on peut envoyer un signal au programme,
lors de la poursuite, même si le programme ne s'est pas arrêté
en raison du signal reçu :
cont [signal] | |
continue l'exécution avec la ligne courante et envoie le signal spécifié au programme | |
cont [signal] {at|to} line | |
place un point d'arrêt temporaire à la ligne source spécifiée puis reprend l'exécution avec la ligne courante et envoie le signal spécifié au programme | |
cont [signal] in procedure | |
place un point d'arrêt temporaire pour arrêter le programme à l'entrée de procedure, puis reprend l'exécution avec la ligne courante et envoie le signal spécifié au programme |
Si le programme s'arrête car dbx a détecté un SIGINT, dbx renvoie automatiquement ce signal au programme avec
(dbx) contSi le programme contient une routine, alarm_handler, pour gérer les signaux d'alarme reçus, on peut arrêter le programme à son entrée pour la parcourir au pas à pas à l'aide de
(dbx) cont SIGALRM in alarm_handlerCette commande place un point d'arrêt temporaire qui provoque l'arrêt du programme à l'entrée de la procédure alarm_handler et envoie le signal SIGALRM au programme. Lors de l'entrée dans la routine alarm_handler, le programme s'arrête et on peut faire du pas à pas.
55 foo( arg1, arg2 )Dans cet exemple, si un step est exécuté à la ligne 211 pour avancer d'une ligne, dbx autorise le processus à continuer à la ligne 58 (première ligne code de la procédure foo). Par contre, si on exécute un next, dbx exécute la ligne 211 (appel à foo) et avance le processus à la ligne 212.
56 int arg1, arg2;
57 {
58 if ( arg1 < arg2 ) {
... ...
78 return( 0 );
79 }
...
211 x = foo( i, j );
212 y = 2 * x;
Utilisation de la commande step
La syntaxe de la commande step est
step [integer] | |
exécute le nombre de lignes source spécifié en entrant dans les procédures si nécessaire. Sans argument, step n'exécute qu'une seule ligne source. S'il rencontre des points d'arrêt, step stoppe l'exécution |
Par défaut, step rentre dans les routines qui sont compiléees
avec l'une des options de déboguage -g, -g2, -g3
pour lesquelles les numéros des lignes source sont disponibles dans
la table des symboles. Cela ne concerne pas les routines des librairies
standard car elles ne sont pas compilées avec ces options.
On peut forcer dbx à entrer dans les routines non compilées
avec ces options en modifiant la valeur de la variable $stepintoall
:
Valeur | Effet sur la commande step |
0 (défaut) | rentre dans toutes les routines qui sont compilées avec l'une des options de déboguage -g, -g2, -g3 |
1 | en plus des procédures précédentes, entre dans les routines pour lesquelles le code source est disponible (même si les sauts peuvent être irréguliers) |
2 | entre dans toutes les procédures. Si dbx ne peut pas trouver le source, il n'affiche pas les numéros des lignes source |
Si le programme fait appel à des librairies dynamiques (DSO), il faut mettre à 1 la variable d'environnement LD_BIND_NOW avant l'exécution du programme. Cela perlmet de ne pas considérer le run-time linker comme faisant partie du code et compliquer le déboguage
(dbx) setenv LD_BIND_NOW 1
Utilisation de la commande next
La syntaxe de la commande next est
next [integer] | |
exécute le nombre de lignes source spécifié sans entrer dans les procédures. Sans argument, next n'exécute qu'une seule ligne source. S'il rencontre des points d'arrêt, next stoppe l'exécution |
Utilisation de la commande return
Si en faisant du pas à pas dans une routine, on décide
de ne pas finir de la parcourir de cette manière on peut utiliser
la commande return pour terminer son exécution et revenir
à la procédure appelante.
La syntaxe de la commande return est
return | |
continue l'exécution jusqu'au retour à la procédure appelante | |
return proc | |
continue l'exécution jusqu'à la fin de la procédure spécifiée. L'exécution continue à moins de rencontrer un point d'arrêt ou d'atteindre la dernière référence de la routine appelée par proc au moment où la commande est passée |
goto line | |
commence l'exécution à la ligne spécifiée. Elle ne peut reprendre qu'à partir d'une ligne source de la procédure courante |
Pour plus d'informations consultez la manpage de dbx.
_____________________________________
dbx
User's Guide (sur le serveur de SGI)