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:
- Puts a break point at
g
- Runs until
g
is first called - Sets breakpoint commands for the breakpoint in
g
so that the next time the breakpoint ing
is reached,gdb
exits - Sets a breakpoint in the function
f
- 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 multiplestep
/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:
- Why are my breakpoint commands in the function
g
not being executed, even thoughgdb
prints out every time it reaches the breakpoint ing
, andinfo break
prints out the commands associated withg
? - How do I change my
gdb
script so that when the breakpoint ing
is reached for the second time,gdb
exits? - 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
CodePudding user response:
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
CodePudding user response:
- 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]