在 Linux 上以编程方式为 gdb 在 C 或 C++ 代码中设置断点

问题描述 投票:0回答:7

如何以编程方式在 C 或 C++ 代码中设置断点,以便适用于 Linux 上的 gdb?

即:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}
c++ c linux gdb
7个回答
132
投票

一种方法是发出中断信号:

#include <csignal>

// Generate an interrupt
std::raise(SIGINT);

在C中:

#include <signal.h>
raise(SIGINT);

更新Microsoft Docs 表示 Windows 并不真正支持

SIGINT
,因此如果考虑可移植性,您最好使用
SIGABRT

任何 Win32 应用程序都不支持 SIGINT。当 CTRL+C 中断发生时,Win32 操作系统会生成一个新线程来专门处理该中断。这可能会导致单线程应用程序(例如 UNIX 中的应用程序)变成多线程并导致意外行为。


42
投票

令人失望的是看到这么多答案没有使用软件断点的专用信号,

SIGTRAP

#include <signal.h>

raise(SIGTRAP); // At the location of the BP.

在 MSVC/MinGW 上,您应该使用

DebugBreak
__debugbreak
内在函数。一个简单的
#ifdef
可以处理这两种情况(POSIX 和 Win32)。


32
投票

通过查看这里,我发现了以下方法:

void main(int argc, char** argv)
{
    asm("int $3");
    int a = 3;
    a++;  //  In gdb> print a;  expect result to be 3
}

这对我来说似乎有点老套。我认为这只适用于 x86 架构。


29
投票

在我从事的一个项目中,我们这样做:

raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */

(在我们的例子中,如果这种情况发生在调试器之外,我们希望严重崩溃,如果可能的话生成崩溃报告。这是我们使用 SIGABRT 的原因之一。在 Windows、Mac 和 Linux 上移植这一点需要进行多次尝试。我们最终得到了一个一些#ifdef,在这里进行了有用的评论:http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66。)


13
投票

__asm__("int $3");
应该有效:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    __asm__("int $3");
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

0
投票

在 OS X 上,您只需调用

std::abort()
(在 Linux 上可能是相同的)


0
投票

<debugging>
将在 C++26 中可用:
std::breakpoint
std::breakpoint_if_debugging
std::is_debugger_present

std::breakpoint
std::is_debugger_present
的cppreference文档还提到了一些当前的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.