For example, with:
#include <functional>
#include <iostream>
int myfunc(int i){ return i + 1; }
int main() {
std::function<int(int)> f = myfunc;
int i = f(1);
std::cout << i << std::endl;
}
compiled with:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
if I try to do a step
into the call f(1)
, then it first leads me in to C++ standard library code, and I either have to think really hard and do the right next
/step
sequence, or be dumb and hit step
17 times before reaching the actual myfunc
call.
Is there an easier way to go about this, maybe with some existing GDB/Python script?
This was basically done by Microsoft people for Visual Studio as mentioned at: https://devblogs.microsoft.com/cppblog/improving-the-debugging-experience-for-stdfunction/
I like it that is is possible to step into the stdlibc++ by default in Ubuntu and have already used it before, but it would be awesome if GDB could step into std::function
user code by default, and have some other mechanism to go into libstdc++ for this specific case.
I'm tempted to go a bit cheeky and just use the following Python GDB script that repeats a command n times: gdb - perform a command n times which allows me to do:
repeat-cmd 17 s
Related: QtCreator debugger: step into std::function
Tested in Ubuntu 18.04, GDB 8.1, GCC 7.4.
To execute one line of code, type "step" or "s". If the line to be executed is a function call, gdb will step into that function and start executing its code one line at a time. If you want to execute the entire function with one keypress, type "next" or "n".
To call a function in the program, GDB has to temporarily modify the state of the inferior. This has potentially undesired side effects. Also, having GDB call nested functions is likely to be erroneous and may even crash the program being debugged.
The first thing which will not work in your use case is
gdb skip -gfile bits/*.h
As you already mentioned, this will skip also over your code which was called from within the std library.
Next idea: Skipping over functions with "known name". As we have typically std::
in front of the function name a used the following .gdbinit
. It looks much better:
sys.path.insert(0, '/usr/share/gcc-9/python/')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
import gdb
import re
def stop_handler(event):
frame_name = gdb.selected_frame().name();
if re.search("(operator new.*)|(^__gnu_cxx::.*)|(^std::.*)", frame_name) != None:
gdb.execute("step")
gdb.events.stop.connect(stop_handler)
end
I searched now a while to find something to get the current file/line-number combination into python but did not find anything. Is there any python access to the current file name and line number? If so, this will be much simpler in this case. Would be nice if someone can add some info's here!
Remark: in ddd that will work not very well, as an internal step from python will not be recognized by the gui. So the green arrow stays on the last stepped line and not the current one. If someone knows also a trick in such a case, any help is welcome!
UPDATE:
If you use the following as .gdbinit
python
import sys
sys.path.insert(0, '/usr/share/gcc-9/python/')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
import gdb
import re
def stop_handler(event):
sal = gdb.selected_frame().find_sal()
if sal == None:
gdb.execute("step")
else:
symtab = sal.symtab;
if symtab == None:
gdb.execute("step")
else:
file_name = symtab.fullname();
if re.search("(.*bits.*)", file_name ) != None:
gdb.execute("step")
gdb.events.stop.connect(stop_handler)
end
Everything works perfectly on my pc. As an additional hint: If using ddd
, you can open the backtrace window and then the green arrow will follow also the python internal gdb steps. That works perfectly for me! Thanks for the question! :-)
Maybe the regexp can be updated to fit for filtering more external libs or to be more selective.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With