Stlink: st-util debe salir en LIBUSB_ERROR_NO_DEVICE

Creado en 17 mar. 2019  ·  12Comentarios  ·  Fuente: stlink-org/stlink

Cuando desenchufo el depurador USB por primera vez y luego intento emitir un comando a través de GDB, st-util da los siguientes errores muy rápidamente:

  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

ocupando así la CPU casi al 100%. Esto resulta en una gran pérdida de tiempo (reiniciar la máquina virtual, etc.).

El tipo de mensaje de error es bastante normal. Sin embargo, stutil debería salir inmediatamente con este error para poder manejar el resto del problema reiniciando stutil o tomando alguna otra medida.

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

Todos 12 comentarios

Creo que stlink debería terminar en este punto:

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

Sí, creo que tienes razón, una llamada a libusb debería marcarse como apropiada. Si lo desea, puede parchear y enviar un PR. También debe hacerse para las otras llamadas a libusb en el archivo usb.c. ¡Gracias por informarnos!

Si lo desea, puede parchear y enviar un PR.

Me encantaría. Sin embargo, no estoy seguro de entender la estructura del proyecto, por lo que un simple exit(1) aquí es suficiente o no.

También debe hacerse para las otras llamadas a libusb en el archivo usb.c.

Puede que no entienda esto muy bien. ¿Quiere decir " send_recv hacer que la aplicación finalice donde devuelva -1 "?

He puesto un comentario en el PR, hay más lugares donde puede salir mal cuando se realizan llamadas a libusb.

El proyecto se organiza de la siguiente manera:

  • libstlink (usb.c es parte de él y nunca debe usar exit en una biblioteca) los archivos de la biblioteca se encuentran en la carpeta src, el más importante es usb.cy common.c (y por supuesto flash_loader.c)
  • st-util se encuentra en src / gdbserver
  • st-info se encuentra en src / tools / info.c
  • st-flash se encuentra en src / tools / flash.c

Creo que esto podría estar relacionado con el # 888 y el # 445.
@ceremcem y @rewolff : ¿Qué tal la idea de discutir esto juntos?

@chenguokai : ¿Tiene una idea sobre cómo proceder aquí?

No se puede reproducir este caso.
Seguí el procedimiento en mi máquina macOS. Aparece el mensaje de error, pero no hay señales de que haya entrado en bucles muertos.
image
image

Editar: emití el comando n después de configurar un punto de interrupción en la función main y desconectar st-link

Existe un problema por el que el programa debería salir en lugar de reintentar ilimitadamente el envío o la recepción de paquetes.

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

Esta llamada a la función no devuelve un valor adecuado para finalizar el ciclo while (1). Los problemas pueden estar dentro de la función o el mecanismo while (1).

Después de verificar el proceso de manejo de errores con lldb , probablemente descubrí el código de falla.

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

Cuando _stlink_usb_step encuentra un error inicialmente provocado por la falla de una llamada libusb, devuelve un valor de retorno distinto de cero (-1 en este caso). Sin embargo, este valor de retorno no lo maneja el bucle recv-handle-send en gdb-server:

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

Se me ocurren dos posibles estrategias de negociación:

Parte común: verifique el valor de retorno de stlink_step en el caso del interruptor.

  1. Si se presenta algún error, intente notificar a GDB y salga.
  2. Rehaga esta llamada de función por tiempos restringidos, si la falla persiste, notifique a GDB y salga, de lo contrario continúe.

Análisis:

La opción 1 es aceptable ya que no podemos predecir lo que sucederá después de un error de comunicación. El inconveniente es que st-util puede fallar con más frecuencia en algunos puertos USB inestables o algo similar.
La opción 2 dará otra oportunidad a los dispositivos inestables, pero puede causar la duplicación de paquetes, lo que hace que la depuración sea un poco más impredecible.

Gracias por el análisis detallado. Preferiría la opción 1 aquí. Si las personas se encuentran con problemas relacionados con inestabilidades de hardware locales específicas, no hay nada que podamos hacer al respecto de todos modos y esto tampoco es nada que las herramientas stlink deberían considerar. Parece más importante que hagamos algún compromiso con la depuración. ¿Puede solucionar este problema de inmediato?

Verificaré la documentación de gdb para enviar paquetes correctamente. Supongo que no es demasiado difícil.
Cuando termine, subiré un PR.

No lo dije, pero iba por la opción 2. Pero después de tu explicación: tienes razón. Me tienes convencido: a menos que haya una razón válida para creer que un error es temporal, un error debe considerarse fatal de inmediato.

Reintentar sin informar al usuario dará lugar a sorpresas repentinas. Suponga que 1/100 o 1/1000 de los bits transferidos se corrompen (en cualquier nivel). Si eso da como resultado que un comando sea "inválido" en el 99% del tiempo, el usuario en esa situación recibiría en promedio muchas advertencias (es decir, stlink se cerrará repentinamente) de que su hardware es inestable antes de obtener la corrupción de datos silenciosa que causa problemas. ...

La "salida fácil" es simplemente "salir ()". Eso cerrará repentinamente la conexión a gdb y lo manejará con suficiente elegancia.

Las funciones básicas funcionan bien bajo el PR con una placa stm32f401.
El bucle muerto se resuelve durante mi prueba local. Ahora st-util saldrá. gdb recibirá una respuesta de error y se desconectará.

¿Fue útil esta página
0 / 5 - 0 calificaciones