Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Command Bars
  New Posts New Posts RSS Feed - CXTPToolTIpContextToolTip::OnDestroy and a crash
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

CXTPToolTIpContextToolTip::OnDestroy and a crash

 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: 867
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Topic: CXTPToolTIpContextToolTip::OnDestroy and a crash
    Posted: 04 December 2013 at 11:59am
I am using an html tooltip and every so often I crash in CXTPTooltipContextToolTip::SetVisible. I suspect that the window is invalid when the OnTimer call comes through.

So I followed the destroy window call until I got to CXTPToolTipContextToolTip::OnDestroy. There I found this:

KillTimer(1); // should fix a potential crash

I see that m_arrTools has a size of zero. In OnTimer I see nIDEvent is 1. But m_nDelayTimer is zero. But the code path to SetVisibleTool has to pass "if (nIDEvent == m_nDelayTimer)"

But neither FindTool nor SetVisibleTool change the value of m_nDelayTimer. Furthermore the TOOLITEM* pVisibleTool passed to SetVisibleTool looks like it is invalid (possibly deleted) memory at the time of the crash (in this particular case I am crashing in in the pWnd->ClientToScreen call SetVisibleTool makes. The call to GetToolSize in SetVisibleTool has already been made and the size looks valid. This isn't the only place I have crashed. For example, I have also crashed during the tool copy code (invalid string pointer causing ATL string class to try and allocate huge memory buffers).

I am led to believe the tool passed into SetVisibleTool was valid when passed in and then somehow got deleted from m_arrTools during the processing but have been unable to verify that.

This isn't easy to reproduce. I have to move around the ribbon quickly quite a bit and a key to making it crash seems to be to click the application button and move over the menus. Also I try to avoid the timer going off so that I see the tip display on the app button/menu. I found that as I move over the app button and menus the context object calls DestroyWindow, which led me to OnDestroy.

Can someone at CodeJock explain the nature of the crash the comment refers to that led to the KillTimer call in OnDestroy?

Could the tooltip formatting code be causing a delay or allowing addition message processing that is causing this issue?

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

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 867
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 04 December 2013 at 3:16pm
I have verified that the tool is being deleted while it is being used. I implemented OnTimer  and OnDelTool and copied the code. I added trace calls to print out the pointer to the item.

When I crash I can see that the timer ran and I had a good tool pointer. Then when I crashed I can see the pointer being used during the OnTimer code execution is still the same. I also see the trace statement from OnDelTool where I printed out the same tool pointer that was being deleted.

So how does this happen? TTM_DELTOOL is invoked via a SendMessage in the tooltip context code. Somehow the frame is processing messages while processing a tool hit and preparing to display the tooltip. That led me to the HTML tooltip code where Navigate is called.

The code for the call to Navigate is  followed by a do loop where AfxGetApp()->PumpMessage is called until get_ReadyState returns READYSTATE_COMPLETE.

That is allowing the frame to process mouse moves and when I move the mouse off the current control on the ribbon to another control the code sends the TTM_DELTOOL message.  Kaboom.

I'm not sure I want that PumpMessage call. The larger the html page is the longer it takes to process and the longer that takes the greater the risk of this occurring.

So what is the purpose of PumpMessage in the HTML tooltip code? Or, what would a CodeJock programmer do to avoid this situation? Note the TTM_DELTOOL call by seeing if the tool is still valid after Navigate? My current crash is in the Assign call in SetVisibleTool (actually in CSimpleString = operator) and after calling EnsureVisible that would be the time to make sure the pointer is still valid.

Other options?

Make a copy of the tool before calling EnsureVisible and using the copy after that call and hope the window of the tool itself is still valid (seems like a safe assumption).










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

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 867
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 04 December 2013 at 3:43pm
Just a quick correction:

GetToolSize is where Navigate is called not EnsureVisible.

SetVisibleTool calls GetToolSize and when that routine returns the tool can be deleted due to the PumpMessage calls.
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 867
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 20 December 2013 at 5:14pm
This call to PumpMessage is more dangerous than I realized. It looks like a user can close the app at just the wrong moment and the commandbars object gets destroyed, which destroys the tooltip context, which destroys the tool context tooltip ...

I have also noticed a crash where the vtable of the html tooltip class is bad (function call to random code). In that case I got a dump and found that OnTimer was on the stack three times when the crash occurred. In each case the call went to the GetToolSize and PumpMessage call.

I tried removing PumpMessage and get_readystate never indicated a ready state (locked in infinite loop). So now I am trying to copy the browser app com interface (with an AddRef) and using the copy in the GetToolSize method so I don't access a bad instance pointer when ready state is signaled and trying to figure out how to handle unwinding the stack if something goes wrong (like the html tooltip destructor fires while in a method on the object).

Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 442
Post Options Post Options   Thanks (0) Thanks(0)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 08 March 2014 at 2:18pm
Have you had any luck in figuring this out? I'm seeing the problem as well.
Back to Top
astoyan View Drop Down
Admin Group
Admin Group
Avatar

Joined: 24 August 2013
Status: Offline
Points: 292
Post Options Post Options   Thanks (0) Thanks(0)   Quote astoyan Quote  Post ReplyReply Direct Link To This Post Posted: 12 March 2014 at 10:55pm
The issue has been addressed and fixed for the next release.
Should you want to re-test, CPU Stress utility (http://blogs.msdn.com/b/vijaysk/archive/2012/10/27/tools-to-simulate-cpu-memory-disk-load.aspx) will help to re-produce the crash faster. If you notice that the issue is not resolved or crashes in another place, please let me know, because catching and debugging this one was not an easy task and some scenarios still might remain unresolved.
Thank you.
Back to Top
markr View Drop Down
Senior Member
Senior Member


Joined: 01 August 2004
Status: Offline
Points: 442
Post Options Post Options   Thanks (0) Thanks(0)   Quote markr Quote  Post ReplyReply Direct Link To This Post Posted: 14 March 2014 at 10:36pm
The issue has been addressed and fixed for the next release.

Well, that's definitely good news. Would the bug you fixed affect markup tooltips as well?
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 867
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 29 September 2015 at 8:50am
Astoyan,

We have pulled 17 (beta 3). We have also implemented MDI tabs for our MDI application. We have been crashing when running with HTML tooltips and I am examining the problem and here is what I see.

I right-click on the tab and bring up a shortcut menu and move over an element. The tooltip timer fires and the HTML tooltip code calls Navigate. Then it goes into the PumpMessage loop. While inside the loop, I move the mouse off the context menu. The tooltip context object's FilterToolTipMessageHelper calls SAFE_DELETEWINDOW(m_pToolTip). The destructor for the HTML tooltip calls SAFE_RELEASE(m_pBrowserApp) and the browser app gets deleted and the pointer is set to NULL.

Then the ready state for the Navigate calls fires. The deleted HTMLTooltip then tries to access the deleted m_pBrowserApp member and the app crashes.

I have set break points in the code and printed messages so I don't interrupt the timing. What I see is something like this (number of calls to get_ReadyState varies, of course):

"navigating browser 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"calling get_ReadyState on 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
"Deleting browser 0x0000000073916250 <No type information available in symbol file for ieframe.dll>"
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\cmdtarg.cpp(40) : Assertion failed!
"calling get_ReadyState on 0x0000000000000000 <NULL>"

Let me note that we have been rarely crashing in the past with the same call stack. Also, users have reported, and I have examined dumps, for cases where the user is moving over and clicking the app close button (upper-right "x"). In those cases, it appears the tooltip context itself has been destroyed while we are in the PumpMessage loop.

Basically what I don't see, or at least understand, is how CodeJock is trying to prevent the deletion of the HTML tooltip while in the PumpMessage loop. I don't see any calls to AddRef/Release on the HTML tooltip. Shouldn't the call to delete really be a call to Release. Then at least when the timer event occurs, the HTML tooltip could itself call AddRef and then Release when exiting the timer handler. Also in the PumpMessage loop, the HTML tooltip could check the m_cRef member and if it is one, assume it should cancel the navigation is exit (to prevent the tip from displaying after the user has moved on).

What do you think?

By the way, I did see the posting of the tool delete message to address the other issue I first brought up.
Back to Top
rdhd View Drop Down
Senior Member
Senior Member
Avatar

Joined: 13 August 2007
Location: United States
Status: Offline
Points: 867
Post Options Post Options   Thanks (0) Thanks(0)   Quote rdhd Quote  Post ReplyReply Direct Link To This Post Posted: 02 October 2015 at 11:42am
Astoyan,

Can you tell me what the fix was you mentioned?
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.125 seconds.