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
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Sep 07, 2017 7:59 am

SetBackground UnRef causing exception

Postby Telemotive » Thu Sep 07, 2017 8:46 am

Hey guys,

I am having a simmilar issue as described here https://forums.wxwidgets.org/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: 11290
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Postby doublemax » Thu Sep 07, 2017 10:07 am

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: 1924
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: SetBackground UnRef causing exception

Postby ONEEYEMAN » Thu Sep 07, 2017 12:47 pm

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
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Sep 07, 2017 7:59 am

Re: SetBackground UnRef causing exception

Postby Telemotive » Fri Sep 08, 2017 7:00 am

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: 11290
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Postby doublemax » Fri Sep 08, 2017 7:37 am

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
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 602
Joined: Sun May 13, 2012 11:42 pm
Location: France
Contact:

Re: SetBackground UnRef causing exception

Postby eranon » Fri Sep 08, 2017 1:40 pm

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: 11290
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Postby doublemax » Fri Sep 08, 2017 1:48 pm

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
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 602
Joined: Sun May 13, 2012 11:42 pm
Location: France
Contact:

Re: SetBackground UnRef causing exception

Postby eranon » Sat Sep 09, 2017 6:02 pm

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: 1924
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: SetBackground UnRef causing exception

Postby ONEEYEMAN » Sat Sep 09, 2017 9:36 pm

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
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Sep 07, 2017 7:59 am

Re: SetBackground UnRef causing exception

Postby Telemotive » Tue Sep 12, 2017 8:10 am

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: 11290
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Postby doublemax » Tue Sep 12, 2017 9:36 am

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
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Sep 07, 2017 7:59 am

Re: SetBackground UnRef causing exception

Postby Telemotive » Tue Sep 12, 2017 10:24 am

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: 11290
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Postby doublemax » Tue Sep 12, 2017 12:33 pm

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
In need of some credit
In need of some credit
Posts: 8
Joined: Thu Sep 07, 2017 7:59 am

Re: SetBackground UnRef causing exception

Postby Telemotive » Thu Sep 14, 2017 7:07 am

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: 11290
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: SetBackground UnRef causing exception

Postby doublemax » Thu Sep 14, 2017 9:50 am

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!


Return to “C++ Development”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 9 guests