GDB call function

You can call a function of the debugged inferior in GDB CLI. Suppose you have a program:

#include <stdio.h>

void sayhi()
{
    printf("hi\n");
}

int main()
{
    printf("hello world\n");
    sayhi();
    return 0;
}

You build it with the following command:

gcc -g -O0 -o test.exe test.cpp

Now you can debug test.exe with gdb:

gdb test.exe

(gdb) br main
Breakpoint 1 at 0x401433: file test.cpp, line 10.
(gdb) run
Starting program: .\test.exe
[New Thread 1712.0xa8c]

Breakpoint 1, main () at test.cpp:10
10          printf("hello world\n");
(gdb) p sayhi()
hi
$1 = void
(gdb)

When you start to run the program and stop at some break-point, you can run the function provided by the inferior using the p command or the call command. GDB will create a frame on stack then call that function. Of course, most functions in the program you are debugging won’t return a valid result, or even crash because they are not called in  right context. But some simple functions such as our sayhi function can work properly. Sometimes(e.g., a weak alias of function), you need to specify the type(prototype) of the function to get the right result. For example, the following call to the pow function does not display the right result:

(gdb) p pow(2,2)
$2 = 1072693280

You should use instead:

(gdb) p ((double(*)(double,double))pow)(2.,2.)
$6 = 4

First, the type of the symbol pow is specified as (double(*)(double,double)), which means pow is a function pointer, the function takes two double parameters and returns double value. Note that you must include the type in brackets. Second, use another pair of brackets to enclose pow and call it providing the actual parameters.

If you do not have the source code of debugged program, you can find interested function names using the nm command:

nm .\test.exe|findstr "sayhi"
00401410 T __Z5sayhiv

The callable functions have a “T” prefixed and their names are mangled. 00401410 is the address of  function. The call command actually calls the function at address 0x00401410. You can jump to that function instead of calling it.

(gdb) jump sayhi
Continuing at 0x401416.
hi
[New Thread 11932.0x2050]
[Inferior 1 (process 11932) exited normally]
(gdb)

Of course, the result is the crashing of the inferior because jump command does not prepare a frame for that function, the returning of the function will corrupt the stack.

If Python scripting is supported in your GDB, you can use the python api to evaluate a function:

python gdb.parse_and_eval("((void(*)())sayhi)()")

Note that you may need to specify the type of the function, otherwise(like the following), you may get the error:

python gdb.parse_and_eval("sayhi()")

gdb.error: 'sayhi()' has unknown return type; cast the call to its declared return type
Error while executing Python code.

You should not use a semicolon after the function calling because gdb parse_and_eval requires an expression not a statement.

You can also use the python API lookup_symbol to get the function then call it:

(gdb) python (gdb.lookup_symbol('sayhi')[0].value())()
warning: hi

(gdb)

 

 

If you like my content, please consider buying me a coffee. Buy me a coffeeBuy me a coffee Thank you for your support!

Leave a Reply