76

I am looking for a way to do some action when a particular break point hits in gdb.

Basically I have some memleak in my program. When malloc and free function hits, I need to enter into the function (step) and collect some basic information like the addr and size (basically print there values). Once done resume my program.

Do we have any good way to do this?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Thangaraj
  • 3,038
  • 7
  • 40
  • 43

3 Answers3

84

For example, here is how you could use breakpoint commands to print the value of x at entry to foo whenever x is positive.

break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end

If the first command you specify in a command list is silent, the usual message about stopping at a breakpoint is not printed. This may be desirable for breakpoints that are to print a specific message and then continue. If none of the remaining commands print anything, you see no sign that the breakpoint was reached. silent is meaningful only at the beginning of a breakpoint command list.

One application for breakpoint commands is to compensate for one bug so you can test for another. Put a breakpoint just after the erroneous line of code, give it a condition to detect the case in which something erroneous has been done, and give it commands to assign correct values to any variables that need them. End with the continue command so that your program does not stop, and start with the silent command so that no output is produced. Here is an example:

break 403
commands
silent
set x = y + 4
cont
end
Fredrik Pihl
  • 44,604
  • 7
  • 83
  • 130
  • Thanks Fredrik. But here the variable name is unknown right. suppose I have 1GB of code. then what should we need to do? is there any generic method to do this? – Thangaraj Jun 29 '11 at 11:22
  • @Thangaraj if you have a memleak, have a look at `valgrind` probably THE best tool to find memoryleaks and very simple to use! – Fredrik Pihl Jun 29 '11 at 16:03
  • Thanks you. valgrind will help me in case of memory leak. but in general is there any other way to achieve. Just to explore... – Thangaraj Jun 30 '11 at 05:50
  • Do you know how to stop GDB from prompting? I meant those messages `Type to continue, or q to quit---` – daisy Jun 29 '14 at 06:51
  • 1
    [Link to GDB docs](https://sourceware.org/gdb/onlinedocs/gdb/Break-Commands.html). – user202729 Jun 16 '18 at 11:01
  • @FredrikPihl Sorry, I can't any difference between the former code snippet and the latter one. What do you want us to know for the second example since there is already a demo snippet above? Could you please explain that for me? – John Nov 11 '22 at 01:57
65

To clarify Fredrik's answer, commands (or just command, it seems) automatically knows you just set a breakpoint. That is, what Fredrik is showing isn't a multi-line break command, it's two separate commands: break, and commands. It looks like this:

(gdb) break 989 
Breakpoint 23 at 0x7fffe2761dac: file foo.cpp, line 989.
(gdb) command
Type commands for breakpoint(s) 23, one per line.
End with a line saying just "end".
>silent
>print result
>end
(gdb) c
Continuing.
$79 = {elems = {0, 0}}
(gdb) 
Ben
  • 9,184
  • 1
  • 43
  • 56
  • 1
    command vs commands: GCC allows you to write just the prefix of command, as long as it is unique. Also, for others: "help commands" shows that one can specify the breakpoint to set the condition on. – thomasa88 Sep 14 '20 at 06:19
16

dprintf (Dynamic printf)

https://sourceware.org/gdb/onlinedocs/gdb/Dynamic-Printf.html

This is the most convenient solution for the specific case of printing things:

dprintf <line>, "%u\n", variable

e.g.:

dprintf 10, "%u %u\n", i, r

It could also in principle be faster than commands as it could compile and inject code, instead of giving control back to GDB to interpret arbitrary command strings, which is extremely slow, but it doesn't seem to do that and is only marginally faster than commands, see also: What is the difference between dprintf vs break + commands + continue? I've asked if there's a way to use compile code to speed things up at: GDB compile code and don't remove injected code after execution

Detailed example:

main.c

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    uint32_t i;
    uint32_t r = 0;
    for (i = 0; i < 10; ++i) {
        r += i*i + 13*r*i + 17;   /* LINE 10. */
    }
    printf("%" PRIu32 "\n", r);
    return EXIT_SUCCESS;
}

Then:

gcc -ggdb3 -O0 -std=c99 -o main main.c
gdb -batch --nh -q -ex 'dprintf 10, "%u %u\n", i, r' -ex 'run' ./main

Output:

Dprintf 1 at 0x400545: file main.c, line 10.
0 0
1 17
2 256
3 6933
4 277346
5 14699371
6 970158528
7 3628079733
8 3070853710
9 317092431
3057168588
[Inferior 1 (process 14305) exited normally]

Tested in Ubuntu 16.04, GDB 8.2.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985