SetBackground UnRef causing exception

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Telemotive
Earned a small fee
Earned a small fee
Posts: 10
Joined: Thu Sep 07, 2017 7:59 am

SetBackground UnRef causing exception

Post by Telemotive »

Hey guys,

I am having a simmilar issue as described here viewtopic.php?t=36096.
It sometimes happens after a few hours, sometimes after a few weeks.
Maybe someone knows the issue and can help me.

I am using wxWidgets 2.8.11 statically linked under Windows.

Code:

Code: Select all

void SettingsGridPanel::onPaint(wxPaintEvent& event)
{
    wxPaintDC panelDC(this);            <------- Exception happens inside

    if(d_currentBitmap != NULL)
    { 
Call stack:

Code: Select all

0000013f2a84a000()	Unbekannt
 	Funktionstester.exe!wxObject::UnRef(void)	Unbekannt
>	Funktionstester.exe!wxObject::Ref(class wxObject const &)	Unbekannt
 	Funktionstester.exe!wxDC::SetBackground(class wxBrush const &)	Unbekannt
 	Funktionstester.exe!wxWindowDC::InitDC(void)	Unbekannt
 	Funktionstester.exe!wxPaintDC::wxPaintDC(class wxWindow *)	Unbekannt
 	Funktionstester.exe!SettingsGridPanel::onPaint(wxPaintEvent & event) Zeile 799	C++
 	Funktionstester.exe!wxEvtHandler::ProcessEventIfMatches(struct wxEventTableEntryBase const &,class wxEvtHandler *,class wxEvent &)	Unbekannt
 	Funktionstester.exe!wxEventHashTable::HandleEvent(class wxEvent &,class wxEvtHandler *)	Unbekannt
 	Funktionstester.exe!wxEvtHandler::ProcessEvent(class wxEvent &)	Unbekannt
 	Funktionstester.exe!wxWindow::HandlePaint(void)	Unbekannt
 	Funktionstester.exe!wxWindow::MSWWindowProc(unsigned int,unsigned __int64,__int64)	Unbekannt
 	Funktionstester.exe!wxWndProc(struct HWND__ *,unsigned int,unsigned __int64,__int64)	Unbekannt
 	user32.dll!0000000077098975()	Unbekannt
 	user32.dll!000000007709729b()	Unbekannt
 	user32.dll!00000000770967e9()	Unbekannt
 	ntdll.dll!00000000771cbc65()	Unbekannt
 	user32.dll!0000000077096e2a()	Unbekannt
 	user32.dll!0000000077096e3c()	Unbekannt
 	user32.dll!0000000077096782()	Unbekannt
 	user32.dll!00000000770d3332()	Unbekannt
 	Funktionstester.exe!wxWindow::MSWProcessMessage(struct tagMSG *)	Unbekannt
 	Funktionstester.exe!wxEventLoop::PreProcessMessage(struct tagMSG *)	Unbekannt
 	Funktionstester.exe!wxEventLoop::ProcessMessage(struct tagMSG *)	Unbekannt
 	Funktionstester.exe!wxEventLoop::Dispatch(void)	Unbekannt
 	Funktionstester.exe!wxEventLoopManual::Run(void)	Unbekannt
 	Funktionstester.exe!wxAppBase::MainLoop(void)	Unbekannt
 	Funktionstester.exe!FunktionstesterMain::OnRun() Zeile 263	C++
 	Funktionstester.exe!wxEntryReal(int &,char * *)	Unbekannt
 	Funktionstester.exe!wxEntry(int &,char * *)	Unbekannt
 	Funktionstester.exe!wxEntry(struct HINSTANCE__ *,struct HINSTANCE__ *,char *,int)	Unbekannt
 	Funktionstester.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Zeile 16	C++
 	Funktionstester.exe!__tmainCRTStartup() Zeile 618	C
 	kernel32.dll!0000000076f759cd()	Unbekannt
 	ntdll.dll!00000000771aa561()	Unbekannt
User avatar
doublemax
Moderator
Moderator
Posts: 19103
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Post by doublemax »

Hard to tell with this little information. As the crash happens at destruction of a wxBrush, my best guess is that you have a GDI handle leak somewhere. Open the taskmanager and enable display for the columns "user objects" and "GDI objects". If one of these increase over time the application should crash when it comes near 10000, which is the internal Windows limit per application.
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7449
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: SetBackground UnRef causing exception

Post by ONEEYEMAN »

Hi,
Also, why do you use an outdated version of the library?
You really should upgrade to the most recent 3.1.

Thank you.
Telemotive
Earned a small fee
Earned a small fee
Posts: 10
Joined: Thu Sep 07, 2017 7:59 am

Re: SetBackground UnRef causing exception

Post by Telemotive »

doublemax wrote:Hard to tell with this little information. As the crash happens at destruction of a wxBrush, my best guess is that you have a GDI handle leak somewhere. Open the taskmanager and enable display for the columns "user objects" and "GDI objects". If one of these increase over time the application should crash when it comes near 10000, which is the internal Windows limit per application.
Thanks, I will have a look on it.
When I open our settings window repeatedly the number of GDI objects increases and as you mentiond the programm crashes with reaching the 10000.
So is there already a leak?
ONEEYEMAN wrote:Hi,
Also, why do you use an outdated version of the library?
You really should upgrade to the most recent 3.1.

Thank you.
We already tried to upgrade, but it seems like wxWidgets has changed so much, that its a really hard task to upgrade.
User avatar
doublemax
Moderator
Moderator
Posts: 19103
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Post by doublemax »

When I open our settings window repeatedly the number of GDI objects increases and as you mentiond the programm crashes with reaching the 10000.
So is there already a leak?
Yes. Check the use of wxPen, wxBrush, wxBitmap etc. in the paint event handler and make sure they are all destroyed properly.

BTW: How many GDI objects are there initially when the program starts?
Use the source, Luke!
User avatar
eranon
Can't get richer than this
Can't get richer than this
Posts: 867
Joined: Sun May 13, 2012 11:42 pm
Location: France
Contact:

Re: SetBackground UnRef causing exception

Post by eranon »

Telemotive wrote:
ONEEYEMAN wrote:Hi,
Also, why do you use an outdated version of the library?
You really should upgrade to the most recent 3.1.

Thank you.
We already tried to upgrade, but it seems like wxWidgets has changed so much, that its a really hard task to upgrade.
You could migrate smoothly and split the gap: first to wxWidgets 2.9, then to 3.0, and finally 3.1. And knowing wx 2.8, 2.9, 3.0 and 3.1 can co-exist, you can add as many targets as you want in your project and switch as necessary.

Some useful docs:
http://docs.wxwidgets.org/3.1/overview_ ... nce28.html
https://wiki.wxwidgets.org/Updating_to_ ... _wxWidgets
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]
User avatar
doublemax
Moderator
Moderator
Posts: 19103
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Post by doublemax »

You could migrate smoothly and split the gap: first to wxWidgets 2.9, then to 3.0, and finally 3.1.
Sorry, i have to disagree, the major differences between 2.8.x and 2.9.x are the same as between 2.8.x and 3.1.x
Use the source, Luke!
User avatar
eranon
Can't get richer than this
Can't get richer than this
Posts: 867
Joined: Sun May 13, 2012 11:42 pm
Location: France
Contact:

Re: SetBackground UnRef causing exception

Post by eranon »

I never used 2.8, I started with 2.9. I don't remember clearly my migration from 2.9 to 3.0, but the one from 3.0 to 3.1 generated a lot of warnings (eg. deprecated). So, if Telemotive wanted to directly switch to wxWidgets 3.1, it would be obviously a good idea, but he doesn't seem to be ready... So, my attempt was to convince him and even if all the steps have not the same weight, it's psychologically smoother (because there's not dev only in life, there's psychology too;). What does we go forward or not ? That is the question!
[Ind. dev. - wxWidgets 3.0/3.1 under "Win 7 64-bit, TDM64-GCC" + "OS X 10.9, LLVM Clang"]
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7449
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: SetBackground UnRef causing exception

Post by ONEEYEMAN »

Hi,
Unless you are stuck with some kind of government project where there is no reason to update GUI unless absolutely needs to I would suggest to upgrade.

Just follow the documentation - it explains everything (what is deprecated, what changes are incompatible and how to migrate smoothly).

Thank you.
Telemotive
Earned a small fee
Earned a small fee
Posts: 10
Joined: Thu Sep 07, 2017 7:59 am

Re: SetBackground UnRef causing exception

Post by Telemotive »

doublemax wrote:Yes. Check the use of wxPen, wxBrush, wxBitmap etc. in the paint event handler and make sure they are all destroyed properly.

BTW: How many GDI objects are there initially when the program starts?
The number of GDI objects is about 160 after the program start, User-Objects are about 190.
I checked the proper destruction of the wxPen, wxBrush and wxBitmap usage and did not find any mistakes.

I have added some code to monitore the GDI and User object usage over time to detect if there is an increase.


Upgrading is no option at the moment, we mainly need to fix this bug.
User avatar
doublemax
Moderator
Moderator
Posts: 19103
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Post by doublemax »

I have added some code to monitore the GDI and User object usage over time to detect if there is an increase.
Did i misunderstand your earlier post? I thought you had already comfirmed that they increase over time and that the crash occurs at around 10000?
Use the source, Luke!
Telemotive
Earned a small fee
Earned a small fee
Posts: 10
Joined: Thu Sep 07, 2017 7:59 am

Re: SetBackground UnRef causing exception

Post by Telemotive »

I am writing a test software where you can do the same test sequence for n times.
You can set the count of cycles and some more settings in a settings page.

I opened and closed the settings page multiple times to check if the GDI objects and User objects increase.
When reaching the 10000 the program crashed like you said.

But the bug I am trying to find does not occur when editing settings, it occurs during the test.
We have a big window writing test information and logs and a status bar shown during the test.
User avatar
doublemax
Moderator
Moderator
Posts: 19103
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Post by doublemax »

It would be a big conincidence if these two issues weren't related. Can you show the code for SettingsGridPanel::onPaint()?

Is it possible to estimate how many leaked objects you have per paint event? (By how much does the number increase when you show/hide the settings window once?)
Use the source, Luke!
Telemotive
Earned a small fee
Earned a small fee
Posts: 10
Joined: Thu Sep 07, 2017 7:59 am

Re: SetBackground UnRef causing exception

Post by Telemotive »

Here the Code

Code: Select all

void SettingsGridPanel::onPaint(wxPaintEvent& event)
{
    wxPaintDC panelDC(this);

    if(d_currentBitmap != NULL)
    {
        //aufpassen dassmer nicht zu weit scrollen
        wxSize clientSize = GetClientSize();
        long horizontalCorrection = d_scrollPosition.GetWidth()*SCROLLBAR_STEPSIZE;
        if((d_currentBitmap->GetWidth() - clientSize.GetWidth()) < horizontalCorrection)
        {
            horizontalCorrection = d_currentBitmap->GetWidth() - clientSize.GetWidth();
        }

        //sonderfall: client kann größer als bitmap sein
        long verticalCorrection = d_scrollPosition.GetHeight()*SCROLLBAR_STEPSIZE;
        if(d_currentBitmap->GetHeight() < clientSize.GetHeight())
        {
            verticalCorrection = 0;
        }
        else if((d_currentBitmap->GetHeight() - clientSize.GetHeight()) < verticalCorrection)
        {
            verticalCorrection = d_currentBitmap->GetHeight() - clientSize.GetHeight();
        }

        //invers scroll position
        wxSize inversScrollPosition = wxSize(horizontalCorrection*-1, verticalCorrection*-1);

        panelDC.DrawBitmap((*d_currentBitmap), inversScrollPosition.GetWidth(), inversScrollPosition.GetHeight(), true);
    }
}
Estimating how many objects leak per paint event is not that easy, but I checked with opening an closing the settings multiple times:

Code: Select all

   
   #1 first run						
                                 User-Objects            GDI-Objects
application start        :       157                     181
after first paint        :       158                     182
opening settings         :       968                     485
after closing settings   :       159                     212
   
   #2 second run
                                 User-Objects            GDI-Objects
opening settings         :       968                     505
after closing settings   :       159                     218
   
   #3 third run
                                 User-Objects            GDI-Objects
opening settings         :       968                     505
after closing settings   :       159                     216
   
User avatar
doublemax
Moderator
Moderator
Posts: 19103
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Post by doublemax »

I think it's safe to say that there is no memory leak in that paint event code. Also, the number of handles seems almost constant after the window has been shown once. Just to be sure: How is the paint event handler connected?

I assume the settings window is opened above the main window? Does that have any custom paint code? Showing and hiding the settings window will also cause a paint event in the underlying window. Maybe the problem lies there. If yes, you should also see the problem if you just move a window from another application over your main window, so that lots of paint events are generated.
Use the source, Luke!
Post Reply