Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to debug PySide2 silent crashes?
Forum Updated to NodeBB v4.3 + New Features

How to debug PySide2 silent crashes?

Scheduled Pinned Locked Moved Solved Qt for Python
11 Posts 3 Posters 3.5k Views 1 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.
  • D Offline
    D Offline
    deahran
    wrote on 27 Apr 2021, 16:50 last edited by
    #1

    Hello,

    My specifications are:

    Windows 10
    Python==3.6.8
    PySide2==5.15.2

    I have a pretty big closed source application, so it's really hard to create a minimal example. But the general concept is a nodeeditor. I'm trying at the moment to pinpoint the real issue. My application uses QGraphicsView, QGraphicsScene, QGraphicsItem, QGraphicsProxyWidget etc. Crash occasionally happens when i move the mouse around.

    To pinpoint the issue, I have wrapped every function in my application for tracing, used "faultHandler", used sys.settrace and crash seems to happens inside event loop. Only error i get is:

    Windows fatal exception: access violation
    

    The error above is thrown on the line below:

    sys.exit(app.exec_())
    

    I've been reading through the internet for two weeks, tried many things, could not find a solution/practice. I know what i provide is near to nothing but Is there a better way to debug my application?

    J 1 Reply Last reply 27 Apr 2021, 18:38
    0
    • D deahran
      27 Apr 2021, 16:50

      Hello,

      My specifications are:

      Windows 10
      Python==3.6.8
      PySide2==5.15.2

      I have a pretty big closed source application, so it's really hard to create a minimal example. But the general concept is a nodeeditor. I'm trying at the moment to pinpoint the real issue. My application uses QGraphicsView, QGraphicsScene, QGraphicsItem, QGraphicsProxyWidget etc. Crash occasionally happens when i move the mouse around.

      To pinpoint the issue, I have wrapped every function in my application for tracing, used "faultHandler", used sys.settrace and crash seems to happens inside event loop. Only error i get is:

      Windows fatal exception: access violation
      

      The error above is thrown on the line below:

      sys.exit(app.exec_())
      

      I've been reading through the internet for two weeks, tried many things, could not find a solution/practice. I know what i provide is near to nothing but Is there a better way to debug my application?

      J Offline
      J Offline
      JonB
      wrote on 27 Apr 2021, 18:38 last edited by
      #2

      @deahran
      Does your Python debugger's stack trace show anything useful for where in sys.exit(app.exec_()) it crashed?

      D 1 Reply Last reply 28 Apr 2021, 09:00
      0
      • J JonB
        27 Apr 2021, 18:38

        @deahran
        Does your Python debugger's stack trace show anything useful for where in sys.exit(app.exec_()) it crashed?

        D Offline
        D Offline
        deahran
        wrote on 28 Apr 2021, 09:00 last edited by
        #3

        @JonB , thank you for responding. I'm using Windows Command Prompt with the command below, since most IDE's monkey patch sys.traceback:

        python -m -q -X faulthandler main.py
        

        Sometimes application crashes with a traceback with same Windows Fatal Exception, but these are pretty random and inconsistent, sometimes happens inside native Python modules, sometimes in requests.send etc. I believe they are caused by interruption when main thread dies.

        J S 2 Replies Last reply 28 Apr 2021, 09:32
        0
        • D deahran
          28 Apr 2021, 09:00

          @JonB , thank you for responding. I'm using Windows Command Prompt with the command below, since most IDE's monkey patch sys.traceback:

          python -m -q -X faulthandler main.py
          

          Sometimes application crashes with a traceback with same Windows Fatal Exception, but these are pretty random and inconsistent, sometimes happens inside native Python modules, sometimes in requests.send etc. I believe they are caused by interruption when main thread dies.

          J Offline
          J Offline
          JonB
          wrote on 28 Apr 2021, 09:32 last edited by
          #4

          @deahran
          I saw from some other post of yours that you seem to be using PyCharm. I would have run your program in that debugger and examined the stack trace when it "crashes" to see if there is anything useful.

          1 Reply Last reply
          0
          • D deahran
            28 Apr 2021, 09:00

            @JonB , thank you for responding. I'm using Windows Command Prompt with the command below, since most IDE's monkey patch sys.traceback:

            python -m -q -X faulthandler main.py
            

            Sometimes application crashes with a traceback with same Windows Fatal Exception, but these are pretty random and inconsistent, sometimes happens inside native Python modules, sometimes in requests.send etc. I believe they are caused by interruption when main thread dies.

            S Offline
            S Offline
            Shawn Driscoll
            wrote on 28 Apr 2021, 17:26 last edited by
            #5

            @deahran It's kind of tricky to track errors when the program is called main.py.

            Do you have something like this to start your code?:

            class MainWindow(QMainWindow):
                def __init__(self, parent=None):
                QMainWindow.__init__(self, parent)
            .
            .
            .
            
            if __name__ == '__main__':
                app = QApplication(sys.argv)
                mainApp = MainWindow()
                mainApp.show()
                            
                sys.exit(app.exec_())
            
            1 Reply Last reply
            0
            • D Offline
              D Offline
              deahran
              wrote on 28 Apr 2021, 19:55 last edited by
              #6

              @JonB

              Sadly, if i run the application in PyCharm debug mode and the application freezes/crashes, somehow PyCharm can't reach any frame due to internal C errors, which is only shown by faulthandler module, The traceback from faulthandler always and only pinpoints to sys.exit(app.exec_()), where the event loop starts.

              I have been expecting a memory leak, invalid shiboken2 wrappers inside events, infinite looping and could not find any.

              The one issue i was able to pinpoint was if i were to use QWidget.setStyleSheet("...") frequently in a mouseMoveEvent for a QWidget inside QGraphicsScene, it also causes a a lot of silent crashes. Removing that line improved the issue a lot.

              @Shawn-Driscoll

              Thank you for responding. I would love to provide a minimal example. But i can not since the application is closed source and pretty big. I'm preparing a one right now but will take quite some time.

              S 1 Reply Last reply 28 Apr 2021, 20:46
              0
              • D deahran
                28 Apr 2021, 19:55

                @JonB

                Sadly, if i run the application in PyCharm debug mode and the application freezes/crashes, somehow PyCharm can't reach any frame due to internal C errors, which is only shown by faulthandler module, The traceback from faulthandler always and only pinpoints to sys.exit(app.exec_()), where the event loop starts.

                I have been expecting a memory leak, invalid shiboken2 wrappers inside events, infinite looping and could not find any.

                The one issue i was able to pinpoint was if i were to use QWidget.setStyleSheet("...") frequently in a mouseMoveEvent for a QWidget inside QGraphicsScene, it also causes a a lot of silent crashes. Removing that line improved the issue a lot.

                @Shawn-Driscoll

                Thank you for responding. I would love to provide a minimal example. But i can not since the application is closed source and pretty big. I'm preparing a one right now but will take quite some time.

                S Offline
                S Offline
                Shawn Driscoll
                wrote on 28 Apr 2021, 20:46 last edited by
                #7

                @deahran I usually add temporary print functions to my code so that I can see in a terminal console where my program is going and how often. Something like:

                def calc_bitcoin(amount_sold):
                    print('Before.....')
                    value = amount_sold / 0.0
                    print('After!!! Did I make it to this point or not??????')
                
                D 1 Reply Last reply 29 Apr 2021, 07:34
                1
                • S Shawn Driscoll
                  28 Apr 2021, 20:46

                  @deahran I usually add temporary print functions to my code so that I can see in a terminal console where my program is going and how often. Something like:

                  def calc_bitcoin(amount_sold):
                      print('Before.....')
                      value = amount_sold / 0.0
                      print('After!!! Did I make it to this point or not??????')
                  
                  D Offline
                  D Offline
                  deahran
                  wrote on 29 Apr 2021, 07:34 last edited by deahran
                  #8

                  @Shawn-Driscoll i like to hodl :). Jokes aside, i've tried that approach too. Crash seems to happen right after QGraphicsScene.drawBackGround() , QGraphicsView.mouseMoveEvent() or other keyboard-mouse events finish returning. I also examined the outer frame with the function below. When these paint or event methods are called, the outer frame points to my main.py.

                  import sys
                  from itertools import count
                  
                  def stack_size2a(size=2):
                      """Get stack size for caller's frame.
                      """
                      frame = sys._getframe(size)
                  
                      for size in count(size):
                          frame = frame.f_back
                          if not frame:
                              return size
                  

                  Also my drawBackGround function , i always see the function return part before crash:

                  class MyScene(QGraphicsScene):
                  .
                  .
                  .
                    def drawBackground(self, painter, rect):
                         if DEBUG: print("graphics_scene.paint -> entering")
                         super().drawBackground(painter, rect)
                  
                         if DEBUG: print("graphics_scene.paint -> called super")
                         # here we create our grid
                         left = int(math.floor(rect.left()))
                         right = int(math.ceil(rect.right()))
                         top = int(math.floor(rect.top()))
                         bottom = int(math.ceil(rect.bottom()))
                  
                         first_left = left - (left % self.grid_size)
                         first_top = top - (top % self.grid_size)
                  
                         # all lines to be drawn
                         lines_light, lines_dark = [], []
                         for x in range(first_left, right, self.grid_size):
                             if (x % (self.grid_size*self.gridSquares) != 0): lines_light.append(QLine(x, top, x, bottom))
                             else: lines_dark.append(QLine(x, top, x, bottom))
                  
                         for y in range(first_top, bottom, self.grid_size):
                             if (y % (self.grid_size*self.gridSquares) != 0): lines_light.append(QLine(left, y, right, y))
                             else: lines_dark.append(QLine(left, y, right, y))
                  
                         if DEBUG: print("graphics_scene.paint -> lines light:", lines_light)
                         if DEBUG: print("graphics_scene.paint -> lines dark:", lines_dark)
                         
                         # draw the lines
                         painter.setPen(self._pen_yellow) #  self._pen_yellow = QPen("yellow")
                         painter.drawLines(lines_light)
                  
                         painter.setPen(self._pen_black) #  self._pen_black = QPen("black")
                         painter.drawLines(lines_dark)
                         if DEBUG: print("graphics_scene.paint -> lines drawn, function return.")
                  
                  J 1 Reply Last reply 29 Apr 2021, 07:38
                  0
                  • D deahran
                    29 Apr 2021, 07:34

                    @Shawn-Driscoll i like to hodl :). Jokes aside, i've tried that approach too. Crash seems to happen right after QGraphicsScene.drawBackGround() , QGraphicsView.mouseMoveEvent() or other keyboard-mouse events finish returning. I also examined the outer frame with the function below. When these paint or event methods are called, the outer frame points to my main.py.

                    import sys
                    from itertools import count
                    
                    def stack_size2a(size=2):
                        """Get stack size for caller's frame.
                        """
                        frame = sys._getframe(size)
                    
                        for size in count(size):
                            frame = frame.f_back
                            if not frame:
                                return size
                    

                    Also my drawBackGround function , i always see the function return part before crash:

                    class MyScene(QGraphicsScene):
                    .
                    .
                    .
                      def drawBackground(self, painter, rect):
                           if DEBUG: print("graphics_scene.paint -> entering")
                           super().drawBackground(painter, rect)
                    
                           if DEBUG: print("graphics_scene.paint -> called super")
                           # here we create our grid
                           left = int(math.floor(rect.left()))
                           right = int(math.ceil(rect.right()))
                           top = int(math.floor(rect.top()))
                           bottom = int(math.ceil(rect.bottom()))
                    
                           first_left = left - (left % self.grid_size)
                           first_top = top - (top % self.grid_size)
                    
                           # all lines to be drawn
                           lines_light, lines_dark = [], []
                           for x in range(first_left, right, self.grid_size):
                               if (x % (self.grid_size*self.gridSquares) != 0): lines_light.append(QLine(x, top, x, bottom))
                               else: lines_dark.append(QLine(x, top, x, bottom))
                    
                           for y in range(first_top, bottom, self.grid_size):
                               if (y % (self.grid_size*self.gridSquares) != 0): lines_light.append(QLine(left, y, right, y))
                               else: lines_dark.append(QLine(left, y, right, y))
                    
                           if DEBUG: print("graphics_scene.paint -> lines light:", lines_light)
                           if DEBUG: print("graphics_scene.paint -> lines dark:", lines_dark)
                           
                           # draw the lines
                           painter.setPen(self._pen_yellow) #  self._pen_yellow = QPen("yellow")
                           painter.drawLines(lines_light)
                    
                           painter.setPen(self._pen_black) #  self._pen_black = QPen("black")
                           painter.drawLines(lines_dark)
                           if DEBUG: print("graphics_scene.paint -> lines drawn, function return.")
                    
                    J Offline
                    J Offline
                    JonB
                    wrote on 29 Apr 2021, 07:38 last edited by JonB
                    #9

                    @deahran
                    If you think something in your drawBackground() code is causing the crash, keep commenting out lines till it goes away! Or not, if you get down to nothing but calling the base implementation. In which case it's something else!

                    I know it's laborious/not easy, but really if you are getting a crash and debugger/print statements aren't helping that's what to do....

                    How does:

                    def drawBackground(self, painter, rect):
                        pass
                    

                    behave?!

                    What about with only super().drawBackground(painter, rect) in it? What about if you comment out the # draw the lines section at the bottom? What about if you remove your whole def drawBackground() override?

                    D 1 Reply Last reply 29 Apr 2021, 08:06
                    0
                    • J JonB
                      29 Apr 2021, 07:38

                      @deahran
                      If you think something in your drawBackground() code is causing the crash, keep commenting out lines till it goes away! Or not, if you get down to nothing but calling the base implementation. In which case it's something else!

                      I know it's laborious/not easy, but really if you are getting a crash and debugger/print statements aren't helping that's what to do....

                      How does:

                      def drawBackground(self, painter, rect):
                          pass
                      

                      behave?!

                      What about with only super().drawBackground(painter, rect) in it? What about if you comment out the # draw the lines section at the bottom? What about if you remove your whole def drawBackground() override?

                      D Offline
                      D Offline
                      deahran
                      wrote on 29 Apr 2021, 08:06 last edited by
                      #10

                      First of all, even though even though i'm not providing a source code or anything, i do really appreciate the help and welcome here!

                      @JonB I'll try those (and for other methods also), i'll post an update if i come across anything.

                      1 Reply Last reply
                      0
                      • D Offline
                        D Offline
                        deahran
                        wrote on 5 May 2021, 20:43 last edited by deahran 5 May 2021, 20:43
                        #11

                        I would like to provide update on my situation. Problem seems to be resolved. I'm not %100 percent sure since it's hard to reproduce the crash.

                        I used a JIT debugger (IDA) to see what happens during crash, which showed me errors were happening because of a segmentation error (SIGSEGV) inside Qt5Widgets.dll->...->QGraphicsItem::topLevelItem->... . Which implies Qt is trying to read some value by pointer from memory, but can not. The changes i made:

                        • There were some QGrahpicsItems with paint() method drawing outside of boundingRect(). Made sure all painting events stays inside boundingRect().
                        • Made sure before changes to boundingRect(), prepareGeometryChange() was called (QGraphicsItem, QGraphicsPathItem)

                        Special thanks to all who replied.

                        1 Reply Last reply
                        1

                        1/11

                        27 Apr 2021, 16:50

                        • Login

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