Xaser
Xaser

Reputation: 2146

GDB Conditional Breakpoint in Multithreaded application

I'm using gdb to debug a multithreaded program.

The program produces a lot of threads that repeatedly process a string (identical thread function).

In that loop, I wish to break if the string in any of these threads equals a predefined constant string. For this I'm using break myfile:1234 if $_streq(managedStr->value(), "testString").

But this breakpoint never gets hit, eventhough I know for sure that managestStr takes the value "testString" for sure.

When leaving the condition, it breaks, but when trying to evaluate the condition manually then, I get an error

The program stopped in another thread while making a function call from GDB.

From this link i learned to set the scheduler-locking option while the program is paused, but setting this option from the very beginning didn't help with the breakpoint not being hit. Instead it will then get get

Error in testing breakpoint condition: The program stopped in another thread while making a function call from GDB. Evaluation of the expression containing the function (ManageString::value()) will be abandoned. When the function is done executing, GDB will silently stop. [Switching to Thread 0x7ffd35fb3700 (LWP 24354)]

What can I do to achieve the desired behaviour?

Upvotes: 0

Views: 1286

Answers (1)

Employed Russian
Employed Russian

Reputation: 213375

break myfile:1234 if $_streq(managedStr->value(), "testString")

That should work, and the fact that it doesn't work implies a bug in GDB.

That said, this method of debugging is exceedingly slow, because GDB has to stop every thread at line 1234 and then examine the memory values (i.e. evaluate the condition).

Usually it is much faster to insert a little bit of helper code into the program:

if (strcmp(namagedStr->value(), "testString") == 0) {
  printf("DEBUG: match\n");  // set breakpoint here!
}

and rebuild it.

Now instead of stopping every thread all the time and evaluating the condition, GDB will set a breakpoint on code that is only reached when the condition is true. This will be 100 to 1000 times faster (depending on number of threads).

This technique could be trivially extended if you need to vary the actual value you are looking for from run to run, or even within a single run, by adding a global variable:

const char *str_to_match = "testString";  // variable can be overwritten in GDB


    if (strcmp(managedStr->value(), str_to_match) == 0) {
      ...
    }

Upvotes: 2

Related Questions