Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Toolkit Pro
  New Posts New Posts RSS Feed - CXTPObservable leaks causing aborts
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

CXTPObservable leaks causing aborts

 Post Reply Post Reply
Author
Message
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 804
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Topic: CXTPObservable leaks causing aborts
    Posted: 17 June 2022 at 5:17pm
I have found this code is asserting in XTPSystemHelpers.h:

template<class Owner, class Observer>
AFX_INLINE CXTPObservable<Owner, Observer>::~CXTPObservable()
{
    ASSERT("All observers must be unsubscribed before destruction" && 0 == m_Observers.GetSize());
}

This causes random crashes when closing a debug build when the user has the Win 10 OS setting to use the cursor text indicator. The crash happens when the ASSERT code does a PeekMessage call. The crash is deep in UIAutomationCore.dll during the PeekMessage call.

So why is CJ asserting? I traced this to using the CXTPRibbonOffice2013Theme which creates some CXTPMarkupColor objects (CXTPMarkUpAmbientColor and CXTPMarkUpAmbientColorBrush). Further, it looks like to me the reason is the global paint manager leaking.

I found CXTPPaintManager::SetCustomTheme calls SetGlobalPaintManager. I have found no call during XTPShutDown that releases the global paint theme. So, I get this ASSERT as there are still observables in existence. I do see SetCustomTheme will assert if I pass in null. So that is not something that should be called with null. The SetCustomTheme code spins the ref count down for the current global paint manager so it gets released when setting a new theme. But the new theme just ... remains

This happens in our app. So, I ran the RibbonMDISample in debug. After it comes up, I go to the styles and change the style from Office 2016 Word to Office 2013 Word. Then I exit. The same ASSERT is called for the same reason - 4 observables in one of the arrays of observables.

So, I ask CodeJock:

What is the correct code calls to make sure this global paint manager is properly released so its destructor runs and these observables call XTPGetApplication()->Unsubscribe() and I can avoid the ASSERT/PeekMessage/RandomCrash?

I could try to call the protected GetGlobalPaintManager/SetGlobalPaintManager and spin the ref count down like SetCustomTheme does and hope no CJ code references the nullptr after that. If, I can the code to compile. The I have to worry about what this means for the future of those calls:

    _XTP_DEPRECATED_IN_FAVOR2(GetGlobalPaintManager, SetGlobalPaintManager)

Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 437
Post Options Post Options   Thanks (0) Thanks(0)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 20 June 2022 at 3:58pm
This happens to me as well, about half the time during app shutdown with the debugger attached.

Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 804
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 21 June 2022 at 1:52pm
Hi markr,

I gave up finding what I would call a good solution to this. I can't get the global paint manager and spin its count down like SetCutomTheme does.

So, here is what I had to resort too. Right before I call XTPShutdown I did this:

    if( XTPPaintManager() )
    {
        XTPPaintManager()->SetTheme(xtpThemeOffice2000);
    }

That is the default theme CJ creates in V20. Unfortunately, sometimes there is no global paint manager, which is why we don't always trap the fact there are observable leaks. So, in that case CJ creates a new theme and it will be the xtpThemeOffice2000 theme and there is no leaking. To avoid creating two of that theme, I can use this:

    if( XTPPaintManager() )
    {
        XTPPaintTheme curTheme = XTPPaintManager()->GetCurrentTheme();
        if( xtpThemeOffice2000 != curTheme )
        {
            XTPPaintManager()->SetTheme(xtpThemeOffice2000);
        }
    }

I dislike doing this but the alternative is risking crashes in debug when shutting down while the OS Text Cursor Indicator setting is on. And, I like a crash free shutdown of our app even in debug.
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 804
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 21 June 2022 at 2:27pm
markr,

Have you turned on the OS Text Cursor Indicator? Any crashes when you do so, I'm crashing due to this paint manager leak. But I'm also crashing in docking pane code. And, now I just crashed in CXTPTabManagerItem::GetRect.

>    ToolkitPro2010vc160x64UD.dll!CXTPTabManagerItem::GetRect() Line 544    C++
     ToolkitPro2010vc160x64UD.dll!CXTPRibbonControlTab::AccessibleLocation(long *, long *, long *, long *, tagVARIANT) Line 606    C++
     ToolkitPro2010vc160x64UD.dll!CXTPAccessible::XAccessible::accLocation(long *, long *, long *, long *, tagVARIANT) Line 1289    C++
     oleacc.dll!00007fffc3bbb4b0()    Unknown
     oleacc.dll!00007fffc3bbb2b8()    Unknown
     UIAutomationCore.dll!AccUtils::accLocation()    Unknown

The code is being sent a VT_I4 with a value of 8 but the array of items is only of size 7 but CJ just goes right ahead and accesses with no checks so I can crash here too:

HRESULT CXTPRibbonControlTab::AccessibleLocation(long* pxLeft, long* pyTop, long* pcxWidth,
                                                 long* pcyHeight, VARIANT varChild)
{
    *pxLeft = *pyTop = *pcxWidth = *pcyHeight = 0;

    int nIndex = GetChildIndex(&varChild);

    if (!m_pParent->GetSafeHwnd())
        return S_OK;

    if (!IsVisible())
        return S_OK;

    CRect rcControl = GetRect();

    if (nIndex != CHILDID_SELF)
    {
        rcControl = GetItem(nIndex - 1)->GetRect();
    }

Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 437
Post Options Post Options   Thanks (0) Thanks(0)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 21 June 2022 at 3:09pm
Hi rdhd,

> Have you turned on the OS Text Cursor Indicator?

No, but I have noticed that if I launch the Windows magnifier (I used it sometimes to align small UI facets) then I'll see debug crashes similar to what you describe.

> but CJ just goes right ahead and accesses with no checks

This type of mistake is quite common in the XTP source code, I'm afraid.

Back to Top
dbrookes View Drop Down
Groupie
Groupie


Joined: 30 August 2019
Location: Australia
Status: Offline
Points: 65
Post Options Post Options   Thanks (0) Thanks(0)   Quote dbrookes Quote  Post ReplyReply Direct Link To This Post Posted: 22 June 2022 at 2:47am
Possible unrelated, but I've seen the same asserts recently in the application I work on. In my case it was caused by some old code that was leaking manually allocated CXTPCommandBars objects. So I'm glad the assert caught that for us. In the debugger if you have a look at the CXTPApplication m_Observers array content you might be able to see what objects (if any) have not been released. I use (static) CXTPPaintManager::SetTheme in my application as well, but haven't had any issues with that. I'm using 20.3.0.

As for the accessibility crash. I have seen stuff like that before in report control and property grid components. The theory at the time was that the crashes were caused by crummy anti-malware applications poking around applications through their accessibility interfaces. I reported the crashes to XTP support but I'm not sure if anything ever got changed. We ended up deciding for our application to patch XTP to #ifdef out all the IAccessible COM interface mappings. That way we effectively disable the accessible interfaces. This is bad for any users who actually may actually want/need accessibility. But we didn't have a huge amount of choice. That was a few years ago.
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 804
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 22 June 2022 at 2:05pm
I did look at the objects and found they were "ambient" color and brush objects. I set a BP in the code and found they are created when we start up and set our theme to office 2013. That let me see that theme object was "stuck" as the global paint manager. I didn't find any leaks. But, SetCustomTheme will spin down the count until the current one is released. So, I finally just set the theme back to the 2003 (default theme) CJ sets at startup. The code released the 2013 theme and the leaks went away with it. Tracking leaks is tough as there was a ref count of well over 900 on the paint manager. Guess that's why SetCustomTheme does this at the end to the global PM it grabs at the top of the code before setting it to the new theme:

        while (0 < pOldTheme->InternalRelease())
            ;

Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.063 seconds.