193

Can I specify that I want gdb to break at line x when char* x points to a string whose value equals "hello"? If yes, how?

341008
  • 9,862
  • 11
  • 52
  • 84

3 Answers3

230

You can use strcmp:

break x:20 if strcmp(y, "hello") == 0

20 is line number, x can be any filename and y can be any variable.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Nathan Fellman
  • 122,701
  • 101
  • 260
  • 319
  • 12
    Note: you must be running the program already so that GDB will see the stdlib. Otherwise: `No symbol "strcmp" in current context.` – Ciro Santilli OurBigBook.com Jul 27 '15 at 20:45
  • 1
    @CiroSantilli六四事件法轮功包卓轩: How to config gdb to see the stdlib? – naive231 Nov 13 '15 at 02:48
  • @naive231 by "see" I meant see functions so you can break at them, not the source: you have to hit `run` for that so that dynamic libraries get loaded. For source, google it and find: http://stackoverflow.com/questions/10000335/how-to-use-debug-version-of-libc :-) – Ciro Santilli OurBigBook.com Nov 13 '15 at 09:52
  • 4
    This method can have side effects. `$_streq` method from @tlwhitec is better. – rools Apr 14 '19 at 14:08
87

Use a break condition with $_streq (one of GDB's own convenience functions):

break [where] if $_streq(x, "hello")

or, if your breakpoint already exists, add the condition to it:

condition <breakpoint number> $_streq(x, "hello")

Since GDB 7.5 (long ago) you can use that and a handful of other native convenience functions for various string matching, including $_regex which supports the Python regex syntax:

$_memeq(buf1, buf2, length)
$_regex(str, regex)
$_streq(str1, str2)
$_strlen(str)

These are quite less problematic than having to execute the usual strcmp() injected to the process' stack, because that can have undesired side effects.

Alas, using the native functions is not always possible, because they rely on GDB being compiled with Python support. This is usually the default, but some constrained environments might not have it. To be sure, you can check it by running show configuration inside GDB and searching for --with-python. This shell oneliner does the trick, too:

gdb -n -quiet -batch -ex 'show configuration' | grep 'with-python'
tlwhitec
  • 1,845
  • 16
  • 15
  • 1
    "but some constrained environments might not have it." Indeed, embedded systems libc does not always provide a malloc() function, so gdb cannot call strcmp(). In this case $_streq() is prefered, thanks for the tip ! – Dali Aug 31 '21 at 12:15
  • @Dali In an environment so stripped down that there's no `malloc`, I wouldn't expect a python runtime either :) Also I'm pretty sure `strcmp` doesn't use `malloc` at all, so I must say I'm pretty confused by your comment :) My recommendation to avoid `strcmp` stems from the fact that it can have side effects (so by debugging your program you inject something that wouldn't be there otherwise). I hit that problem while debugging a highly multithreaded process, where using `strcmp` in gdb just broke the whole process. – tlwhitec Aug 31 '21 at 13:21
  • 1
    "In an environment so stripped down that there's no malloc, I wouldn't expect a python runtime either :)" In my case gdb is used as part of a cross-compilation environnement. The program runs on the embedded system, Gdb client on a linux host. So yes my gdb client has been built with python support. – Dali Sep 03 '21 at 15:06
  • "My recommendation to avoid strcmp stems from the fact that it can have side effects (so by debugging your program you inject something that wouldn't be there otherwise)." Your answer can thankfully solve more problems than the one you encountered, that's what I meant. – Dali Sep 03 '21 at 15:08
  • 1
    strcmp calls points to your debugged program implementation. Here is a gdb output to illustrate: (gdb) call strcmp("hello", "world") evaluation of this expression requires the program to have a function "malloc". – Dali Sep 03 '21 at 15:10
  • Whereas the convenience function is available : (gdb) call $_streq("hello", "hello") $25 = 1. So then again thanks for your answer, it helped me and potentially other embedded systems developper. – Dali Sep 03 '21 at 15:18
  • 1
    @tlwhitec When having GDB inject a `strcmp` call into a process if one of the arguments is a string literal, GDB must create that string in the process's memory. To do this is uses `malloc`. For convenience functions which are run in the GDB process, it doesn't need to allocate the string on the inferior. – crass Feb 14 '23 at 00:13
  • @Dali "Indeed, embedded systems libc does not always provide a malloc() function, so gdb cannot call strcmp()" This confuses the issue, even when there is no `malloc` in the inferior, GDB can still call `strcmp()`, if it is a valid function pointer symbol. You just can't do `strcmp(x, "astring")` because the string literal requires `malloc`. – crass Feb 14 '23 at 00:17
60
break x if ((int)strcmp(y, "hello")) == 0

On some implementations gdb might not know the return type of strcmp. That means you would have to cast, otherwise it would always evaluate to true!

tshepang
  • 12,111
  • 21
  • 91
  • 136
Tobias Domhan
  • 3,096
  • 1
  • 19
  • 12