当我第一次拔下 USB 调试器,然后尝试通过 GDB 发出命令时,st-util 非常迅速地给出以下错误:
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
从而几乎 100% 地占用 CPU。 这会导致严重的时间浪费(重新启动虚拟机等)。
这种错误信息是很正常的。 但是, stutil
应该在出现此错误时立即退出,以便我可以通过重新启动stutil
或采取其他一些措施来处理其余的问题。
我认为stlink
应该在此时终止: https :
我认为
stlink
应该在此时终止:https://github.com/texane/stlink/blob/df3c2b02867db03fb82f6faaad71300398965e85/src/usb.c#L54
是的,我认为您是对的,应该适当检查对 libusb 的调用。 如果你愿意,你可以修补并发送 PR。 对于在 usb.c 文件中对 libusb 的其他调用也应该这样做。 感谢举报!
如果你愿意,你可以修补并发送 PR。
我喜欢。 但是,我不确定我是否了解项目结构,因此简单的exit(1)
在这里是否足够。
对于在 usb.c 文件中对 libusb 的其他调用也应该这样做。
我可能不太明白这一点。 您的意思是“ send_recv
使应用程序在返回-1
地方终止”?
我认为这可能与 #888 和 #445 有关。
@ceremcem和@rewolff :一起讨论这个想法怎么样?
@chenguokai :你知道如何在这里进行吗?
无法重现这种情况。
我在我的 macOS 机器上遵循了这个过程。 出现错误消息,但没有进入任何死循环的迹象。
编辑:我在main
函数上设置断点并拔下 st-link 后发出命令n
确实存在程序应该退出而不是无限重试发送或接收数据包的问题。
这个函数调用没有返回一个合适的值来结束 while(1) 循环。 问题可能出在函数或 while(1) 机制内部。
用lldb
检查错误处理过程后,我大概找出了故障代码。
当_stlink_usb_step
遇到最初由 libusb 调用失败触发的错误时,它返回一个非零返回值(在这种情况下为 -1)。 但是,gdb-server 中的 recv-handle-send 循环不处理此返回值:
我提出了两种可能的交易策略:
公共部分:检查switch case中stlink_step
的返回值。
分析:
选项 1 是可以接受的,因为我们无法预测通信错误后会发生什么。 缺点是 st-util 在某些不稳定的 USB 端口或类似的东西上可能会更频繁地失败。
选项 2 会给不稳定的设备另一个机会,但可能会导致数据包重复,这使得调试更加不可预测。
谢谢详细分析。 我更喜欢这里的选项 1。 如果人们遇到与特定本地硬件不稳定性相关的问题,我们无论如何也无能为力,这也不是 stlink 工具应该考虑的。 我们对调试做出任何妥协似乎更重要。 你能马上解决这个问题吗?
我将检查 gdb 的文档以正确发送数据包。 我想不是太难。
完成后,我会提出一个PR。
我没有说,但我选择了选项 2。但是在你的解释之后:你是对的。 你让我信服了:除非有充分的理由相信错误是暂时的,否则应该立即将错误视为致命错误。
在没有通知用户的情况下重试会导致突然的意外。 假设传输位的 1/100 或 1/1000 被损坏(无论级别如何)。 如果这导致命令在 99% 的时间内“无效”,那么在这种情况下,用户在获得导致问题的静默数据损坏之前,平均会收到大量警告(即 stlink 突然退出),说明他的硬件不稳定。 ...
“简单的出路”就是“退出()”。 这将突然关闭与 gdb 的连接,它会足够优雅地处理它。
基本功能在 stm32f401 板的 PR 下运行良好。
在我的本地测试期间解决了死循环。 现在 st-util 将退出。 gdb 将收到失败回复并断开连接。