Creator debugging and forcing step over certain functions
-
It seems like https://qt-project.atlassian.net/browse/QTCREATORBUG-31599 is exactly your problem.
@aha_1980
Yes and no.I am not asking for/seeking as much as those two. They are requesting "skipping (one or more) function calls which are in an expression whose value is passed to another function". That is pretty advanced and not what I have seen offered elsewhere even with MS stuff. I am asking only to mark a single function as itself being "step over instead of into". Nothing about how/where it is called from or whether it is passed as a parameter to something else, which is much more complicated.
I wrote an example to show my "real world", and that there will be hundreds of such functions, such as every simple getter. Let's take no more than:
int foo() const { return bar; }and calling code just goes
int something = foo();. So we don't have other functions involved or passing as parameters etc. I just want to markfoo()as "no-step-into", so that when I happen to press Step Into in the caller it executes with being stepped into (i.e. like Step Over) and then we are sitting on the next statement in the caller again. Just like if the statement were not a function call. This also happens automatically (apparently) in gdb with step if the function called does not have debugging line information. But I have not found a way to switch that off when compiling for debug across a statement --- e.g. there is no pragma for "switch off-gcompiler option.This was easy when I used MS stuff. It may have been C# I recall rather than C++ bit you marked a function with something like
[debugger-step-through]. Did that on hundreds of functions like simple getters and it's horrible now not to be able to do it :( -
@JonB I've investigated a bit more, and if you are using gdb there is a solution: Just add
skip function fooin Edit > Preferences > Debugger > GDB > Additional Startup Commands. I tested that withskip function QString::QStringand voilà: you no longer land in one of the QString constructors. -
@JonB I've investigated a bit more, and if you are using gdb there is a solution: Just add
skip function fooin Edit > Preferences > Debugger > GDB > Additional Startup Commands. I tested that withskip function QString::QStringand voilà: you no longer land in one of the QString constructors.Skipping Over Functions and Files is the thing for
gdb.All you have to do do, is have a clang plugin that would go over all of the
[[debug_step_over]]annotated functions in the code, and then generate a.gdbinitfile with all theskip function xyz.Shouldn't be hard to vibe code, right? 😅
-
@cristian-adam: A python script called from External Tools would already suffice ;)
-
Skipping Over Functions and Files is the thing for
gdb.All you have to do do, is have a clang plugin that would go over all of the
[[debug_step_over]]annotated functions in the code, and then generate a.gdbinitfile with all theskip function xyz.Shouldn't be hard to vibe code, right? 😅
It looks like Visual Studio has something for just my code where you could customize the stepping behavior for certain functions.
Qt Creator does have a Python helpers debugging layer. Having something there that would skip functions would be helpful.
There is also a precedent, for Android we auto continue debugging when hitting certain functions https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/share/qtcreator/debugger/lldbbridge.py#n1548
def wantAutoContinue(self, frame): if self.platform_ != 'remote-android': return False funcname = frame.GetFunctionName() if funcname: if funcname.startswith('java.'): return True if funcname.startswith('android.'): return True if funcname.startswith('com.android.'): return True if funcname.startswith('jdk.'): return True if funcname.startswith('sun.'): return True module = frame.GetModule() filespec = module.GetPlatformFileSpec() # Not GetFileSpec filename = filespec.GetFilename() if filename and filename.endswith('libart.so'): return True if funcname == None and not frame.line_entry.file.IsValid() and filename == None: return True return FalseThis could be implemented for all debuggers. It could be the
natjmcformat, or something similar. And this is way easier to vibe code! -
@JonB I've investigated a bit more, and if you are using gdb there is a solution: Just add
skip function fooin Edit > Preferences > Debugger > GDB > Additional Startup Commands. I tested that withskip function QString::QStringand voilà: you no longer land in one of the QString constructors.Just add skip function foo in Edit > Preferences > Debugger > GDB > Additional Startup Commands
Unfortunately I add and delete and rename getters/setters and other one-liners all the time. I need a solution which just works from code, not requires to manually maintain a list.
While we are here: isn't Edit > Preferences > Debugger > GDB > Additional Startup Commands global rather than per project? If so it's all very well with your
QString::QStringbut won't be usable when I have any number of separate projects of my own. -
Skipping Over Functions and Files is the thing for
gdb.All you have to do do, is have a clang plugin that would go over all of the
[[debug_step_over]]annotated functions in the code, and then generate a.gdbinitfile with all theskip function xyz.Shouldn't be hard to vibe code, right? 😅
@cristian-adam
Again,.gdbinitis in $HOME, right? Which would make these global, when I only want them to apply to whatever project I work on, sometimes more than one at a time. I like proper, clean solutions, not hacks! :)I don't know about clang, plugins or "vibe coding". I am old :) :( Sounds like teaching an old dog new tricks? Although we know it's not parsing correctly, it might be simpler to use grep/sed/perl or whatever if I could put
[[debug_step_over]]somewhere near the function name. I think gcc uses "attributes-something" rather than[[? Can you invent any attribute name you like without compiler borking when it doesn't know what it is?I also don't know whether Creator debugger UI does anything of its own? Or, if one were to want this behaviour is it down to finding something in underlying gdb which offers the desired facility and Creator UI is really just a thin wrapper round that?
-
It looks like Visual Studio has something for just my code where you could customize the stepping behavior for certain functions.
Qt Creator does have a Python helpers debugging layer. Having something there that would skip functions would be helpful.
There is also a precedent, for Android we auto continue debugging when hitting certain functions https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/share/qtcreator/debugger/lldbbridge.py#n1548
def wantAutoContinue(self, frame): if self.platform_ != 'remote-android': return False funcname = frame.GetFunctionName() if funcname: if funcname.startswith('java.'): return True if funcname.startswith('android.'): return True if funcname.startswith('com.android.'): return True if funcname.startswith('jdk.'): return True if funcname.startswith('sun.'): return True module = frame.GetModule() filespec = module.GetPlatformFileSpec() # Not GetFileSpec filename = filespec.GetFilename() if filename and filename.endswith('libart.so'): return True if funcname == None and not frame.line_entry.file.IsValid() and filename == None: return True return FalseThis could be implemented for all debuggers. It could be the
natjmcformat, or something similar. And this is way easier to vibe code!@cristian-adam
I didn't realise this feature seems to be unusual. I did spend years with MSVC/VS so I guess I got accustomed to whatever it has.I have had a quick search, not exhaustive. I find that what I recall was written as
[DebuggerStepThrough] someFunctionDefinition() {}It may be this was for C# and managed code, like the weird C++ they had for that. Maybe it wasn't for plain C++, not sure.
I also see VS has a dedicated setting to auto-"skip over properties/getters/setters". I realise this is not so easy with C++, but it's often all those standard getters/setters we really want to step over. It's this sort of feature which made VS really good. Just saying.
So maybe I was spoiled in C# days with the simple
[DebuggerStepThrough]etc. code annotations and this isn't so common. Surprises me, as it's so basic to debugging experience. I have code which may gogetterInClass1()->getterInClass2()->getterInClass3()->doSomething();When I step into --- coz I'm going to want to see what's in
doSomething()--- it's then about 6 key presses to get into and out of each object getter, real pain. If I just used public variables instead of getters this would be so simple. But you wouldn't want me to do that just for debugging, would you...? I end up doing:Foo *ptr(getterInClass1()->getterInClass2()->getterInClass3()); ptr->doSomething();just so I can step over the first line and then stick to stepping in, but I shouldn't have to do this just for the debugger, should I?
-
My usual workaround is to jump to the function I actually want to step into (in Qt Creator position cursor on function name and hit
F2) and then place a breakpoint inside that function. Then I can do a regular "jump over" instead of "step into" with the debugger. Its ugly because you have to constantly enable/disable breakpoints, but it works for some light debugging. Sometimes it helps making the breakpoint conditional. -
Yes I understand. But that is not convenient when you will want to step into each one because you don't know what you might be looking for. Sequences like e.g.:
getterA()->getterB()->method1(); getterC()->getterD()->method2(); getterA()->getterB()->method3(); etc....are simply a pain in the ass to step into. I know it's "filthy", but I am taking to writing the underlying class member variable (within its class body) instead of going via the getter just to make debugging less painful (coding is for my own purposes, I wouldn't do that in other circumstances).
As I wrote, when I did C# I know I found debugging/VS much more pleasant. I had not appreciated that e.g.
[DebuggerStepThrough] someFunctionDefinition() {}was C# only. Obviously C# combines debugger directives with code because it can do what it likes. I had assumed in C++ I would be able to "annotate" with some compiler-debugger attribute to achieve similar. It looks like they have a strict rule that any attributes must be to do with compilation only, not debugging, as gcc and gdb are treated as quite separate entities. I guess I need gcc to be willing to put in some directives/hints for debugging but that is not going to happen?