How do I set a conditional breakpoint in gdb, when char* x points to a string whose value equals "hello"?
Asked Answered
B

3

197

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?

Brownnose answered 15/11, 2010 at 11:25 Comment(1)
Note: strncmp and strstr are other useful C query functions.Silber
O
233

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.

Outgeneral answered 15/11, 2010 at 11:27 Comment(5)
Note: you must be running the program already so that GDB will see the stdlib. Otherwise: No symbol "strcmp" in current context.Silber
@CiroSantilli六四事件法轮功包卓轩: How to config gdb to see the stdlib?Lycia
@Lycia 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: #10000835 :-)Silber
This method can have side effects. $_streq method from @tlwhitec is better.Gala
For some reason gdb thinks strcmp() returns void. The $_streq from another answer workedLuck
G
90

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'
Giavani answered 10/5, 2017 at 12:46 Comment(8)
"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 !Helbonnah
@Helbonnah 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.Giavani
"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.Helbonnah
"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.Helbonnah
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".Helbonnah
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.Helbonnah
@Giavani 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.Imbrue
@Helbonnah "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.Imbrue
R
61
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!

Raddie answered 22/3, 2012 at 9:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.