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.
Acho que stlink
deve terminar neste ponto: https://github.com/texane/stlink/blob/df3c2b02867db03fb82f6faaad71300398965e85/src/usb.c#L54
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:
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.
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.
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.
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:
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.
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á.