finding line number of end of a function - c++

I am trying to automate some debug by printing inputs and outputs of a function via GDB, when that function hits. To enable setting breakpoints at these places, I am doing the following.
I am working with templates, and rbreak :. does not hit the breakpoints at the functions in my file. So i extract line numbers of functions from the executable as follows.
With the executable, extract the linenumber of start of a function;
nm a.out | grep "className" | grep "functionName" | grep " t " | addr2line -e a.out -f | grep "cpp" | uniq
-> this outputs the filename:linenumber
add these contents to a .gdb file with a "b prefix"
Query - how can we extract the line number of a end of a function from the executable ?
With this info, I can add it to the GDB script, the final script would
look something like below. this script would be loaded into GDB before
the execution of the program.
b filepath:<startline of function>
commands
print input1 input2 etc
continue
end
b filepath:<endline of function>
commands
print output1 output2 etc
continue
end
It remains to find only the end line of a given function belonging to a class/file, given the executable and start line of the function
I also considered using GDBs finish command but the control is back to the caller already.
it would be easy to have the prints within the called function instead of the caller, so that we can monitor input/outputs of every call of the function.
This will simplify my debug to a large extent.
Any suggestion/comments is highly appreciated.
Thanks a lot in advance !!

First, notice that template functions are not functions, but actually recipes. When you use a template the compiler generates a function from the template.
If you want to use the break command then you need the full function name. For instance, the template below
template <typename T>
inline T doubleInput(const T& x) {
return 2 * x;
}
will become the function doubleInput<int> when you pass an int, doubleInput<double> when you pass a double, etc. You need the whole name including the <type> part to add a breakpoint with the break command and even in that case it will only stop in that particular case of the template.
But the rbreak command does work with templates. If you write in gdb rbreak doubleInput* then a breakpoint will be added in all existing specializations of the template.
See the answer in this question.
I don't know if gdb nowadays has the feature to add a breakpoint in the return of a function, but answers in the nine years old question provide some possibilities, including a custom python command to find and add a breakpoint to the retq instructions or using reverse debugging. I haven't tried these options.

Related

Obtain a trace of all function invocations? [duplicate]

How can we list all the functions being called in an application. I tried using GDB but its backtrace list only upto the main function call.
I need deeper list i.e list of all the functions being called by the main function and the function being called from these called functions and so on.
Is there a way to get this in gdb? Or could you give me suggestions on how to get this?
How can we list all the functions being called in an application
For any realistically sized application, this list will have thousands of entries, which will probably make it useless.
You can find out all functions defined (but not necessarily called) in an application with the nm command, e.g.
nm /path/to/a.out | egrep ' [TW] '
You can also use GDB to set a breakpoint on each function:
(gdb) set logging on # collect trace in gdb.txt
(gdb) set confirm off # you wouldn't want to confirm every one of them
(gdb) rbreak . # set a breakpoint on each function
Once you continue, you'll hit a breakpoint for each function called. Use the disable and continue commands to move forward. I don't believe there is an easy way to automate that, unless you want to use Python scripting.
Already mentioned gprof is another good option.
You want a call graph. The tool that you want to use is not gdb, it's gprof. You compile your program with -pg and then run it. When it runs a file gmon.out will be produced. You then process this file with gprof and enjoy the output.
record function-call-history
https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html
This should be a great hardware accelerated possibility if you are one of the few people (2015) with a CPU that supports Intel Processor Tracing (Intel PT, intel_pt in /proc/cpuinfo).
GDB docs claim that it can produce output like:
(gdb) list 1, 10
1 void foo (void)
2 {
3 }
4
5 void bar (void)
6 {
7 ...
8 foo ();
9 ...
10 }
(gdb) record function-call-history /ilc
1 bar inst 1,4 at foo.c:6,8
2 foo inst 5,10 at foo.c:2,3
3 bar inst 11,13 at foo.c:9,10
Before using it you need to run:
start
record btrace
which is where a non capable CPU fails with:
Target does not support branch tracing.
CPU support is further discussed at: How to run record instruction-history and function-call-history in GDB?
Related threads:
how to trace function call in C?
Is there a compiler feature to inject custom function entry and exit code?
For embedded, you also consider JTAG and supporting hardware like ARM's DSTREAM, but x86 support does not seem very good: debugging x86 kernel using a hardware debugger
This question might need clarification to decide between what are currently 2 answers. Depends on what you need:
1) You need to know how many times each function is being called in straight list/graph format of functions matched with # of calls. This could lead to ambiguous/inconclusive results if your code is not procedural (i.e. functions calling other functions in a branch out structure without ambiguity of what is calling what). This is basic gprof functionality which requires recompilation with -pg flag.
2) You need a list of functions in the order in which they were called, this depends on your program which is the best/feasible option:
a) IF your program runs and terminates without runtime errors you can use gprof for this purpose.
b) ELSE option above using dbg with logging and break points is the left over option that I learned upon reading this.
3) You need to know not only the order but, for example, the function arguments for each call as well. My current work is simulations in physics of particle transport, so this would ABSOLUTELY be useful in tracking down where anomalous results are coming from... i.e. when the arguments getting passed around stop making sense. I imagine one way to do this is would be a variation on what Employed Russian did except using the following:
(gdb) info args
Logging the results of this command with every break point (set at every function call) gives the args of the current function.
With gdb, if you can find the most child function, you can list its all ancestors like this:
gdb <your-binary>
(gdb) b theMostChildFunction ## put breakpoint on the desired function
(gdb) r ## run the program
(gdb) bt ## backtrace starting from the breakpoint
Otherwise, on linux, you can use perf tool to trace programs and their function calls. The advantage of this, it is tracing all processes including child processes and also it shows usage percentages of the functions in the program.
You can install perf like this:
sudo apt install linux-tools-generic
sudo apt install linux-cloud-tools-generic
Before using perf you may also need to remove some kernel restrictions temporarily:
sudo sh -c 'echo 0 >/proc/sys/kernel/kptr_restrict'
sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
sudo sh -c 'echo 0 >/proc/sys/kernel/yama/ptrace_scope'
After this, you can run your program binary with perf like this:
perf record -g -s -a <your-binary-and-its-flags>
Then either you can look the output on terminal like this:
perf report
or on text file like this:
perf report -i perf.data > output.txt
vim output.txt
when you are recording the function calls with perf also you may want to filter kernel calls with --all-user flag:
perf record -g -s -a --all-user <your-binary-and-its-flags>
For further information you can look here: https://perf.wiki.kernel.org/index.php/Tutorial

Is it possible to register commands to a breakpoint from within an external file in GDB?

GDB allows registering a set of commands to a specific breakpoint via commands NUM syntax. I need to register the set of commands for a specific breakpoint via an external file, by using a syntax something like the following:
commands ./main.c:18
silent
print buffer[0]
cont
end
commands ./io.c:29
silent
printf "Hello world %i\n", myvar1
cont
end
The commands path/to/file:XX syntax is made up by me. Because the NUM in commands NUM syntax requires exactly the breakpoint's runtime ID number (assigned by GDB), I can not use a deterministic syntax for that purpose.
I'm currently registering breakpoints via a text file with such a content:
break ./main.c:18
break ./io.c:29
and then issuing source breakpoints.txt command inside GDB. It seems that there is no way to register commands at the same time while registering a breakpoint:
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point. Accepted values are -probe' (for a generic, automatically guessed probe type), -probe-stap' (for a SystemTap probe) or
`-probe-dtrace' (for a DTrace probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame. This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if their
conditions are different.
Question
Is there any easy way to set some predetermined commands for a predetermined breakpoint from within a file?
If not, is there any equivalent way to pass the (gdb) info breakpoints output to a file or a program while pipe is not available in GDB (version 5.3)? Currently I'm trying a workaround by using logging feature for that purpose:
set logging file /tmp/breakpoints
set logging on
info breakpoints
set logging off
Is there any easy way to set some predetermined commands for a predetermined breakpoint from within a file?
Yes: if you use commands without NUM, the commands will apply to the last breakpoint set. So you want something like:
break main.c:18
commands
silent
print buffer[0]
cont
end

Step into function call in gdb but not calls for parameters

I would like to step into the function GDB is currently at, but not into the functions that are called to prepare the parameters for the call.
Is there a single command in gdb that steps over functions like initial_metadata_flags() and directly into SendInitialMetadata?
void StartCallInternal() {
> single_buf.SendInitialMetadata(&context_->send_initial_metadata_,
context_->initial_metadata_flags());
}
If there is, I did not see it mentioned here: https://sourceware.org/gdb/onlinedocs/gdb/Continuing-and-Stepping.html
My current workaround is to step, finish, step, finish, until I get to the primary function on that line. But would like something more direct.
There are similar questions asked about Python and Visual Studio, but I haven't found a good answer for gdb.
You can configure functions that you want to skip while stepping:
(gdb) help skip
Ignore a function while stepping.
Usage: skip [FUNCTION-NAME]
skip [FILE-SPEC] [FUNCTION-SPEC]
If no arguments are given, ignore the current function.
FILE-SPEC is one of:
-fi|-file FILE-NAME
-gfi|-gfile GLOB-FILE-PATTERN
FUNCTION-SPEC is one of:
-fu|-function FUNCTION-NAME
-rfu|-rfunction FUNCTION-NAME-REGULAR-EXPRESSION
...

How to do a specific action when ANY Unknown Breakpoint gets Hit in GDB

I have read the following SO question:
Do specific action when certain breakpoint hits in gdb
Here, we use 'command' to decide what to do when the SPECIFIED Breakboint Gets Hit.
My Question is:
Suppose I put Breakpoints on ALL the Functions matching a given pattern:
gdb$rbreak func_
=> 100 Breakpoints (say)
When I execute this Code, I want to do the SAME Action - on hitting Each of these functions.
Hence, I cannot define something like:
command break_point_number
// since I don't know how many breakpoints will be there
Can somebody please suggest me:
How can I do a specific action-set when ANY Breakpoint gets Hit in GDB?
Thanks.
With a new enough version of gdb you can use a range:
(gdb) rbreak whatever
... gdb creates breakpoints N, N+1, ..., M
(gdb) commands N-M
> stuff
> end
I forget exactly when this feature went in.
With an older version of gdb, I'm not sure it can easily be done.
It can be done with difficulty: use set logging to write output to a file, then "info break", then "shell" to run scripts to edit the file into gdb commands, then "source". This is very painful.

List of all function calls made in an application

How can we list all the functions being called in an application. I tried using GDB but its backtrace list only upto the main function call.
I need deeper list i.e list of all the functions being called by the main function and the function being called from these called functions and so on.
Is there a way to get this in gdb? Or could you give me suggestions on how to get this?
How can we list all the functions being called in an application
For any realistically sized application, this list will have thousands of entries, which will probably make it useless.
You can find out all functions defined (but not necessarily called) in an application with the nm command, e.g.
nm /path/to/a.out | egrep ' [TW] '
You can also use GDB to set a breakpoint on each function:
(gdb) set logging on # collect trace in gdb.txt
(gdb) set confirm off # you wouldn't want to confirm every one of them
(gdb) rbreak . # set a breakpoint on each function
Once you continue, you'll hit a breakpoint for each function called. Use the disable and continue commands to move forward. I don't believe there is an easy way to automate that, unless you want to use Python scripting.
Already mentioned gprof is another good option.
You want a call graph. The tool that you want to use is not gdb, it's gprof. You compile your program with -pg and then run it. When it runs a file gmon.out will be produced. You then process this file with gprof and enjoy the output.
record function-call-history
https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html
This should be a great hardware accelerated possibility if you are one of the few people (2015) with a CPU that supports Intel Processor Tracing (Intel PT, intel_pt in /proc/cpuinfo).
GDB docs claim that it can produce output like:
(gdb) list 1, 10
1 void foo (void)
2 {
3 }
4
5 void bar (void)
6 {
7 ...
8 foo ();
9 ...
10 }
(gdb) record function-call-history /ilc
1 bar inst 1,4 at foo.c:6,8
2 foo inst 5,10 at foo.c:2,3
3 bar inst 11,13 at foo.c:9,10
Before using it you need to run:
start
record btrace
which is where a non capable CPU fails with:
Target does not support branch tracing.
CPU support is further discussed at: How to run record instruction-history and function-call-history in GDB?
Related threads:
how to trace function call in C?
Is there a compiler feature to inject custom function entry and exit code?
For embedded, you also consider JTAG and supporting hardware like ARM's DSTREAM, but x86 support does not seem very good: debugging x86 kernel using a hardware debugger
This question might need clarification to decide between what are currently 2 answers. Depends on what you need:
1) You need to know how many times each function is being called in straight list/graph format of functions matched with # of calls. This could lead to ambiguous/inconclusive results if your code is not procedural (i.e. functions calling other functions in a branch out structure without ambiguity of what is calling what). This is basic gprof functionality which requires recompilation with -pg flag.
2) You need a list of functions in the order in which they were called, this depends on your program which is the best/feasible option:
a) IF your program runs and terminates without runtime errors you can use gprof for this purpose.
b) ELSE option above using dbg with logging and break points is the left over option that I learned upon reading this.
3) You need to know not only the order but, for example, the function arguments for each call as well. My current work is simulations in physics of particle transport, so this would ABSOLUTELY be useful in tracking down where anomalous results are coming from... i.e. when the arguments getting passed around stop making sense. I imagine one way to do this is would be a variation on what Employed Russian did except using the following:
(gdb) info args
Logging the results of this command with every break point (set at every function call) gives the args of the current function.
With gdb, if you can find the most child function, you can list its all ancestors like this:
gdb <your-binary>
(gdb) b theMostChildFunction ## put breakpoint on the desired function
(gdb) r ## run the program
(gdb) bt ## backtrace starting from the breakpoint
Otherwise, on linux, you can use perf tool to trace programs and their function calls. The advantage of this, it is tracing all processes including child processes and also it shows usage percentages of the functions in the program.
You can install perf like this:
sudo apt install linux-tools-generic
sudo apt install linux-cloud-tools-generic
Before using perf you may also need to remove some kernel restrictions temporarily:
sudo sh -c 'echo 0 >/proc/sys/kernel/kptr_restrict'
sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
sudo sh -c 'echo 0 >/proc/sys/kernel/yama/ptrace_scope'
After this, you can run your program binary with perf like this:
perf record -g -s -a <your-binary-and-its-flags>
Then either you can look the output on terminal like this:
perf report
or on text file like this:
perf report -i perf.data > output.txt
vim output.txt
when you are recording the function calls with perf also you may want to filter kernel calls with --all-user flag:
perf record -g -s -a --all-user <your-binary-and-its-flags>
For further information you can look here: https://perf.wiki.kernel.org/index.php/Tutorial