Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Creator and other tools
  4. Creator debugging and forcing step over certain functions
Forum Updated to NodeBB v4.3 + New Features

Creator debugging and forcing step over certain functions

Scheduled Pinned Locked Moved Unsolved Qt Creator and other tools
13 Posts 4 Posters 300 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote last edited by
    #1

    Using Creator 13, gdb 15, gcc 13.

    Compiling for debug. Now that I am doing heavy debugging stepping I can no longer tolerate Creator debugger's Step Into stepping into every trivial function no matter how I try to make it step over certain ones. For example, simple getter's defined in a .h file like:

    Emulator *emulator() const { return g_emulator; }
    ProcessorModel *processorModel() const { return emulator()->processorModel(); }
    

    When I come to a line like processorModel()->someMethod() and use Creator Step Into, because I do want to step into someMethod(), I want some way to "mark" emulator() and processorModel() as "always step over never into".

    • I have kept them in a .h file, they are private and only used in the corresponding .cpp, so we don't have to worry about them being used elsewhere.
    • I have tried setting compiler debug flags to some kind of -g -O<level>, no -O level I could find prevented the getters being stepped into.
    • I have tried marking them inline and even __attribute__((always_inline)) inline.
    • Doing a Step Over the whole statement instead is not what I want: my finger/mouse may be repeatedly clicking the Step Into, I don't want to have to stop and examine every statement before pressing, and besides I often want to step into other stuff in the statement.

    None of these alters the always-step-into behaviour, and so far I have not been able to find any way. IIRC, MSVC/debugger allowed this by marking a function with something like [[debug_step_over]] or equivalent.

    Can anyone suggest something? Without this simple but vital facility, whether in gcc, gdb or Creator, debug stepping is a painful experience....

    1 Reply Last reply
    0
    • aha_1980A Offline
      aha_1980A Offline
      aha_1980
      Lifetime Qt Champion
      wrote last edited by
      #2

      @JonB I currently only find a related suggestion for Creator: https://qt-project.atlassian.net/browse/QTCREATORBUG-21420 (you might want to comment and vote there); but I'm sure I have seen some discussion about your problem somewhere (I'm not sure about the outcome though)

      Qt has to stay free or it will die.

      1 Reply Last reply
      0
      • aha_1980A Offline
        aha_1980A Offline
        aha_1980
        Lifetime Qt Champion
        wrote last edited by
        #3

        It seems like https://qt-project.atlassian.net/browse/QTCREATORBUG-31599 is exactly your problem.

        Qt has to stay free or it will die.

        JonBJ 1 Reply Last reply
        0
        • aha_1980A aha_1980

          It seems like https://qt-project.atlassian.net/browse/QTCREATORBUG-31599 is exactly your problem.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote last edited by
          #4

          @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 mark foo() 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 -g compiler 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 :(

          1 Reply Last reply
          0
          • aha_1980A Offline
            aha_1980A Offline
            aha_1980
            Lifetime Qt Champion
            wrote last edited by
            #5

            @JonB I've investigated a bit more, and if you are using gdb there is a solution: Just add skip function foo in Edit > Preferences > Debugger > GDB > Additional Startup Commands. I tested that with skip function QString::QString and voilà: you no longer land in one of the QString constructors.

            Qt has to stay free or it will die.

            cristian-adamC JonBJ 2 Replies Last reply
            1
            • aha_1980A aha_1980

              @JonB I've investigated a bit more, and if you are using gdb there is a solution: Just add skip function foo in Edit > Preferences > Debugger > GDB > Additional Startup Commands. I tested that with skip function QString::QString and voilà: you no longer land in one of the QString constructors.

              cristian-adamC Offline
              cristian-adamC Offline
              cristian-adam
              wrote last edited by
              #6

              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 .gdbinit file with all the skip function xyz.

              Shouldn't be hard to vibe code, right? 😅

              cristian-adamC JonBJ 2 Replies Last reply
              1
              • aha_1980A Offline
                aha_1980A Offline
                aha_1980
                Lifetime Qt Champion
                wrote last edited by
                #7

                @cristian-adam: A python script called from External Tools would already suffice ;)

                Qt has to stay free or it will die.

                1 Reply Last reply
                0
                • cristian-adamC cristian-adam

                  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 .gdbinit file with all the skip function xyz.

                  Shouldn't be hard to vibe code, right? 😅

                  cristian-adamC Offline
                  cristian-adamC Offline
                  cristian-adam
                  wrote last edited by
                  #8

                  It looks like Visual Studio has something for just my code where you could customize the stepping behavior for certain functions.

                  https://learn.microsoft.com/en-us/visualstudio/debugger/just-my-code?view=visualstudio#additional-information-on-natstepfilter-and-natjmc-files

                  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 False
                  

                  This could be implemented for all debuggers. It could be the natjmc format, or something similar. And this is way easier to vibe code!

                  JonBJ 1 Reply Last reply
                  0
                  • aha_1980A aha_1980

                    @JonB I've investigated a bit more, and if you are using gdb there is a solution: Just add skip function foo in Edit > Preferences > Debugger > GDB > Additional Startup Commands. I tested that with skip function QString::QString and voilà: you no longer land in one of the QString constructors.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote last edited by
                    #9

                    @aha_1980

                    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::QString but won't be usable when I have any number of separate projects of my own.

                    1 Reply Last reply
                    0
                    • cristian-adamC cristian-adam

                      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 .gdbinit file with all the skip function xyz.

                      Shouldn't be hard to vibe code, right? 😅

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote last edited by JonB
                      #10

                      @cristian-adam
                      Again, .gdbinit is 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?

                      1 Reply Last reply
                      0
                      • cristian-adamC cristian-adam

                        It looks like Visual Studio has something for just my code where you could customize the stepping behavior for certain functions.

                        https://learn.microsoft.com/en-us/visualstudio/debugger/just-my-code?view=visualstudio#additional-information-on-natstepfilter-and-natjmc-files

                        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 False
                        

                        This could be implemented for all debuggers. It could be the natjmc format, or something similar. And this is way easier to vibe code!

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote last edited by JonB
                        #11

                        @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 go

                        getterInClass1()->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?

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          SimonSchroeder
                          wrote last edited by
                          #12

                          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.

                          1 Reply Last reply
                          0
                          • JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote last edited by JonB
                            #13

                            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?

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved