Stlink: st-util deve sair em LIBUSB_ERROR_NO_DEVICE

Criado em 17 mar. 2019  ·  12Comentários  ·  Fonte: stlink-org/stlink

Quando eu desconecto o depurador USB pela primeira vez e tento emitir um comando via GDB, st-util fornece os seguintes erros muito rapidamente:

  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 assim a CPU quase 100%. Isso resulta em uma grande perda de tempo (reiniciar a máquina virtual, etc.).

O tipo de mensagem de erro é normal. No entanto, stutil deve sair imediatamente com esse erro para que eu possa lidar com o resto do problema reiniciando stutil ou tomando alguma outra medida.

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

Todos 12 comentários

Acho que stlink deve terminar neste ponto:

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

Sim, acho que você está certo, uma chamada para libusb deve ser marcada apropriada. Se você quiser, pode corrigir e enviar um PR. Também deve ser feito para as outras chamadas para libusb no arquivo usb.c. Obrigado por relatar!

Se você quiser, pode corrigir e enviar um PR.

Eu adoraria. No entanto, não tenho certeza se entendi a estrutura do projeto, portanto, um simples exit(1) suficiente aqui ou não.

Também deve ser feito para as outras chamadas para libusb no arquivo usb.c.

Posso não entender isso muito bem. Você quer dizer " send_recv fazer o aplicativo terminar sempre que retornar -1 "?

Coloquei um comentário no PR, há mais lugares onde pode dar errado quando as ligações são feitas para libusb.

O projeto está organizado da seguinte forma:

  • libstlink (usb.c faz parte dele e nunca deve usar exit em uma biblioteca) os arquivos da biblioteca estão localizados na pasta src, o mais importante é usb.c e common.c (e, claro, flash_loader.c)
  • st-util está localizado em src / gdbserver
  • st-info está localizado em src / tools / info.c
  • st-flash está localizado em src / tools / flash.c

Acho que isso pode estar relacionado aos números 888 e 445.
@ceremcem e @rewolff : E a ideia de discutirmos isso juntos?

@chenguokai : Você tem uma ideia de como proceder aqui?

Não é possível reproduzir este caso.
Eu segui o procedimento em minha máquina macOS. A mensagem de erro aparece, mas nenhum sinal de entrada em loops mortos.
image
image

Editar: Emita o comando n após configurar um ponto de interrupção na função main e desconectar o st-link

Existe um problema que o programa deve encerrar, em vez de tentar novamente enviar ou receber pacotes de forma ilimitada.

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

Esta chamada de função não retorna um valor adequado para encerrar o loop while (1). Os problemas podem estar dentro da função ou do mecanismo while (1).

Depois de verificar o processo de tratamento de erros com lldb , provavelmente descobri o código da falha.

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

Quando _stlink_usb_step encontra um erro inicialmente disparado pela falha de uma chamada libusb, ele retorna um valor de retorno diferente de zero (-1 neste caso). No entanto, este valor de retorno não é tratado pelo loop recv-handle-send no gdb-server:

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

Eu vim com duas estratégias de negócio possíveis:

Parte comum: Verifique o valor de retorno de stlink_step na caixa do switch.

  1. Se algum erro for apresentado, tente notificar o GDB e sair.
  2. Refaça esta chamada de função para tempos restritos, se a falha persistir, notifique o GDB e saia, caso contrário, prossiga.

Análise:

A opção 1 é aceitável, pois não podemos prever o que acontecerá após um erro de comunicação. A desvantagem é que st-util pode falhar com mais frequência em algumas portas usb instáveis ​​ou algo parecido.
A opção 2 dará aos dispositivos instáveis ​​outra chance, mas pode causar a duplicação de pacotes, o que torna a depuração um pouco mais imprevisível.

Obrigado pela análise detalhada. Eu favoreceria a opção 1 aqui. Se as pessoas tiverem problemas relacionados a instabilidades de hardware locais específicas, não há nada que possamos fazer para isso de qualquer maneira e isso também não é nada que as ferramentas stlink devam considerar. Parece mais importante comprometer a depuração. Você consegue consertar isso imediatamente?

Vou verificar a documentação do gdb para enviar o (s) pacote (s) corretamente. Não é muito difícil, eu acho.
Depois de terminar, levantarei um PR.

Eu não disse isso, mas estava indo para a opção 2. Mas depois da sua explicação: Você tem razão. Você me convenceu: a menos que haja um motivo válido para acreditar que um erro é temporário, um erro deve ser considerado fatal imediatamente.

Tentar novamente sem informar o usuário causará surpresas repentinas. Suponha que 1/100 ou 1/1000 dos bits transferidos sejam corrompidos (em qualquer nível). Se isso resultar em um comando sendo "inválido" em 99% do tempo, o usuário nessa situação receberia, em média, muitos avisos (ou seja, stlink fechando repentinamente) de que seu hardware está instável antes de obter a corrupção de dados silenciosa que causa problemas. ...

A "saída mais fácil" é apenas "sair ()". Isso fechará repentinamente a conexão com o gdb e tratará disso de maneira suficientemente elegante.

As funções básicas funcionam bem no PR com uma placa stm32f401.
O ciclo morto é resolvido durante meu teste local. Agora o st-util vai sair. O gdb receberá uma resposta de falha e se desconectará.

Esta página foi útil?
0 / 5 - 0 avaliações