16

I'm wanting to set a breakpoint on a function parameter if it is greater than a certain value. Dummy code below:

int main(void)
{
    uint64_t num = 123456;
    uint64_t x   = 847534;

    uint64_t other = (num*x) - (x/num);

    .... other stuff here (multithreaded stuff)

    calc(other);
}

void calc(uint64_t size)
{
    ...do some stuff with size
}

I've tried to set a breakpoint by:

(gdb) b calc if size == 852479

but it does not know what size is since it is a parameter I'm guessing. How would I break if the parameter equals a certain number. It is NOT an option to break on all the calls to this function because it gets called a billion times in the multithreaded environment.

Nick.D
  • 336
  • 1
  • 4
  • 10
  • possible duplicate of [How do I set a conditional breakpoint in gdb, when char\* x points to a string whose value equals "hello"?](http://stackoverflow.com/questions/4183871/how-do-i-set-a-conditional-breakpoint-in-gdb-when-char-x-points-to-a-string-wh) – Ricky Mutschlechner Nov 12 '14 at 16:46
  • Have you tried setting the breakpoint on the first line of the function code? – Leeor Nov 12 '14 at 16:49
  • 2
    @RickyMutschlechner I've looked at that 1 and it's not a duplicate because in the case of that code x (the variable in question) is assumed to be available by gdb to break on because it is a variable declared outside of a function. In my case this variable is the parameter of a function. I am successfully able to break on variables declared outside of a function but not able to break on parameters via conditional break – Nick.D Nov 12 '14 at 16:51
  • @Leeor That will work but this function gets called literally a billion times in a multithreaded environment and the error in question that I want to investigate happens after a variable amount of running time. So I will not be able to break on the first line on the function unless I want to keep pressing continue for hours (possibly days) :) – Nick.D Nov 12 '14 at 16:52
  • 1
    @Nick.D, I meant a conditional break – Leeor Nov 12 '14 at 17:02
  • 2
    That conditional breakpoint command works fine for me (gcc 4.8.2, gdb 7.6.1-51.el7 on CentOS 7). I type it right after starting gdb, without running the target. What gcc/gdb versions and OS do you see this problem on? – Mark Plotnick Nov 12 '14 at 17:21
  • are you using gdb on emacs, e.g. M-x gdb? It could be that its broken, try M-x gud-gdb instead - see http://stackoverflow.com/questions/20662444/getting-gdb-to-work-with-emacs-24 – bph Nov 14 '14 at 09:53

3 Answers3

8

from the gdb prompt:

break "file.c":100 if (size=852479)

or

break "file.c":100 if (size>852479)

here i am assuming you want the conditional breakpoint on line 100 and your src file is file.c

i.e if you want to break on the line that calls calc, then that would be line 100 - modify as appropriate (you would also have to substitute size with other in this instance)

if you used a line no. that was one of the 1st statements in the calc function then you would stick with size

bph
  • 10,728
  • 15
  • 60
  • 135
  • The problem that I'm having is gdb is not aware of "size" before starting the program possibly because it's a parameter name and not a variable declared outside of a function. One thing that I am trying right now is to set a break point on the function, running the program, now gdb is aware of the size variable and now I'm doing a condition break on that variable. Example below (gdb) break file.c:calc (gdb) run Breakpoint 1, calc (size=48) at file.c:67 in file.c (gdb) b if size = 852479 //This is where size is actually recognized by gdb (gdb) c – Nick.D Nov 12 '14 at 17:00
  • is gdb aware of anything *before* starting the program? 'other' is a variable that is declared and instantiated before the call to calc - therefore you should have no problem setting a conditional breakpoint on it (perhaps i am still misunderstanding the question here?) – bph Nov 12 '14 at 17:05
  • 1
    size should have a "==" on it instead of a "=", should be this: break "file.c":100 if (size==852479) – richmb Aug 11 '20 at 14:06
8

Assuming x86-64 calling conventions on GNU/Linux platform you could examine %rdi (64-bit) register directly to check function's first parameter:

b calc if $rdi == 852479

This allows you to break on function calc even if you don't have debugging symbols loaded (thus no code listing, i.e. by list calc).

Note that this method would fail if function is inlined by optimizing compiler.

Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137
5

If break foo if arg1 == 14 doesn't work for some reason (I've encountered some functions/binaries where it does, and where it doesn't), you can try to substitute it with commands.

commands allows you to set some gdb commands that will be run each time breakpoint is hit. To achieve desired effect - a conditional breakpoint - you can do the following:

(gdb) b foo
Breakpoint 1 at 0x400633: file test.c, line 6.
(gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>if arg1 != 14
 >cont
 >end
>end

The execution will stop at breakpoint only if arg1 == 14.

The only drawback is that silent suppresses typical "breakpoint hit" message. You can remove silent, but then gdb will print the message even if breakpoint is skipped by commands script, which is undesireable if breakpoint is hit very often.

You can add some custom notification inside command script, though.

WGH
  • 3,222
  • 2
  • 29
  • 42