Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt and Exception Trapping
QtWS25 Last Chance

Qt and Exception Trapping

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 3 Posters 1.9k Views
  • 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.
  • webzoidW Offline
    webzoidW Offline
    webzoid
    wrote on last edited by
    #1

    I've been battling with an exception issue which occurs about 20/25/30 minutes into my application running on Windows 10. Try as I might, I am not able to find the location of the crash nor figure out what is triggering it.

    The application runs perfectly then all of a sudden, terminates with the following information taken from Event Viewer:

    EventData:
    MyApp.exe
    1.0.0.1
    5b686e4f
    ucrtbase.dll
    10.0.17134.191
    cb91c047
    c0000409
    000a253b
    2fec
    01d4355f109eee82
    

    Is there any way, within the scope of Qt, whereby I can trap unhandled exceptions and gleam some meaningful information from them. I appreciate that Qt doesn't really support exceptions but is there any static routine which I can implement/override which could tell me the faulting module, line, column, etc?

    JonBJ 1 Reply Last reply
    0
    • webzoidW webzoid

      I've been battling with an exception issue which occurs about 20/25/30 minutes into my application running on Windows 10. Try as I might, I am not able to find the location of the crash nor figure out what is triggering it.

      The application runs perfectly then all of a sudden, terminates with the following information taken from Event Viewer:

      EventData:
      MyApp.exe
      1.0.0.1
      5b686e4f
      ucrtbase.dll
      10.0.17134.191
      cb91c047
      c0000409
      000a253b
      2fec
      01d4355f109eee82
      

      Is there any way, within the scope of Qt, whereby I can trap unhandled exceptions and gleam some meaningful information from them. I appreciate that Qt doesn't really support exceptions but is there any static routine which I can implement/override which could tell me the faulting module, line, column, etc?

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by
      #2

      @webzoid
      (So far as I know) your best chance is to run it in a debugger, sometimes you get a useful traceback (though often not as it's buried away in Windows libraries). You won't see line numbers etc. unless you've compiled for debug. If you compile Qt yourself, compile that for debug too.

      Google for ucrtbase. Some suggestion it's an MSVC module.

      You have a 1 in 1,000 chance that if you Google for some of those memory address numbers you'll find someone else with similar problem....

      1 Reply Last reply
      0
      • webzoidW Offline
        webzoidW Offline
        webzoid
        wrote on last edited by
        #3

        Unfortunately debugging doesn't help, I can't recreate the exact issue on my development machine. The issue is with the program running on a customers machine. I've pretty much exhausted all the Google links to ucrtbase and all the error codes that go with it - lots are game-related, some are Microsoft Word related, others are meaningless.

        Following my initial post, I've implemented a MiniDump class from the following link:

        http://blog.aaronballman.com/2011/05/generating-a-minidump/

        Setting it up as follows in main:

        LONG WINAPI MyCrashHandler(EXCEPTION_POINTERS * /*ExceptionInfo*/)
        {
        	MiniDump dump;
        	dump.Create(L"AppCrash.dmp");
        
        	return EXCEPTION_EXECUTE_HANDLER;
        }
        
        int main(int argc, char *argv[])
        {
        	QApplication a(argc, argv);
        
                // Other init code removed...
        
        	::SetUnhandledExceptionFilter(MyCrashHandler);
        
        	// Create a MainWindow and show it maximized
        	MainWindow w;
        	w.showMaximized();
        
        	return a.exec();
        }
        

        The resulting dmp file when opened in Microsoft Visual Studio gives me the following call stack:

        ntdll.dll!77eaa22c()
        [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
        [External Code]
        Qt5Gui.dll!QPalette::QPalette() Line 536
        MyApp.exe!_com_issue_errorex(HRESULT hr, IUnknown * punk, const _GUID & riid) Line 66
        MyApp.exe!S57Draw::paint(QPainter * painter, QRect rect) Line 115
        MyApp.exe!ChartWidget::paintEvent(QPaintEvent *event) Line 384
        // etc
        

        So, what I can gleam from the above info is that the actual exception is occurring in the paintEvent function of my ChartWidget. Within the paintEvent there is a call to a COM object which paints onto a HDC which ultimately becomes a GDI bitmap, which I then paint onto my QWidget. It also looks like there is something COM-related which is causing issues...

        JonBJ 1 Reply Last reply
        0
        • webzoidW webzoid

          Unfortunately debugging doesn't help, I can't recreate the exact issue on my development machine. The issue is with the program running on a customers machine. I've pretty much exhausted all the Google links to ucrtbase and all the error codes that go with it - lots are game-related, some are Microsoft Word related, others are meaningless.

          Following my initial post, I've implemented a MiniDump class from the following link:

          http://blog.aaronballman.com/2011/05/generating-a-minidump/

          Setting it up as follows in main:

          LONG WINAPI MyCrashHandler(EXCEPTION_POINTERS * /*ExceptionInfo*/)
          {
          	MiniDump dump;
          	dump.Create(L"AppCrash.dmp");
          
          	return EXCEPTION_EXECUTE_HANDLER;
          }
          
          int main(int argc, char *argv[])
          {
          	QApplication a(argc, argv);
          
                  // Other init code removed...
          
          	::SetUnhandledExceptionFilter(MyCrashHandler);
          
          	// Create a MainWindow and show it maximized
          	MainWindow w;
          	w.showMaximized();
          
          	return a.exec();
          }
          

          The resulting dmp file when opened in Microsoft Visual Studio gives me the following call stack:

          ntdll.dll!77eaa22c()
          [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
          [External Code]
          Qt5Gui.dll!QPalette::QPalette() Line 536
          MyApp.exe!_com_issue_errorex(HRESULT hr, IUnknown * punk, const _GUID & riid) Line 66
          MyApp.exe!S57Draw::paint(QPainter * painter, QRect rect) Line 115
          MyApp.exe!ChartWidget::paintEvent(QPaintEvent *event) Line 384
          // etc
          

          So, what I can gleam from the above info is that the actual exception is occurring in the paintEvent function of my ChartWidget. Within the paintEvent there is a call to a COM object which paints onto a HDC which ultimately becomes a GDI bitmap, which I then paint onto my QWidget. It also looks like there is something COM-related which is causing issues...

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by
          #4

          @webzoid said in Qt and Exception Trapping:

          MyApp.exe!S57Draw::paint(QPainter * painter, QRect rect) Line 115

          Probably won't help further but.... That seems to be from https://encx.com/reference/interface_i_s57_draw.html#a6c50588412be1774e10cc0758a05fa83

          Do you have the sources? Does line #115 convey anything helpful?

          webzoidW 1 Reply Last reply
          1
          • JonBJ JonB

            @webzoid said in Qt and Exception Trapping:

            MyApp.exe!S57Draw::paint(QPainter * painter, QRect rect) Line 115

            Probably won't help further but.... That seems to be from https://encx.com/reference/interface_i_s57_draw.html#a6c50588412be1774e10cc0758a05fa83

            Do you have the sources? Does line #115 convey anything helpful?

            webzoidW Offline
            webzoidW Offline
            webzoid
            wrote on last edited by webzoid
            #5

            @JonB Yeah, that's my thinking with regards to the source of the exception.

            The line in question, 115 (I've highlighted this by way of a comment) refers to this block of code from within my application:

            void S57Draw::paint(QPainter *painter, QRect rect) {
                // Width and height of our paint area
            	int width = rect.width();
            	int height = rect.height();
            
            	// Get the CSS background color
            	QColor bg = painter->background().color();
            	COLORREF color = RGB(bg.red(), bg.green(), bg.blue());
            
            	HDC hDC = CreateCompatibleDC(NULL);
            	DWORD *srcData = nullptr;
            	BITMAPINFO bmi = {
            		sizeof(BITMAPINFOHEADER),
            		width,
            		// Negative height means that the image is drawn vertically flipped
            		// which is what we want. Normal height draws the image flipped, for some reason
            		-height,
            		1,
            		32,
            		BI_RGB,
            		0, 0, 0, 0, 0
            	};
            
            	HBITMAP bmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void **)&srcData, 0, 0);
            	HGDIOBJ prev = SelectObject(hDC, bmp);
            
            	// Fill the background
            	HBRUSH br = CreateSolidBrush(color);
            	RECT r = {
            		0, 0,
            		width, height
            	};
            	FillRect(hDC, &r, br);
            
            	// Draw the S57 chart onto our memory dc
            	m_ptr->Draw(reinterpret_cast<OLE_HANDLE>(hDC));
            
                    // ##### WHAT FOLLOWS IS LINE 115 #####
            	SelectObject(hDC, prev);
            	GdiFlush();
            	{
            		// Scoped so that the QImage is destroyed before HBITMAP
            		QImage img((uchar *)srcData, width, height, QImage::Format_RGB32);
            		painter->drawImage(0, 0, img);
            	}
            	DeleteObject(br);
            	DeleteObject(bmp);
            	DeleteDC(hDC);
            }
            
            kshegunovK JonBJ 2 Replies Last reply
            0
            • webzoidW webzoid

              @JonB Yeah, that's my thinking with regards to the source of the exception.

              The line in question, 115 (I've highlighted this by way of a comment) refers to this block of code from within my application:

              void S57Draw::paint(QPainter *painter, QRect rect) {
                  // Width and height of our paint area
              	int width = rect.width();
              	int height = rect.height();
              
              	// Get the CSS background color
              	QColor bg = painter->background().color();
              	COLORREF color = RGB(bg.red(), bg.green(), bg.blue());
              
              	HDC hDC = CreateCompatibleDC(NULL);
              	DWORD *srcData = nullptr;
              	BITMAPINFO bmi = {
              		sizeof(BITMAPINFOHEADER),
              		width,
              		// Negative height means that the image is drawn vertically flipped
              		// which is what we want. Normal height draws the image flipped, for some reason
              		-height,
              		1,
              		32,
              		BI_RGB,
              		0, 0, 0, 0, 0
              	};
              
              	HBITMAP bmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void **)&srcData, 0, 0);
              	HGDIOBJ prev = SelectObject(hDC, bmp);
              
              	// Fill the background
              	HBRUSH br = CreateSolidBrush(color);
              	RECT r = {
              		0, 0,
              		width, height
              	};
              	FillRect(hDC, &r, br);
              
              	// Draw the S57 chart onto our memory dc
              	m_ptr->Draw(reinterpret_cast<OLE_HANDLE>(hDC));
              
                      // ##### WHAT FOLLOWS IS LINE 115 #####
              	SelectObject(hDC, prev);
              	GdiFlush();
              	{
              		// Scoped so that the QImage is destroyed before HBITMAP
              		QImage img((uchar *)srcData, width, height, QImage::Format_RGB32);
              		painter->drawImage(0, 0, img);
              	}
              	DeleteObject(br);
              	DeleteObject(bmp);
              	DeleteDC(hDC);
              }
              
              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #6

              You don't check any of the handles for being valid or not ...

              Read and abide by the Qt Code of Conduct

              webzoidW 1 Reply Last reply
              4
              • webzoidW webzoid

                @JonB Yeah, that's my thinking with regards to the source of the exception.

                The line in question, 115 (I've highlighted this by way of a comment) refers to this block of code from within my application:

                void S57Draw::paint(QPainter *painter, QRect rect) {
                    // Width and height of our paint area
                	int width = rect.width();
                	int height = rect.height();
                
                	// Get the CSS background color
                	QColor bg = painter->background().color();
                	COLORREF color = RGB(bg.red(), bg.green(), bg.blue());
                
                	HDC hDC = CreateCompatibleDC(NULL);
                	DWORD *srcData = nullptr;
                	BITMAPINFO bmi = {
                		sizeof(BITMAPINFOHEADER),
                		width,
                		// Negative height means that the image is drawn vertically flipped
                		// which is what we want. Normal height draws the image flipped, for some reason
                		-height,
                		1,
                		32,
                		BI_RGB,
                		0, 0, 0, 0, 0
                	};
                
                	HBITMAP bmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void **)&srcData, 0, 0);
                	HGDIOBJ prev = SelectObject(hDC, bmp);
                
                	// Fill the background
                	HBRUSH br = CreateSolidBrush(color);
                	RECT r = {
                		0, 0,
                		width, height
                	};
                	FillRect(hDC, &r, br);
                
                	// Draw the S57 chart onto our memory dc
                	m_ptr->Draw(reinterpret_cast<OLE_HANDLE>(hDC));
                
                        // ##### WHAT FOLLOWS IS LINE 115 #####
                	SelectObject(hDC, prev);
                	GdiFlush();
                	{
                		// Scoped so that the QImage is destroyed before HBITMAP
                		QImage img((uchar *)srcData, width, height, QImage::Format_RGB32);
                		painter->drawImage(0, 0, img);
                	}
                	DeleteObject(br);
                	DeleteObject(bmp);
                	DeleteDC(hDC);
                }
                
                JonBJ Online
                JonBJ Online
                JonB
                wrote on last edited by
                #7

                @webzoid said in Qt and Exception Trapping:

                You're way beyond my pay grade here (and I actually though that S57Draw was in some library....) I'm afraid. Is the prev you're reselecting which you got earlier on invalid now? But that's it for my input, you need someone else who knows what they're talking about :)

                1 Reply Last reply
                0
                • kshegunovK kshegunov

                  You don't check any of the handles for being valid or not ...

                  webzoidW Offline
                  webzoidW Offline
                  webzoid
                  wrote on last edited by
                  #8

                  @kshegunov You are absolutely correct - error checking has been added. Testing now so will see if the outcome is different.

                  1 Reply Last reply
                  0
                  • webzoidW Offline
                    webzoidW Offline
                    webzoid
                    wrote on last edited by
                    #9

                    Ok, so an update...

                    The code sample I posted was fine, there were no issues caused by the lack of error-checking (although bad practice, I admit).

                    Fundamentally, the issue was related to difficult to trace memory leaks. As QtCreator for Windows does not have any native memory profiling or debugging tools, I decided to get Visual Studio to attach to my application. I didn't realise but VS has some nice memory snapshot tools which allowed me to keep track of the heap and ultimately solve the problem.

                    I had a rogue class which inherited from QObject and it was the underlying implementation of the QObjectPrivateData which was adding an extra 1.5MB to the heap on every new class instance. I decided that actually, I didn't need to derive from QObject and therefore the issue has now been resolved.

                    So, if there's a useful tip for those who are having memory issues - use Visual Studio for debugging. It's brilliant!!!

                    1 Reply Last reply
                    1

                    • Login

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