简体   繁体   中英

gdb not executing breakpoint commands during while loop

I have a simple C program (shown below), that calls a function g 5 times in a loop, and inside the function g , it calls f 10 times in a loop (so f is called 50 times altogether). I am trying to write a gdb script (also shown below) that:

  1. Puts a break point at g
  2. Runs until g is first called
  3. Sets breakpoint commands for the breakpoint in g so that the next time the breakpoint in g is reached, gdb exits
  4. Sets a breakpoint in the function f
  5. Enters a while-loop, which does something every time f is reached, and then continues (this has to be a while loop rather than a set of breakpoint commands, because this is a minimal example of a more complex case, where I have multiple step / finish / continue commands every time the breakpoint in the inner function is reached, which is not possible with breakpoint commands)

What I observe is that the breakpoint in the inner function f is reached, but when gdb reaches the breakpoint in g for the second time, it doesn't execute the commands I have set for g (IE gdb doesn't exit). The program continues executing and continues to the next time the function f is called, even though if I type info break at the gdb prompt, gdb shows the commands I have set for the breakpoint in g .

My questions:

  1. Why are my breakpoint commands in the function g not being executed, even though gdb prints out every time it reaches the breakpoint in g , and info break prints out the commands associated with g ?
  2. How do I change my gdb script so that when the breakpoint in g is reached for the second time, gdb exits?
  3. Maybe, as a solution to the previous question, is there some way to check which breakpoint has been reached in the while-loop, and exit if it is the breakpoint in g ?

Below are my simple C program and gdb script:

Simple C program

#include <stdio.h>

int i = 0;

void f() {
    printf("in f(), i = %i\n", i++);
}

void g() {
    printf("in g()\n");
    for (int j = 0; j < 10; j++) {
        f();
    }
}

int main() {
    for (int j = 0; j < 5; j++) {
        g();
    }
}

gdb script

break g
run

delete
break g
commands
printf "gdb: in g\n"
quit
end

break f
continue
while 1
    printf "gdb: in f\n"
    continue
end

I have a sort-of-hacky solution, which works in this case (and also in the more complex case I am interested in, for which the question above is a minimal reproducible example). But it won't necessarily work in every case, so I'm going to post it here but not accept it as an answer, while I wait for a more general solution.

The trick is as follows: at the start of the while-loop, go up the stack-frame and look at the j counter variable in the main function, and exit gdb as soon as j > 0 (which means that g has been called more than once). Example gdb script:

break g
run

delete
break f
continue

while 1
    printf "gdb: in f\n"
    up-silently
    up-silently
    if j > 0
        quit
    end
    continue
end
  1. How do I change my gdb script so that when the breakpoint in g is reached for the second time, gdb exits?

You can use this blah.txt script file:

break g
ignore 1 1
run
quit
y

Which is basically saying:

  • Break on g function.
  • Ignore that breakpoint 1 time.
  • Run the program.
  • Quit.
  • Yes, I really want to quit.

Build your blah.c file with: gcc -g -o blah blah.c

Run it with: gdb -x blah.txt blah

Output:

GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from blah...
Breakpoint 1 at 0x1196: file blah.c, line 9.
in g()
in f(), i = 0
in f(), i = 1
in f(), i = 2
in f(), i = 3
in f(), i = 4
in f(), i = 5
in f(), i = 6
in f(), i = 7
in f(), i = 8
in f(), i = 9

Breakpoint 1, g () at blah.c:9
9       void g() {
A debugging session is active.

        Inferior 1 [process 181] will be killed.

Quit anyway? (y or n) [answered Y; input not from terminal]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM