1
votes

La variable de commodité GDB ne se développe pas dans .gdbinit

J'exécute gdb avec un fichier .gdbinit , qui contient des variables pratiques qui ne se développent tout simplement pas.

1. Ma configuration

J'ai écrit le fichier .gdbinit suivant pour flasher un exécutable sur un microcontrôleur via une sonde blackmagic (voir https://github.com/blacksphere/blackmagic/wiki ):

arm-none-eabi-gdb -x .gdbinit -ex "flash-remote COM9"

La sonde blackmagic s'attache lui-même à un port COM, qui peut être différent d'un ordinateur à l'autre. Par conséquent, je ne veux pas coder cela en dur dans le fichier .gdbinit . Une variable de commodité GDB ressemblait à la solution la plus élégante:

https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_59.html

J'utilise donc la variable de commodité $ com dans le fichier .gdbinit et je le définis sur la ligne de commande lorsque j'appelle GDB:

arm-none-eabi-gdb -x .gdbinit -ex "flash-remote \"COM9\""

2. L'erreur

GDB démarre mais envoie un message d'erreur:

define flash-remote
  target extended-remote $arg0
  monitor version
  monitor swdp_scan
  attach 1
  file mcu_application.elf
  load
  start
  detach
  quit
end

Il semble que GDB ne reconnaît pas le $ com variable de commodité. Je vérifie donc si GDB a effectivement stocké la variable:

(gdb) set $com = "COM9"

(gdb) show convenience
$com = "COM9"
$trace_file = void
$trace_func = void
...

(gdb) target extended-remote $com
$com: No such file or directory.

Cela prouve que GDB l'a correctement stockée sous "COM9" . Le problème est donc de ne pas l'étendre.

3. Quelques essais supplémentaires

En observant l'échec de l'extension de $ com lors de l'exécution de .gdbinit , j'ai pensé que cela pourrait fonctionner pour émettre les commandes directement dans GDB :

(gdb) show convenience
$com = "COM9"
$trace_file = void
$trace_func = void
$trace_line = -1
$tracepoint = -1
$trace_frame = -1
$_inferior = 1
...

Mais l'erreur persiste.

4. Questions

Connaissez-vous un moyen de faire fonctionner les variables de commodité dans GDB? Ou connaissez-vous un autre mécanisme pour atteindre le même objectif?


5. La solution

Merci @Mark Plotnick pour votre réponse! Comme vous l'avez suggéré, j'ai donné à mon fichier .gdbinit le contenu suivant:

.gdbinit:6: Error in sourced command file:
$com: No such file or directory.

Cependant, j'ai dû supprimer les guillemets autour de l'argument COM9 lors de l'appel de GDB. Donc au lieu de:

arm-none-eabi-gdb -x .gdbinit -ex "set $com = \"COM9\""

j'invoque GDB de cette façon:

# .gdbinit file:
# ------------------------------------------- #
#              GDB commands                   #
#              FOR STM32F767ZI                #
# ------------------------------------------- #
target extended-remote $com
monitor version
monitor swdp_scan
attach 1
file mcu_application.elf
load
start
detach
quit

Maintenant ça marche! Vous avez sauvé ma journée!


0 commentaires

3 Réponses :


1
votes

Le manuel de GDB documente clairement que .gdbinit < / code> est évalué avant toute commande -ex .

Vous pouvez écrire un wrapper de shell trivial qui crée un /tmp/.gdbinit.$unique_suffix temporaire avec les substitutions appropriées, invoque gdb -x /tmp/.gdbinit .... < / code> et supprime le fichier temporaire une fois que GDB est sorti.


2 commentaires

Salut @EmployedRussian, merci pour votre réponse. Malheureusement, cela ne fonctionne pas. Même si je n'utilise pas du tout de fichier .gdbinit et que je saisis simplement les commandes manuellement dans gdb, la variable $ com ne se développe pas (voir le paragraphe 3 dans ma question).


Salut @EmployedRussian, merci pour votre aide. Votre suggestion fonctionnerait certainement. Cependant, la solution que je recherche devrait s'intégrer élégamment dans notre nouvel IDE pour les microcontrôleurs (je suis dans la startup "Embeetle", qui construit un nouvel IDE pour les microcontrôleurs). La solution doit donc être immédiatement évidente pour les utilisateurs qui souhaitent éditer eux-mêmes le fichier .gdbinit (nous nous efforçons pour un IDE qui ne cache rien dans les coulisses, mais n'utilise que des fichiers de configuration standard de l'industrie, voir embeetle.com/#comics/cfg_as_code ).



1
votes

Le format de sélection d'un port COM sous Windows est "//./COM9", donc votre test dans GDB aurait dû utiliser:

$com = COM9
target extended-remote //.$com

Je n'ai pas testé cela, mais je l'aurais fait attendez-vous à ce que cela fonctionne.


1 commentaires

Salut @Sid, Merci pour votre aide. Malheureusement ça ne marche pas.



3
votes

Les variables de commodité ne sont développées que dans certains contextes - principalement des expressions - comme les arguments pour print , x , eval , set et if .

Vous pouvez utiliser eval pour faire ce que vous voulez:

arm-none-eabi-gdb -ex "flash-remote \"COM9\""

Mais - et c'est un gros mais - jusqu'à récemment, lors de l'évaluation des expressions, gdb stockait des valeurs de chaîne dans l'espace d'adressage de la cible, ce qui nécessite un processus en cours d'exécution. Ainsi, sur les anciens gdbs, vous pouvez obtenir le message d'erreur L'évaluation de cette expression nécessite que le programme cible soit actif .

Gdb dispose d'une fonction de macro plus générale: commandes définies par l'utilisateur .

Une possibilité est de mettez ceci dans .gdbinit:

define flash-remote
  target extended-remote $arg0
  monitor version
  monitor swdp_scan
  attach 1
  file mcu_application.elf
  load
  start
  detach
  quit
end

Et invoquez gdb comme ceci:

eval "target extended-remote %s", $com


3 commentaires

Merci @Mark Plotnick. Cela fonctionne à merveille! Je mettrai une prime sur cette question et je vous la décernerai pour vous exprimer ma gratitude pour votre aide. Tu as sauvé ma journée (et en fait toute ma semaine).


Salut @Mark Plotnick. Je viens de vous attribuer la prime +100 pour vous montrer mon appréciation :-)


@ K.Mulier Merci.