Grupos de Google ya no admite nuevas publicaciones ni suscripciones de Usenet. El contenido anterior sigue siendo visible.

CTooltipCtrl with custom paint causing SYSTEM CRASH!!!!!

Visto 112 veces
Saltar al primer mensaje no leído

abhivg

no leída,
30 sept 2009, 2:56:4630/9/09
a abhishek...@persistent.co.in,pravin_...@persistent.co.in
Hi,

I have a CToolTipCtrl derived class which I am using to display text
as well as graphical data.

The tooltip class is handling the paint message in OnPaint() which
contains the text and drawing logic.

Following is a gist of the OnPaint():


///CODE START
CMyToolTip::OnPaint()
{

//CToolTipCtrl::OnPaint(); //if this is uncommented, below
drawing logic is not seen

if(someCondition)
{

CPaintDC dc(this);

CBrush br;
brCreateSolidBrush(RGB(0, 0, 255));
CBrush* pOldBrush = dc.SelectObject(&br);

CFont font;
font.CreatePointFont(90, _T("MS Shell Dlg"));
CFont* pOldFont = dc.SelectObject(&font);


CRect rc;
GetWindowRect (&rc);
//modify rect coordinates here
MoveWindow (&rc); //resize the tooltip window

//output some text
CRect txtRc(rc);
txtRc.right = l;
SetTextWidth(&dc, txtRc, m_str); //m_str
contains text to be written
dc.DrawText(m_str ,&txtRc, DT_LEFT);

//do some drawing
CRect someRect(somecoordinates,..);
dc.Rectangle(&someRect)
.
.


dc.SelectObject(pOldBrush);

::DeleteObject(dc.SelectObject(pOldFont));
::DeleteObject(pOldBrush);

return;
}


CToolTipCtrl::OnPaint(); //have this too as above
drawing wont happen everytime

}
///CODE START

Now there is one object of CMyToolTip class in a view class. View
displays a geographical map and some objects on the map.
Hovering cursor over the objects should show tooltip. Some objects
have only text data and some have text and graphics data.

Problem is as follows:
Hovering mouse over text-only objects and text-graphics objects and
displaying their tooltips works fine, but continuously alternating
between the two after some time displays a blank tooltip or with wrong
data and eventually the whole system crashes!!! (windows blue scren)

The code has released GDI resources where required, so nt sure what
the problem is. Commenting the custom drawing part, does not
bring the crash. What seems to be wrong in the implementation? Please
help

Scot T Brennecke

no leída,
30 sept 2009, 3:39:5030/9/09
a

Windows Blue Screen (a.k.a BSOD) implies to me that you have a hardware-related problem. Perhaps you have a bad driver for your
video (or other device involved in the actions).

abhivg

no leída,
30 sept 2009, 4:09:5730/9/09
a
On Sep 30, 12:39 pm, Scot T Brennecke <Sc...@Spamhater.MVPs.org>
wrote:

Does not seem to be hw related. Was able to reproduce on 3 machines,
different makes. Commenting the graphics part does not cause the bsod.

David Lowndes

no leída,
30 sept 2009, 4:43:1930/9/09
a
Can you pin down the issue to either the selection of the brush or the
font?

Your code doesn't check for the (unlikely) event of SelectObject
failing.

Out of interest, does reversing the order of re-selecting the original
font & brush have any effect?

I don't think you need to explicitly delete the font & brush, their
destructors should take care of that.

Dave

Goran

no leída,
30 sept 2009, 8:02:5330/9/09
a
On Sep 30, 8:56 am, abhivg <abhi...@gmail.com> wrote:
> Hi,
>
> I have a CToolTipCtrl derived class which I am using to display text
> as well as graphical data.
>
> The tooltip class is handling the paint message in OnPaint() which
> contains the text and drawing logic.
>
> Following is a gist of the OnPaint():
>
> ///CODE START
> CMyToolTip::OnPaint()
> {
>
> //CToolTipCtrl::OnPaint();           //if this is uncommented, below
> drawing logic is not seen
>
> if(someCondition)
> {
>
>                 CPaintDC dc(this);
>
>                 CBrush br;
>                 brCreateSolidBrush(RGB(0, 0, 255));

That's brush creation. If that failed, the rest is dubious. (IOW, you
better must check that)

>                 CBrush* pOldBrush = dc.SelectObject(&br);
>
>                 CFont font;
>                 font.CreatePointFont(90, _T("MS Shell Dlg"));

That's font creation. If that failed, the rest is dubious.

>                 CFont* pOldFont = dc.SelectObject(&font);
>
>                 CRect rc;
>                 GetWindowRect (&rc);
>                 //modify rect coordinates here
>                 MoveWindow (&rc);       //resize the tooltip window
>
>                 //output some text
>                 CRect txtRc(rc);
>                 txtRc.right = l;
>                 SetTextWidth(&dc, txtRc, m_str);            //m_str
> contains text to be written
>                 dc.DrawText(m_str ,&txtRc, DT_LEFT);
>
>                 //do some drawing
>                 CRect someRect(somecoordinates,..);
>                 dc.Rectangle(&someRect)
>                 .
>                 .
>
>                 dc.SelectObject(pOldBrush);
>
>                 ::DeleteObject(dc.SelectObject(pOldFont));
>                 ::DeleteObject(pOldBrush);

You must not do that. pOldBrush is not yours to delete.

Also, font GDI object is being deleted twice: once in ~CFont, once in

DeleteObject(dc.SelectObject(pOldFont));

You must not do that either.

SelectObject must only be used like so (not counting region objects):

oldObject = dc.SelectObject(&myObject);
if (!oldObject)
// Crap, error, can't continue!
workworkwork
dc.SelectObject(oldObject);
At any point from here, but not before, you can let myObject get
destroyed.
(The simplest way being creating it on the stack and letting it go out
of scope).

One should use RAII and scoping to force correct use, e.g.:

class CSelectObject /*probably noncopyable and without operator new*/
{
CSelectObject(CDC& cd, CGdiObject& o) : m_dc(dc), m_o(o)
{
m_pOld = m_dc.SelectOObject(&o);
if (NULL == m_pOld)
throw CGodDamnErrorException;
}
~CSelectObject()
{
VERIFY(m_dc.SelectObject(m_pOld);
}
CGdiObject* m_pOld;
};

and then:

OnPaint(...)
{
{
CSelectObject TempGDISelection(*pDC, myGdiObject1);
workworkwork
{
CSelectObject TempGDISelection(*pDC, myGdiObject2);
workworkwork
}
}
}

That said, none of that should cause BSOD. If it does, you should file
a bug report with Windows.

Goran.

Joseph M. Newcomer

no leída,
30 sept 2009, 15:08:5730/9/09
a
As with most bug reports we get here, you omitted all kinds of critical information, such
as the version of Windows you are using, and if it has all the latest updates installed.

I will repeat something I say far too often: the word "crash" without a description is
meaningless noise. If you get a BSOD, it has a description of the error. For example, it
is most likely code 0x7E (unhandled kernel exception), and the first of the four arguments
displayed is 0xC000005, acess fault. The other arguments are usually relevant as well;
the third or fourth (I forget which) is the address of the location that failed. If it is
0 or a small number, you probably have a bad driver. But it is probably not
hardware-related until you see addresses like 0xF???????.

You can get additional information which would help diagnose the problem. Download WinDbg
from the Microsoft Web site. Configure it to download the standard symbols from Microsoft
To do this, you go to File>Symbol Path, then set the path to be

SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols

(this puts the symbols in the directory c:\websymbols; you may want to put them somewhere
else)

Go to File> Open Crash Dump. You can usually find the minidumps in c:\windows\minidumps.
The file name encodes the date and time of the crash, and has a sequence number so there
can be more than one crash in a day.

Then do !analyze -v. The backtrace is often informative. If you have a video driver in
the backtrace, it is your driver. Otherwise, you might have found a bug in the kernel.

If you copy the output from !analyze -v and post it here, I'll take a stab at analyzing
it.

joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Malachy Moses

no leída,
30 sept 2009, 20:11:5530/9/09
a
In your CMyToolTip::OnPaint(), you also call the OnPaint() function of
the base class (i.e., CToolTipCtrl::OnPaint()).

Meanwhile, in your "custom drawing part", you create a CPaintDC.

I think it is wrong to call the base class's OnPaint() if you also
create a CPaintDC in the override. The reason is that only one
CPaintDC is valid for the duration of a WM_PAINT message. Painting in
both your class and the base class results in two CPaintDC's, only one
of which contains the correct clipping region.

Perhaps that is part of the reason why there's no "crash" when you
comment out the custom drawing part.

abhivg

no leída,
8 oct 2009, 4:11:088/10/09
a
On Oct 1, 12:08 am, Joseph M. Newcomer <newco...@flounder.com> wrote:
> As with most bug reports we get here, you omitted all kinds of critical information, such
> as the version of Windows you are using, and if it has all the latest updates installed.
>
> I will repeat something I say far too often: the word "crash" without a description is
> meaningless noise. If you get a BSOD, it has a description of the error. For example, it
> is most likely code 0x7E (unhandled kernel exception), and the first of the four arguments
> displayed is 0xC000005, acess fault. The other arguments are usually relevant as well;
> the third or fourth (I forget which) is the address of the location that failed. If it is
> 0 or a small number, you probably have a bad driver. But it is probably not
> hardware-related until you see addresses like 0xF???????.
>
> You can get additional information which would help diagnose the problem. Download WinDbg
> from the Microsoft Web site. Configure it to download the standard symbols from Microsoft
> To do this, you go to File>Symbol Path, then set the path to be
>
> SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
>
> (this puts the symbols in the directory c:\websymbols; you may want to put them somewhere
> else)
>
> Go to File> OpenCrashDump. You can usually find the minidumps in c:\windows\minidumps.
> The file name encodes the date and time of thecrash, and has a sequence number so there
> can be more than onecrashin a day.

>
> Then do !analyze -v. The backtrace is often informative. If you have a video driver in
> the backtrace, it is your driver. Otherwise, you might have found a bug in the kernel.
>
> If you copy the output from !analyze -v and post it here, I'll take a stab at analyzing
> it.
>
> joe
>
>
>
> On Tue, 29 Sep 2009 23:56:46 -0700 (PDT), abhivg <abhi...@gmail.com> wrote:
> >Hi,
>
> >I have aCToolTipCtrlderived class which I am using to display text
> >data and eventually the wholesystemcrashes!!! (windows blue scren)

>
> >The code has released GDI resources where required, so nt sure what
> >the problem is. Commenting the custom drawing part, does not
> >bring thecrash. What seems to be wrong in the implementation? Please

> >help
>
> Joseph M. Newcomer [MVP]
> email: newco...@flounder.com

Yes, I should have given some more information, so here it is. This is
the log from the WinDgb which you mentioned.

"Microsoft (R) Windows Debugger Version 6.11.0001.404 X86
Copyright (c) Microsoft Corporation. All rights reserved.


Loading Dump File [C:\WINDOWS\Minidump\Mini100809-02.dmp]
Mini Kernel Dump File: Only registers and stack trace are available

Symbol search path is: SRV*f:\websymbols*http://msdl.microsoft.com/
download/symbols
Executable search path is:
Windows XP Kernel Version 2600 (Service Pack 2) MP (2 procs) Free x86
compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp2_gdr.090206-1233
Machine Name:
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055c700
Debug session time: Thu Oct 8 12:01:18.262 2009 (GMT+6)
System Uptime: 0 days 0:42:06.994
Loading Kernel Symbols
...............................................................
................................................................
.....
Loading User Symbols
Mini Kernel Dump does not contain unloaded driver list
Unable to load image igxpdv32.DLL, Win32 error 0n2
*** WARNING: Unable to verify timestamp for igxpdv32.DLL
*** ERROR: Module load completed but symbols could not be loaded for
igxpdv32.DLL
*******************************************************************************
*
*
* Bugcheck
Analysis *
*
*
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck EA, {88c70430, 89b556d8, 89b1ebd8, 1}

*** WARNING: Unable to verify timestamp for igxpgd32.dll
*** ERROR: Module load completed but symbols could not be loaded for
igxpgd32.dll
Probably caused by : igxpdv32.DLL ( igxpdv32+e48 )

Followup: MachineOwner
---------

1: kd> ! analyze -v
*******************************************************************************
*
*
* Bugcheck
Analysis *
*
*
*******************************************************************************

THREAD_STUCK_IN_DEVICE_DRIVER (ea)
The device driver is spinning in an infinite loop, most likely waiting
for
hardware to become idle. This usually indicates problem with the
hardware
itself or with the device driver programming the hardware incorrectly.
If the kernel debugger is connected and running when watchdog detects
a
timeout condition then DbgBreakPoint() will be called instead of
KeBugCheckEx()
and detailed message including bugcheck arguments will be printed to
the
debugger. This way we can identify an offending thread, set
breakpoints in it,
and hit go to return to the spinning code to debug it further. Because
KeBugCheckEx() is not called the .bugcheck directive will not return
bugcheck
information in this case. The arguments are already printed out to the
kernel
debugger. You can also retrieve them from a global variable via
"dd watchdog!g_WdBugCheckData l5" (use dq on NT64).
On MP machines (OS builds <= 3790) it is possible to hit a timeout
when the spinning thread is
interrupted by hardware interrupt and ISR or DPC routine is running at
the time
of the bugcheck (this is because the timeout's work item can be
delivered and
handled on the second CPU and the same time). If this is the case you
will have
to look deeper at the offending thread's stack (e.g. using dds) to
determine
spinning code which caused the timeout to occur.
Arguments:
Arg1: 88c70430, Pointer to a stuck thread object. Do .thread then kb
on it to find
the hung location.
Arg2: 89b556d8, Pointer to a DEFERRED_WATCHDOG object.
Arg3: 89b1ebd8, Pointer to offending driver name.
Arg4: 00000001, Number of times this error occurred. If a debugger is
attached,
this error is not always fatal -- see DESCRIPTION below. On the
blue screen, this will always equal 1.

Debugging Details:
------------------


FAULTING_THREAD: 88c70430

DEFAULT_BUCKET_ID: GRAPHICS_DRIVER_FAULT

CUSTOMER_CRASH_COUNT: 2

BUGCHECK_STR: 0xEA

PROCESS_NAME: MyApp.exe

LAST_CONTROL_TRANSFER: from 89a35000 to bf049e48

STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may
be wrong.
a7f8be0c 89a35000 89a3511c 89a35000 a7f8becc igxpdv32+0xe48
a7f8be10 89a3511c 89a35000 a7f8becc bf05c2e8 0x89a35000
a7f8be14 89a35000 a7f8becc bf05c2e8 89a3511c 0x89a3511c
a7f8be18 a7f8becc bf05c2e8 89a3511c 00000230 0x89a35000
a7f8be1c bf05c2e8 89a3511c 00000230 00000002 0xa7f8becc
a7f8bf34 bf8c205b e1753018 00000000 bf8c2064 igxpdv32+0x132e8
a7f8bf6c 805353ed a7f8bf00 e80af7f0 00000001 win32k!
WatchdogDrvSynchronizeSurface+0x57
a7f8bf94 bf802ace e80af430 00000000 a7f8bfb4 nt!
ExAcquireResourceExclusiveLite+0x67
a7f8bfa4 bf84e7f3 e80af430 e1753018 a7f8bfc0 win32k!HeavyFreePool+0xbb
a7f8bfb4 bf03300f e17d5e58 a7f8c1f0 bf026741 win32k!EngFreeMem+0x1c
a7f8bfc0 bf026741 e17d5e58 00003f88 00002ad0 igxpgd32+0x1100f
a7f8c210 bf80f471 a7f8c370 a7f8c308 bf81144c igxpgd32+0x4741
a7f8c21c bf81144c 00000008 a7f8c7c0 e3b2de98 win32k!
EXFORMOBJ::vComputeAccelFlags+0x77
a7f8c308 bf81075e a7f8c388 e3b2de98 a7f8c4bc win32k!
bGetNtoW_Win31+0x54e
a7f8c438 a7f8c490 bf01b24a e1753018 a7f8c548 win32k!
bGetNtoD_Win31+0x179
a7f8c534 bf810062 e39c8d6c a7f8c608 a7f8c55c 0xa7f8c490
a7f8c65c 00000000 000002b9 0000040e 000002c5 win32k!
RFONTOBJ::bMatchRealization+0x9e


STACK_COMMAND: .thread 0xffffffff88c70430 ; kb

FOLLOWUP_IP:
igxpdv32+e48
bf049e48 75d6 jne igxpdv32+0xe20 (bf049e20)

SYMBOL_STACK_INDEX: 0

SYMBOL_NAME: igxpdv32+e48

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: igxpdv32

IMAGE_NAME: igxpdv32.DLL

DEBUG_FLR_IMAGE_TIMESTAMP: 44c142ec

FAILURE_BUCKET_ID: 0xEA_IMAGE_igxpdv32.DLL_DATE_2006_07_22

BUCKET_ID: 0xEA_IMAGE_igxpdv32.DLL_DATE_2006_07_22"

abhivg

no leída,
8 oct 2009, 4:12:568/10/09
a
On Oct 1, 5:11 am, Malachy Moses <malachy.mo...@gmail.com> wrote:
> In your CMyToolTip::OnPaint(), you also call the OnPaint() function of
> the base class (i.e.,CToolTipCtrl::OnPaint()).

>
> Meanwhile, in your "custom drawing part", you create a CPaintDC.
>
> I think it is wrong to call the base class's OnPaint() if you also
> create a CPaintDC in the override. The reason is that only one
> CPaintDC is valid for the duration of a WM_PAINT message. Painting in
> both your class and the base class results in two CPaintDC's, only one
> of which contains the correct clipping region.
>
> Perhaps that is part of the reason why there's no "crash" when you
> comment out the custom drawing part.

The base OnPaint() will be called only if 'someCondition' becomes
false. So either our painting logic will happen or the base class one.
Will it still be a problem?

abhivg

no leída,
8 oct 2009, 4:22:318/10/09
a
> Debug session time: Thu Oct 8 12:01:18.262 2009 (GMT+6)SystemUptime: 0 days 0:42:06.994
> bf049e48 ...
>
> read more »

Currently I have been able to pinpoint the scenario and reproduce the
crash regularly.
Default behavior of regular text tooltip is:
If tooltip can be shown to below right of cursor screen space
permitting, it is shown to below right. However if there isn't enough
screen space to below-right of cursor, it is shown in top-right
position wrt cursor. Same applies to all bounding sides of screen.

This scenario where the tooltip is trying to readjust itself in case
of less screen space availability, is when the bsod is occuring. The
drawing inside the tooltip becomes extremely sluggish. Monitoring
through task manager shows that memory used shoots up from an average
100 M to 400-500M and the bsod occurs. Sometimes the GDI objects shoot
up too.

Joseph M. Newcomer

no leída,
10 oct 2009, 19:38:3010/10/09
a
Good! See below...

****
This tells you immediately what is going on. And the explanation below even suggests that
this might be a hardware error or a device driver error. So you call your video card
vendor, and ask them to whom you should email this minidump. It's their problem.
****

Joseph M. Newcomer [MVP]
email: newc...@flounder.com

Scot T Brennecke

no leída,
10 oct 2009, 20:26:3710/10/09
a
Joseph M. Newcomer wrote:
> This tells you immediately what is going on. And the explanation below even suggests that
> this might be a hardware error or a device driver error. So you call your video card
> vendor, and ask them to whom you should email this minidump. It's their problem.

And this is what I suggested back on Sep 30th. The OP replied with "Does not seem to be hw related. Was able to reproduce on 3

machines, different makes. Commenting the graphics part does not cause the bsod."

Perhaps this is helpful:
http://forums.techarena.in/operating-systems/1119202.htm

This is just one of many hits you'll get if you search (Bing it!) for "igxpdv32.DLL" and "BSOD" or "blue screen".

Joseph M. Newcomer

no leída,
11 oct 2009, 11:37:0811/10/09
a
...which suggests the three "different" machines all use the Intel video graphics
chipset...and yes, you *did* suggest it, but without the additional information it could
not be confirmed that this was in a specific driver. The OP made the logic error that if
it happened on different machines it might not be driver or hardware related, without
knowing whether or not the machines had the same hardware.

Note also that some graphics drivers are clones of other graphics drivers, so the driver
for the XXXX chipset might have inherited a bug that was used in the YYYY chipset. This
is why reading the crash dumps is essential. It is clear this is a driver problem (a
correct device driver cannot be driven into erroneous states by any form of user action),
although it could be a hardware failure caused by an erroneous driver doing the wrong
thing to the hardware and then waiting for a never-arriving response (note that it is
still a driver problem!)

joe

0 mensajes nuevos