Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Access violation on calling GetSafeHwnd()

223 views
Skip to first unread message

Testkr

unread,
Feb 27, 2007, 2:27:07 PM2/27/07
to
When I am calling this function, I am getting an access violation error.
Can somebody tell me why is it happening. I am running this application on
Windows Vista.

Regards,
Pooja Katiyar.

Scott McPhillips [MVP]

unread,
Feb 27, 2007, 3:18:43 PM2/27/07
to
Testkr wrote:
> When I am calling this function, I am getting an access violation error.
> Can somebody tell me why is it happening. I am running this application on
> Windows Vista.

Show a few lines of your code. I would guess you are using a CWnd
pointer that is not actually pointing at a CWnd.

--
Scott McPhillips [VC++ MVP]

Testkr

unread,
Feb 28, 2007, 9:26:02 AM2/28/07
to
Hi Scott,

Here is the piece of code -

BOOL CZedObjectFrame::OnCmdMsg( UINT nID, int nCode, void * pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
// call up, does menu and toolbar updates
BOOL rc = FALSE;

if (!CanUserModify() && m_pToolBar != NULL)
{
CToolBarCtrl & ctrlFramework = m_pToolBar->GetToolBarCtrl();
if(ctrlFramework.IsButtonEnabled(nID) == 0)
{
return rc;
}
}

rc = CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

access violation here >>>> HWND viewHandle = GetSafeHwnd();
if(viewHandle != NULL && ::IsWindow(viewHandle))
{

Scott McPhillips [MVP]

unread,
Feb 28, 2007, 9:47:40 AM2/28/07
to
Testkr wrote:
> Hi Scott,
>
> Here is the piece of code -
>
> BOOL CZedObjectFrame::OnCmdMsg( UINT nID, int nCode, void * pExtra,
> AFX_CMDHANDLERINFO* pHandlerInfo)
> {
> // call up, does menu and toolbar updates
> BOOL rc = FALSE;
>
> if (!CanUserModify() && m_pToolBar != NULL)
> {
> CToolBarCtrl & ctrlFramework = m_pToolBar->GetToolBarCtrl();
> if(ctrlFramework.IsButtonEnabled(nID) == 0)
> {
> return rc;
> }
> }
>
> rc = CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
>
> access violation here >>>> HWND viewHandle = GetSafeHwnd();
> if(viewHandle != NULL && ::IsWindow(viewHandle))
> {

Get a breakpoint there. (You may need to add some temporary code so it
breaks on the relevant message.) When it hits the breakpoint examine
the 'this' pointer, and its member variables, to see what you've got. I
don't see any way it could fail unless 'this' is corrupt. Keep in mind
that a lot of stuff is executed when you call CFrameWnd::OnCmdMsg, so
something in there may be causing mayhem. You could move the
troublesome line ahead of the call to see if that changes things.

Joseph M. Newcomer

unread,
Mar 1, 2007, 3:09:21 PM3/1/07
to
I don't suppose you could bother to show us the code? It's probably obvious. But I'm not
getting a good sense of the code from the ethereal vibrations.
joe

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

Joseph M. Newcomer

unread,
Mar 1, 2007, 3:11:23 PM3/1/07
to
It seems pretty obvious that the current pointer you have is not a pointer to a CWnd. So
what is it a pointer to? When you get the access violation, you should be able to see
this in the debugger. What did you see?
joe

Doug Harrison [MVP]

unread,
Mar 1, 2007, 6:35:24 PM3/1/07
to
On Wed, 28 Feb 2007 06:26:02 -0800, Testkr
<Tes...@discussions.microsoft.com> wrote:

>Hi Scott,
>
>Here is the piece of code -
>
>BOOL CZedObjectFrame::OnCmdMsg( UINT nID, int nCode, void * pExtra,
>AFX_CMDHANDLERINFO* pHandlerInfo)
>{
> // call up, does menu and toolbar updates
> BOOL rc = FALSE;
>
> if (!CanUserModify() && m_pToolBar != NULL)
> {
> CToolBarCtrl & ctrlFramework = m_pToolBar->GetToolBarCtrl();
> if(ctrlFramework.IsButtonEnabled(nID) == 0)
> {
> return rc;
> }
> }
>
> rc = CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
>
>access violation here >>>> HWND viewHandle = GetSafeHwnd();
> if(viewHandle != NULL && ::IsWindow(viewHandle))
> {

If the command message caused the window to be closed, I could (barely) see
this faulting. If this is not the case, then you entered this member
function on an invalid window, or something has caused damage to the object
it was called on or perhaps the thread's stack, e.g. a buffer overrun, or
maybe the register used to hold the "this" pointer wasn't properly saved
and restored across the function call. I don't see any other possibilities,
since GetSafeHwnd amounts to the following in this context:

HWND viewHandle = (this != 0) ? m_hWnd : 0;

I have to say, it's strange you'd get an access violation there and not
earlier. Even if the window were closed and the memory freed, it would have
to be decommitted from your address space to cause an access violation, and
AFAIK, that happens rarely if ever for the C++ heap. What do you observe in
the debugger?

--
Doug Harrison
Visual C++ MVP

Joseph M. Newcomer

unread,
Mar 2, 2007, 12:42:36 AM3/2/07
to
One of the situations I've seen that causes a failure is when there is a CWnd * that is a
local or member variable that is uninitialized, so it is something like 0xcccccccc or
0xcdcdcdcd. Of course, if he had gone into the debugger and examined the variable and
reported it, perhaps there would be a chance to figure out what had gone wrong.
joe

Doug Harrison [MVP]

unread,
Mar 2, 2007, 1:59:36 AM3/2/07
to
On Fri, 02 Mar 2007 00:42:36 -0500, Joseph M. Newcomer
<newc...@flounder.com> wrote:

>One of the situations I've seen that causes a failure is when there is a CWnd * that is a
>local or member variable that is uninitialized, so it is something like 0xcccccccc or
>0xcdcdcdcd. Of course, if he had gone into the debugger and examined the variable and
>reported it, perhaps there would be a chance to figure out what had gone wrong.
> joe

Unless I'm missing something, his code involves a "this" pointer becoming
corrupted inside a member function. He had:

>>>BOOL CZedObjectFrame::OnCmdMsg( UINT nID, int nCode, void * pExtra,
>>>AFX_CMDHANDLERINFO* pHandlerInfo)

<snip>


>>> rc = CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
>>>
>>>access violation here >>>> HWND viewHandle = GetSafeHwnd();

Apparently, the OnCmdMsg upcall to the base class went all right, but upon
return, he GPF's when he calls GetSafeHwnd, which as I noted, could hardly
be simpler (below I changed m_hWnd to this->m_hWnd to emphasize the
implicit dereference):

>> HWND viewHandle = (this != 0) ? this->m_hWnd : 0;

The "this" pointer is typically kept in a register and is passed in a
register to normal member functions, which follow the __thiscall calling
convention. So how can it get corrupted? I can think of three
possibilities:

1. The base class OnCmdMsg didn't preserve the register
CZedObjectFrame::OnCmdMsg was using to hold "this", or

2. CZedObjectFrame::OnCmdMsg had to dump "this" to the stack, and upon
return from CFrameWnd::OnCmdMsg, it loaded a bad pointer due to stack
corruption, or

3. The memory holding the CZedObjectFrame object was decommitted. (If it
weren't decommitted, he'd load a garbage HWND value and fail later.)

Only (2) seems even somewhat likely. Oh well, enough guessing. I'd actually
be surprised if any of it applies. :)

Joseph M. Newcomer

unread,
Mar 2, 2007, 11:10:42 PM3/2/07
to
Consider the following situation

CMyWnd * something;

something->Whatever();

void CMyWnd::Whatever()
{
HWND h = GetSafeHwnd();
...
}

Note that what this does is pass the uninitialized something pointer (0xccccccccc), which
is harmless until there is an attempt to use it; since GetSafeHwnd() only checks for a
NULL pointer, it will then try to return ((CWnd*)(0xcccccccc))->m_hWnd, which is going to
be fatal.
joe

Alexander Grigoriev

unread,
Mar 2, 2007, 11:30:16 PM3/2/07
to
Looks like one of our "favorive" message handler argument mismatch bug, so
easily got with VC6.

"Doug Harrison [MVP]" <d...@mvps.org> wrote in message
news:5lifu21bsu9k17s7b...@4ax.com...

Doug Harrison [MVP]

unread,
Mar 3, 2007, 12:05:44 PM3/3/07
to
On Fri, 02 Mar 2007 23:10:42 -0500, Joseph M. Newcomer
<newc...@flounder.com> wrote:

>Consider the following situation
>
>CMyWnd * something;
>
>something->Whatever();
>
>void CMyWnd::Whatever()
> {
> HWND h = GetSafeHwnd();
> ...
> }
>
>Note that what this does is pass the uninitialized something pointer (0xccccccccc), which
>is harmless until there is an attempt to use it; since GetSafeHwnd() only checks for a
>NULL pointer, it will then try to return ((CWnd*)(0xcccccccc))->m_hWnd, which is going to
>be fatal.
> joe

Sure, but the OP had done a lot of "this" dereferencing before calling
GetSafeHwnd. If his OnCmdMsg override had been called on an invalid object,
it would have crashed sooner than it did.

0 new messages