J. Polfer
J. Polfer

Reputation: 12481

Set breakpoint in C or C++ code programmatically for gdb on Linux

How can I set a breakpoint in C or C++ code programatically that will work for gdb on Linux?

I.e.:

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

Upvotes: 149

Views: 123089

Answers (8)

GKxx
GKxx

Reputation: 373

<debugging> will be available in C++26: std::breakpoint, std::breakpoint_if_debugging and std::is_debugger_present.

The cppreference documentations for std::breakpoint and std::is_debugger_present also mention some of the current solutions.

Upvotes: 2

H&#229;vard S
H&#229;vard S

Reputation: 23876

One way is to signal an interrupt:

#include <csignal>

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

In C:

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

UPDATE: Microsoft Docs says that Windows doesn't really support SIGINT, so if portability is a concern, you're probably better off using SIGABRT.

SIGINT is not supported for any Win32 application. When a CTRL+C interrupt occurs, Win32 operating systems generate a new thread to specifically handle that interrupt. This can cause a single-thread application, such as one in UNIX, to become multithreaded and cause unexpected behavior.

Upvotes: 133

Disappointing to see so many answers not using the dedicated signal for software breakpoints, SIGTRAP:

#include <signal.h>

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

On MSVC/MinGW, you should use DebugBreak, or the __debugbreak intrinsic. A simple #ifdef can handle both cases (POSIX and Win32).

Upvotes: 56

J. Polfer
J. Polfer

Reputation: 12481

By looking here, I found the following way:

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

This seems a touch hackish to me. And I think this only works on x86 architecture.

Upvotes: 33

dacap
dacap

Reputation: 488

On OS X you can just call std::abort() (it might be the same on Linux)

Upvotes: 1

hek2mgl
hek2mgl

Reputation: 157947

__asm__("int $3"); should work:

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;
}

Upvotes: 13

Jason Orendorff
Jason Orendorff

Reputation: 45086

In a project I work on, we do this:

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

(In our case we wanted to crash hard if this happened outside the debugger, generating a crash report if possible. That's one reason we used SIGABRT. Doing this portably across Windows, Mac, and Linux took several attempts. We ended up with a few #ifdefs, helpfully commented here: http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66 .)

Upvotes: 29

Related Questions