Linux 断言失败后继续调试?
当 Windows 上的 Visual C++ 断言失败时,调试器会停止,显示消息,然后让您继续(或者,如果没有调试会话正在运行,则会为您启动 Visual Studio)。
在Linux上,assert()的默认行为似乎是显示错误并退出程序。由于我所有的断言都经过宏,所以我尝试使用信号来解决这个问题,例如
#define ASSERT(TEST) if(!(TEST)) raise(SIGSTOP);
但是尽管 GDB< /a> (通过 KDevelop)在正确的点停止,我似乎无法继续过去的信号,并在 GDB 中手动发送信号只会让我悬而未决,既无法控制 GDB,也无法控制调试的进程。
When an assertion fails with Visual C++ on Windows, the debugger stops, displays the message, and then lets you continue (or, if no debugging session is running, offers to launch visual studio for you).
On Linux, it seems that the default behavior of assert() is to display the error and quit the program. Since all my asserts go through macros, I tried to use signals to get around this problem, like
#define ASSERT(TEST) if(!(TEST)) raise(SIGSTOP);
But although GDB (through KDevelop) stops at the correct point, I can't seem to continue past the signal, and sending the signal manually within GDB just leaves me hanging, with control of neither GDB nor the debugged process.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您确实想重新创建 DebugBreak 的行为。这将停止调试器中的程序。
我在谷歌上搜索“DebugBreak linux”,发现了几个 对这段内联程序集的引用做同样的事情。
然后你的断言可以变成
根据 Andomar int 3 导致 cpu 引发中断 3。根据 drpepper 一个更便携的方法来做到这一点是调用:
You really want to recreate the behavior of DebugBreak. This stops the program in the debugger.
My googling of "DebugBreak linux" has turned up several references to this piece of inline assembly which is supposed to do the same.
Then your assert can become
According to Andomar int 3 causes the cpu to raise interrupt 3. According to drpepper a more portable way to do this would be to call:
您可以配置 gdb 以不同的方式处理特定信号。例如,以下内容将导致 SIGSTOP 不被视为可停止事件。
gdb 中的
handle SIGSTOP nostop noprint pass
help handle
将为您提供更多信息。You can configure gdb to handle specific signals in a different way. For example, the following will cause SIGSTOP not to be treated as a stoppable event.
handle SIGSTOP nostop noprint pass
help handle
within gdb will give you more information.通过以下方式可以实现更好的可用性
Even better usability is achieved with
您是否尝试过向进程发送 SIGCONT 信号?
Have you tried to send a SIGCONT signal to the process?
您可以将
assert
替换为您自己的版本,该版本调用pause()
而不是abort()
。当断言失败时,程序将暂停,您可以运行 gdb --pid $(pidof program) 来检查调用堆栈和变量。这种方法的一个优点是程序
不需要在GDB下启动。头文件(基于/usr/include/assert.h):
assert_fail
的实现(基于glibc中的assert.c):You can replace
assert
with your own version which callspause()
instead ofabort()
. When the assertion fails, the program will pause and you can rungdb --pid $(pidof program)
to examine the callstack and variables. An advantage of this approach is that theprogram
does not need to be started under GDB.Header file (based on /usr/include/assert.h):
Implementation of
assert_fail
(based on assert.c in glibc):