Stlink: st-util devrait se terminer sur LIBUSB_ERROR_NO_DEVICE

Créé le 17 mars 2019  ·  12Commentaires  ·  Source: stlink-org/stlink

Lorsque je débranche le débogueur USB pour la première fois, puis que j'essaie d'émettre une commande via GDB, st-util génère très rapidement les erreurs suivantes :

  core status: unknown
[!] send_recv send request failed: LIBUSB_ERROR_NO_DEVICE                      
[!] send_recv STLINK_DEBUG_GETSTATUS
  core status: unknown
[!] send_recv send request failed: LIBUSB_ERROR_NO_DEVICE                      
[!] send_recv STLINK_DEBUG_GETSTATUS
  core status: unknown
[!] send_recv send request failed: LIBUSB_ERROR_NO_DEVICE                      
[!] send_recv STLINK_DEBUG_GETSTATUS
  core status: unknown
[!] send_recv send request failed: LIBUSB_ERROR_NO_DEVICE                      
[!] send_recv STLINK_DEBUG_GETSTATUS
  core status: unknown
2019-03-17T14:26:42 ERROR src/flash_loader.c: flash loader run error           
2019-03-17T14:26:42 ERROR src/common.c: stlink_flash_loader_run(0x8000000) failed! == -1

occupant ainsi le CPU près de 100%. Il en résulte une grave perte de temps (redémarrage de la machine virtuelle, etc.).

Le genre de message d'erreur est tout à fait normal. Cependant, stutil devrait se terminer immédiatement sur cette erreur afin que je puisse gérer le reste du problème en redémarrant stutil ou en prenant une autre mesure.

bufixed componenst-util componenstlink-lib dependenclibusb errogdb-server staturesolved

Tous les 12 commentaires

Je pense que stlink devrait se terminer à ce stade :

https://github.com/texane/stlink/blob/df3c2b02867db03fb82f6faaad71300398965e85/src/usb.c#L54

Oui, je pense que vous avez raison, un appel à libusb doit être vérifié comme approprié. Si vous le souhaitez, vous pouvez patcher et envoyer un PR. Il faut aussi le faire pour les autres appels à libusb dans le fichier usb.c. Merci d'avoir signalé !

Si vous le souhaitez, vous pouvez patcher et envoyer un PR.

J'aimerais bien. Cependant, je ne suis pas sûr de comprendre la structure du projet, donc un simple exit(1) suffit ici ou non.

Il faut aussi le faire pour les autres appels à libusb dans le fichier usb.c.

Je ne comprends peut-être pas très bien. Voulez-vous dire « send_recv fait que l'application se termine partout où elle renvoie -1 » ?

J'ai placé un commentaire dans le PR, il y a plus d'endroits où ça peut mal tourner lorsque des appels sont passés à libusb.

Le projet est organisé de la manière suivante :

  • libstlink (usb.c en fait partie et ne devrait jamais utiliser exit dans une bibliothèque) les fichiers de la bibliothèque sont situés dans le dossier src, le plus important est usb.c et common.c (et bien sûr flash_loader.c)
  • st-util est situé dans src/gdbserver
  • st-info se trouve dans src/tools/info.c
  • st-flash se trouve dans src/tools/flash.c

Je pense que cela pourrait être lié aux #888 et #445.
@ceremcem et @rewolff : Et l'idée d'en discuter ensemble ?

@chenguokai : Avez-vous une idée sur la façon de procéder ici ?

Impossible de reproduire ce cas.
J'ai suivi la procédure sur ma machine macOS. Le message d'erreur apparaît, mais aucun signe de saisie de boucles mortes.
image
image

Edit: j'ai émis la commande n après avoir configuré un point d'arrêt sur la fonction main et débranché st-link

Il existe un problème selon lequel le programme doit quitter plutôt que de réessayer de manière illimitée d'envoyer ou de recevoir des paquets.

https://github.com/texane/stlink/blob/0082e488579077762627dba2cee54ffca64dad17/src/gdbserver/gdb-server.c#L1121

Cet appel de fonction ne renvoie pas une valeur appropriée pour terminer la boucle while(1). Les problèmes peuvent résider à l'intérieur de la fonction ou du mécanisme while(1).

Après avoir vérifié le processus de gestion des erreurs avec lldb , j'ai probablement trouvé le code d'erreur.

https://github.com/texane/stlink/blob/bf840a1ae82ffc3ef9929f243bb8050d6856f698/src/gdbserver/gdb-server.c#L1448

Lorsque _stlink_usb_step rencontre une erreur initialement déclenchée par l'échec d'un appel libusb, il renvoie une valeur de retour non nulle (-1 dans ce cas). Cependant, cette valeur de retour n'est pas gérée par la boucle recv-handle-send dans gdb-server :

https://github.com/texane/stlink/blob/bf840a1ae82ffc3ef9929f243bb8050d6856f698/src/gdbserver/gdb-server.c#L1119

Je propose deux stratégies de transaction possibles :

Partie commune : vérifiez la valeur de retour de stlink_step dans le cas du commutateur.

  1. Si une erreur se présente, essayez de notifier GDB et quittez.
  2. Refaire cet appel de fonction pour des périodes restreintes, si l'échec persiste, notifier GDB et quitter, sinon continuer.

Analyse:

L'option 1 est acceptable car nous ne pouvons pas prédire ce qui se passera après une erreur de communication. L'inconvénient est que st-util peut échouer plus fréquemment sur certains ports USB instables ou quelque chose de similaire.
L'option 2 donnera une autre chance aux périphériques instables mais peut entraîner une duplication de paquets, ce qui rend le débogage légèrement plus imprévisible.

Merci pour l'analyse détaillée. Je préférerais l'option 1 ici. Si des personnes rencontrent des problèmes liés à des instabilités matérielles locales spécifiques, nous ne pouvons rien y faire de toute façon et ce n'est pas non plus ce que les outils stlink devraient prendre en compte. Il semble plus important que nous fassions un compromis sur le débogage. Êtes-vous en mesure de résoudre ce problème tout de suite?

Je vais vérifier la documentation de gdb pour envoyer correctement le(s) paquet(s). Pas trop difficile je pense.
Une fois que j'ai terminé, je vais élever un PR.

Je ne l'ai pas dit, mais j'allais pour l'option 2. Mais après ton explication : Tu as raison. Vous m'avez convaincu : à moins qu'il n'y ait une raison valable de croire qu'une erreur est temporaire, une erreur doit être immédiatement considérée comme fatale.

Réessayer sans en informer l'utilisateur entraînera des surprises soudaines. Supposons que 1/100ème ou 1/1000ème des bits transférés soit corrompu (à n'importe quel niveau). Si cela se traduit par une commande « invalide » dans 99% du temps, l'utilisateur dans cette situation recevra en moyenne de nombreux avertissements (c'est-à-dire que stlink se ferme soudainement) indiquant que son matériel est instable avant d'avoir la corruption silencieuse des données qui cause des problèmes. ...

La "solution de facilité" consiste simplement à "sortir ()". Cela fermera soudainement la connexion à gdb et le gérera avec suffisamment de grâce.

Les fonctions de base fonctionnent bien sous le PR avec une carte stm32f401.
La boucle morte est résolue lors de mon test local. Maintenant, st-util va se fermer. gdb recevra une réponse d'échec et se déconnectera.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

bolorkhuu picture bolorkhuu  ·  11Commentaires

grzegorz-kraszewski picture grzegorz-kraszewski  ·  9Commentaires

tabemann picture tabemann  ·  5Commentaires

renn0xtek9 picture renn0xtek9  ·  8Commentaires

chenguokai picture chenguokai  ·  6Commentaires