0

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.

  1. 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
  1. 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 !!

CutePoison
  • 131
  • 1
  • 6

1 Answers1

0

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.

darcamo
  • 3,294
  • 1
  • 16
  • 27