Stlink: st-util sollte auf LIBUSB_ERROR_NO_DEVICE beendet werden

Erstellt am 17. März 2019  ·  12Kommentare  ·  Quelle: stlink-org/stlink

Wenn ich zuerst den USB-Debugger abziehe und dann versuche, einen Befehl über GDB auszugeben, gibt st-util sehr schnell die folgenden Fehler aus:

  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

damit wird die CPU fast 100% belegt. Dies führt zu erheblicher Zeitverschwendung (Neustart der virtuellen Maschine usw.).

Die Art der Fehlermeldung ist ganz normal. stutil sollte jedoch bei diesem Fehler sofort beendet werden, damit ich den Rest des Problems lösen kann, indem ich stutil neu starte oder eine andere Maßnahme ergreife.

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

Alle 12 Kommentare

Ich denke, stlink sollte an dieser Stelle enden:

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

Ja ich denke du hast recht, ein Anruf bei libusb sollte entsprechend geprüft werden. Wenn Sie möchten, können Sie patchen und eine PR senden. Dies sollte auch für die anderen Aufrufe von libusb in der Datei usb.c durchgeführt werden. Danke fürs Melden!

Wenn Sie möchten, können Sie patchen und eine PR senden.

Ich würde gern. Ich bin mir jedoch nicht sicher, ob ich die Projektstruktur verstehe, so dass ein einfaches exit(1) hier ausreicht oder nicht.

Dies sollte auch für die anderen Aufrufe von libusb in der Datei usb.c durchgeführt werden.

Ich verstehe das vielleicht nicht so gut. Meinst du " send_recv bewirkt, dass die Anwendung beendet wird, wo immer sie -1 zurückgibt "?

Ich habe einen Kommentar in der PR platziert, es gibt noch mehr Stellen, an denen es schief gehen kann, wenn libusb angerufen wird.

Das Projekt ist wie folgt organisiert:

  • libstlink (usb.c ist Teil davon und sollte niemals exit in einer Bibliothek verwenden) Dateien der Bibliothek befinden sich im src-Ordner, am wichtigsten sind usb.c und common.c (und natürlich flash_loader.c)
  • st-util befindet sich in src/gdbserver
  • st-info befindet sich in src/tools/info.c
  • st-flash befindet sich in src/tools/flash.c

Ich denke, das könnte mit #888 und #445 zusammenhängen.
@ceremcem und @rewolff : Wie wäre es mit der Idee, dies gemeinsam zu besprechen?

@chenguokai : Hast du eine Idee, wie du hier vorgehen sollst?

Kann diesen Fall nicht reproduzieren.
Ich habe das Verfahren auf meinem macOS-Computer befolgt. Die Fehlermeldung wird angezeigt, aber keine Anzeichen für das Eintreten von toten Schleifen.
image
image

Bearbeiten: Ich habe den Befehl n ausgegeben, nachdem ich einen Haltepunkt für die Funktion main und den st-link entfernt habe

Es gibt ein Problem, dass das Programm beenden sollte, anstatt unbegrenzt erneut zu versuchen, Pakete zu senden oder zu empfangen.

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

Dieser Funktionsaufruf gibt keinen geeigneten Wert zurück, um die while(1)-Schleife zu beenden. Probleme können innerhalb der Funktion oder des while(1)-Mechanismus liegen.

Nachdem ich den Fehlerbehandlungsprozess mit lldb überprüft hatte, habe ich wahrscheinlich den Fehlercode herausgefunden.

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

Wenn _stlink_usb_step auf einen Fehler stößt, der ursprünglich durch das Fehlschlagen eines libusb-Aufrufs ausgelöst wurde, gibt es einen Rückgabewert ungleich Null zurück (in diesem Fall -1). Dieser Rückgabewert wird jedoch nicht von der recv-handle-send-Schleife in gdb-server verarbeitet:

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

Ich überlege mir zwei mögliche Deal-Strategien:

Gemeinsamer Teil: Überprüfen Sie den Rückgabewert von stlink_step im Schalterfall.

  1. Wenn ein Fehler angezeigt wird, versuchen Sie, GDB zu benachrichtigen und zu beenden.
  2. Wiederholen Sie diesen Funktionsaufruf für eingeschränkte Zeiten, wenn der Fehler weiterhin besteht, benachrichtigen Sie die GDB und beenden Sie sie, andernfalls fahren Sie fort.

Analyse:

Option 1 ist akzeptabel, da wir nicht vorhersagen können, was nach einem Kommunikationsfehler passiert. Der Nachteil ist, dass st-util auf einigen instabilen USB-Ports oder ähnlichem häufiger fehlschlägt.
Option 2 gibt instabilen Geräten eine weitere Chance, kann aber zu Paketduplizierungen führen, was das Debuggen etwas unvorhersehbarer macht.

Thx für die ausführliche Analyse. Ich würde hier Variante 1 bevorzugen. Wenn Leute auf Probleme im Zusammenhang mit bestimmten lokalen Hardware-Instabilitäten stoßen, können wir sowieso nichts dagegen tun und dies ist auch nichts, was die Stlink-Tools berücksichtigen sollten. Es scheint wichtiger, dass wir beim Debugging keine Kompromisse eingehen. Können Sie das sofort beheben?

Ich werde die Dokumentation von gdb überprüfen, um Pakete richtig zu senden. Nicht allzu schwer denke ich.
Nachdem ich fertig bin, werde ich eine PR erstellen.

Ich habe es nicht gesagt, aber ich habe mich für Option 2 entschieden. Aber nach deiner Erklärung: Du hast recht. Sie haben mich überzeugt: Wenn kein triftiger Grund zu der Annahme besteht, dass ein Fehler vorübergehend ist, sollte ein Fehler sofort als fatal angesehen werden.

Ein erneuter Versuch, ohne den Benutzer zu informieren, führt zu plötzlichen Überraschungen. Angenommen, 1/100 oder 1/1000 der übertragenen Bits werden beschädigt (auf welcher Ebene auch immer). Wenn dies dazu führt, dass ein Befehl in 99% der Fälle "ungültig" ist, erhält der Benutzer in dieser Situation im Durchschnitt viele Warnungen (dh Stlink wird plötzlich beendet), dass seine Hardware instabil ist, bevor er die stille Datenbeschädigung bekommt, die Probleme verursacht. ...

Der "einfache Ausweg" ist einfach "exit ()". Dadurch wird die Verbindung zu gdb plötzlich geschlossen und dies wird ausreichend elegant behandelt.

Grundfunktionen laufen gut unter dem PR mit einem stm32f401 Board.
Die tote Schleife wird während meines lokalen Tests aufgelöst. Jetzt wird st-util beendet. gdb erhält eine Fehlerantwort und trennt die Verbindung.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen