How to step into a set of chained methods with gdb? [duplicate] - c++

I am debugging C++ in gdb 7.1 on Linux.
I have a function a() that is called in many places in the code. I want to set a breakpoint in it, but only if it was called from b(). Is there any way to do it?
Is there any way to do it only if b() was called from c(), and so on ad infinitum?

Update: There is now a better answer to this question: use GDB _is_caller convenience function.
The need you describe comes up quite often, usually in the context of some_utility_fn being called a lot, but you only are interested in the call which comes from some_other_fn.
You could probably script this entire interaction using the new embedded Python support in GDB from CVS trunk.
Without Python, you are limited in what you can do, but the usual technique is to have a disabled breakpoint on a(), and enable it from a command, attached to a breakpoint on b().
Here is an example:
int a(int x)
{
return x + 1;
}
int b()
{
return a(1);
}
int call_a_lots()
{
int i, sum = 0;
for (i = 0; i < 100; i++)
sum += a(i);
}
int main()
{
call_a_lots();
return b();
}
gcc -g t.c
gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) break a
Breakpoint 1 at 0x4004cb: file t.c, line 3.
(gdb) disable 1
(gdb) break b
Breakpoint 2 at 0x4004d7: file t.c, line 8.
(gdb) command 2
>silent
>enable 1
>continue
>end
(gdb) run
Breakpoint 1, a (x=1) at t.c:3
3 return x + 1;
(gdb) bt
#0 a (x=1) at t.c:3
#1 0x00000000004004e1 in b () at t.c:8
#2 0x000000000040052c in main () at t.c:21
(gdb) q
Voila: we've stopped on a() called from b(), ignoring previous 100 calls to a().

gdb can handle this directly now without any need for Python. Just do this:
b a if $_caller_is("b")

I have tested this on gdb 7.6 that is already available but it does not work on gdb 7.2 and probably on gdb 7.1:
So this is main.cpp:
int a()
{
int p = 0;
p = p +1;
return p;
}
int b()
{
return a();
}
int c()
{
return a();
}
int main()
{
c();
b();
a();
return 0;
}
Then g++ -g main.cpp
This is my_check.py:
class MyBreakpoint (gdb.Breakpoint):
def stop (self):
if gdb.selected_frame().older().name()=="b":
gdb.execute("bt")
return True
else:
return False
MyBreakpoint("a")
And this is how it works:
4>gdb -q -x my_check.py ./a.out
Reading symbols from /home/a.out...done.
Breakpoint 1 at 0x400540: file main.cpp, line 3.
(gdb) r
Starting program: /home/a.out
#0 a () at main.cpp:3
#1 0x0000000000400559 in b () at main.cpp:10
#2 0x0000000000400574 in main () at main.cpp:21
Breakpoint 1, a () at main.cpp:3
3 int p = 0;
(gdb) c
Continuing.
[Inferior 1 (process 16739) exited normally]
(gdb) quit

A simpler solution than Python scripting is using a temporary breakpoint.
It looks like this:
b ParentFunction
command 1
tb FunctionImInterestedIn
c
end
Every time you break in ParentFunction, you'll set a one-time breakpoint on the function you're actually interested in, then continue running (presumably until you hit that breakpoint).
Since you'll break exactly once on FunctionImInterestedIn, this won't work if FunctionImInterestedIn is called multiple times in the context of ParentFunction and you want to break on each invocation.

not sure how to do it by gdb.
But you can declare global variable like:
bool call_a = false;
and when b calling a
call_a = true;
a();
and set call_a to false when other function call a() or after your breakpoint
then use condition break-point
break [line-number] if call_a == true

An easy one for arm is:
Set the breakpoint in the function you are interested.
break a
Attach an gdb command to that breakpoint.
command 1
up 1
if $lr == 0x12345678
echo match \n
down 1
else
echo no match \n
echo $lr \n
down 1
cont
end
end
When ever you arrive in the function a(), the command temporarily pops up one stack frame thus updating the link register. The callers link register value can then be used continue when the caller is not the execution
path you need.
Enjoy.

Related

how to call a func with parameters from an executable using gdb

I need help running a program in an executable using GDB.
I have an executable file name vuln. I do not know the source code as I am doing a CTF. When I analyzed the executable, I found three exciting functions: main, vuln, and flag. Vuln func is vulnerable to BOF attack, but I do not want to go that way. What I am trying to do is run the executable in gdb, and I used print (void) flag(param1, param2) command to directly run flag func as this is supposed to give me a flag; however, it does not work as it says my parameters are incorrect which I am sure are not. I have also found out about the jump function, but I cannot pass any parameters.
So is there any way to run a function from executable with parameters properly or I would have to go through the pain of BOF.
GHIDRA disassembled code of FLAG and VULN Func are below.
void flag(int param_1, int param_2){
char local_50 [64];
FILE *local_10;
local_10 = fopen("flag.txt", "r");
if(local_10 != (FILE *)0x0){
fgets(local_50, 0x40, local_10);
if ((param_1 == -0x21524111) && (param_2 == -0x3f212ff3)){
printf(local_50);
}
return;
}
puts("Hurry up and try in on server side.");
exit(0);
}
void vuln(void)
{
char local_bc [180];
gets(local_bc);
puts(local_bc);
return;
}
print (void) flag(param1, param2)
Not sure what your values of param1 and param2 are, but this seems to work just fine for me:
echo "hello" > flag.txt
gdb -q ./a.out
(gdb) start
Temporary breakpoint 4 at 0x555555555307
Starting program: /tmp/a.out
Thread 1 "a.out" hit Temporary breakpoint 4, 0x0000555555555307 in main ()
(gdb) p (void)flag(-0x21524111, -0x3f212ff3)
hello
$2 = void
(gdb)

I can't use gdb to call a function

For the first time I use gdb to call the function Test(), it shows gdborig.exe has stopped working.
#include <cstdio>
int a=1;
int Test(){
return ++a;
}
int main(){
printf("%d",Test());
return 0;
}
Then I reboot the cmd, this time it just exit without any warning.
Reading symbols from Test... done.
(gdb) b 7
Breakpoint 1 at Ox401573: file Test.cpp, line 7.
(gdb) r
Starting program: C:\Users\He\Desktop\Test.exe
[New Thread 12420. Ox41ec]
[New Thread 12420. Ox2c68]
Thread 1 hit Breakpoint 1, main () at Test.cpp:7
7 printf("%d", Test()) ;
(gdb) call Test()
The gdb version is gdb-8.1

What is clang++ option so that inside GDB I can use std::cout as function parameter

I first asked the question here. Now I encounter the same problem when using clang, hence ask again.
I tried both clang++ 3.8 and 3.9, the command options are "-g -O0".
The gdb version is 7.11.1-0ubuntu1~16.04.
Here is the code:
#include <iostream>
using namespace std;
class D
{
int n;
public:
D(int _n):n(_n){}
void dump(ostream &os);
};
void
D::dump(ostream &os)
{
os << "n=" << n << std::endl;
}
int main() {
D d(200);
std::cout << "hello" << std::endl;
return 0;
}
When it runs to "return 0", call command fails:
(gdb) call d.dump(std::cout)
A syntax error in expression, near `)'.
The same code and same gdb command work fine when compiled with g++ with same option.
Is there a workaround?
It might be because of a verison problem . The program is working fine. I executed it
~/c++practise> g++ stackoverflow1.cpp
~/c++practise> ./a.out
hello
~/c++practise> gdb --version
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-90.el6)
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17)
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b std::cout
"std::cout" is not a function
(gdb) b D::dump(ostream &os)
Breakpoint 1 at 0x400865: file stackoverflow1.cpp, line 15.
(gdb) b main
Breakpoint 2 at 0x4008a2: file stackoverflow1.cpp, line 19.
(gdb) run
Starting program: /home/e1211797/c++practise/outputtrail
Breakpoint 2, main () at stackoverflow1.cpp:19
19 D d(200);
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.x86_64 libgcc-4.4.7-17.el6.x86_64 libstdc++-4.4.7-17.el6.x86_64
(gdb) s
D::D (this=0x7fffffffe0a0, _n=200) at stackoverflow1.cpp:8
8 D(int _n):n(_n){}
(gdb) s
main () at stackoverflow1.cpp:21
21 std::cout << "hello" << std::endl;
(gdb) s
hello
22 return 0;
(gdb) s
23 }
(gdb) s
0x0000003788c1ed1d in __libc_start_main () from /lib64/libc.so.6
(gdb) s
Single stepping until exit from function __libc_start_main,
which has no line number information.
Program exited normally.
(gdb)

what is the command in GDB to step into the next function in the flow?

I am running GDB. I donot wish to use "s" command and step into the next line.
I directly want to jump to the starting line of the next function in the code flow.
And I havent put any breakpoint ( because I dont know which is the next function to be hit ).
Is there any command to do so ?
Edit:
Sorry. I did not ask my question clearly.
I will give 1 example.
line#1 int function(int a)
line#2 {
line#3 int b;
line#4 b = 10;
line#5 b = b + a;
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
...... ...
line#1000 if (10 == b)
line#1001 {
line#1002 func1();
line#1003 } else
line#1004 {
line#1005 func2();
line#1006 }
line#1007 } // function(int a);
...... ...
...... ...
...... ...
line#2000 void func1()
line#2001 {
line#2002 printf("hello\n");
line#2003 }
line#2004 void func2()
line#2005 {
line#2006 printf("hi\n");
line#2007 }
Now, my control is currently at line#4.
I donot know if func1 will be called, or func2 will be called.
I have not put any breakpoint in func1 or func2.
Since function() is a big function, I donot want to use "step" command to reach either func1 or func2.
In this case, consider value of "a" is 0.
Hence func1() will be called.
Is there any command to directly jump from line#4 to line#2000 without putting any breakpoint ?
So, any command to directly jump to next function to be hit in the code flow ?
Thank you!
If your program sets up the frame base pointer $bp upon entry to a function, you can simply watch it, then continue, and execution will stop just after entry to another function. (This will also stop execution when a function returns.)
Note that some compilers don't emit code that uses a frame base pointer at all, and some may choose not to update the pointer in functions in which there aren't any local variables.
$ gdb -q args
(gdb) list
1 main(int argc, char **argv)
2 {
3 for(int i=0; i<argc; i++)
4 printf("arg %d is %s\n", i, argv[i]);
5 }
(gdb) start
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdfa8) at args.c:3
3 for(int i=0; i<argc; i++)
(gdb) watch $bp
Watchpoint 2: $bp
(gdb) c
Continuing.
Watchpoint 2: $bp
Old value = -8608
New value = -8880
0x0000000000453e24 in vfprintf ()
(gdb) bt
#0 0x0000000000453e24 in vfprintf ()
#1 0x000000000040f3d6 in printf ()
#2 0x00000000004009f1 in main (argc=1, argv=0x7fffffffdfa8) at args.c:4
There is no built-in command to do this in gdb.
If you wanted to implement it, you could probably do so in Python. The idea would be to record the current frame, then invoke step repeatedly until the current frame changes. At that point you know the inferior has either called a function or returned from the current function.

Is there any way to set a breakpoint in gdb that is conditional on the call stack?

I am debugging C++ in gdb 7.1 on Linux.
I have a function a() that is called in many places in the code. I want to set a breakpoint in it, but only if it was called from b(). Is there any way to do it?
Is there any way to do it only if b() was called from c(), and so on ad infinitum?
Update: There is now a better answer to this question: use GDB _is_caller convenience function.
The need you describe comes up quite often, usually in the context of some_utility_fn being called a lot, but you only are interested in the call which comes from some_other_fn.
You could probably script this entire interaction using the new embedded Python support in GDB from CVS trunk.
Without Python, you are limited in what you can do, but the usual technique is to have a disabled breakpoint on a(), and enable it from a command, attached to a breakpoint on b().
Here is an example:
int a(int x)
{
return x + 1;
}
int b()
{
return a(1);
}
int call_a_lots()
{
int i, sum = 0;
for (i = 0; i < 100; i++)
sum += a(i);
}
int main()
{
call_a_lots();
return b();
}
gcc -g t.c
gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) break a
Breakpoint 1 at 0x4004cb: file t.c, line 3.
(gdb) disable 1
(gdb) break b
Breakpoint 2 at 0x4004d7: file t.c, line 8.
(gdb) command 2
>silent
>enable 1
>continue
>end
(gdb) run
Breakpoint 1, a (x=1) at t.c:3
3 return x + 1;
(gdb) bt
#0 a (x=1) at t.c:3
#1 0x00000000004004e1 in b () at t.c:8
#2 0x000000000040052c in main () at t.c:21
(gdb) q
Voila: we've stopped on a() called from b(), ignoring previous 100 calls to a().
gdb can handle this directly now without any need for Python. Just do this:
b a if $_caller_is("b")
I have tested this on gdb 7.6 that is already available but it does not work on gdb 7.2 and probably on gdb 7.1:
So this is main.cpp:
int a()
{
int p = 0;
p = p +1;
return p;
}
int b()
{
return a();
}
int c()
{
return a();
}
int main()
{
c();
b();
a();
return 0;
}
Then g++ -g main.cpp
This is my_check.py:
class MyBreakpoint (gdb.Breakpoint):
def stop (self):
if gdb.selected_frame().older().name()=="b":
gdb.execute("bt")
return True
else:
return False
MyBreakpoint("a")
And this is how it works:
4>gdb -q -x my_check.py ./a.out
Reading symbols from /home/a.out...done.
Breakpoint 1 at 0x400540: file main.cpp, line 3.
(gdb) r
Starting program: /home/a.out
#0 a () at main.cpp:3
#1 0x0000000000400559 in b () at main.cpp:10
#2 0x0000000000400574 in main () at main.cpp:21
Breakpoint 1, a () at main.cpp:3
3 int p = 0;
(gdb) c
Continuing.
[Inferior 1 (process 16739) exited normally]
(gdb) quit
A simpler solution than Python scripting is using a temporary breakpoint.
It looks like this:
b ParentFunction
command 1
tb FunctionImInterestedIn
c
end
Every time you break in ParentFunction, you'll set a one-time breakpoint on the function you're actually interested in, then continue running (presumably until you hit that breakpoint).
Since you'll break exactly once on FunctionImInterestedIn, this won't work if FunctionImInterestedIn is called multiple times in the context of ParentFunction and you want to break on each invocation.
not sure how to do it by gdb.
But you can declare global variable like:
bool call_a = false;
and when b calling a
call_a = true;
a();
and set call_a to false when other function call a() or after your breakpoint
then use condition break-point
break [line-number] if call_a == true
An easy one for arm is:
Set the breakpoint in the function you are interested.
break a
Attach an gdb command to that breakpoint.
command 1
up 1
if $lr == 0x12345678
echo match \n
down 1
else
echo no match \n
echo $lr \n
down 1
cont
end
end
When ever you arrive in the function a(), the command temporarily pops up one stack frame thus updating the link register. The callers link register value can then be used continue when the caller is not the execution
path you need.
Enjoy.