15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


AfxMessageBox corrupts data

Harry Hahne -- hahne@epas.utoronto.ca
Wednesday, November 20, 1996

Environment: Win 95, VC 4.1

My MFC program has a command handler function in my view class (CView derived)
that includes a call to AfxMessageBox() to report an error condition that may 
occur inside the command handler.  The command handler creates an object that 
uses a custom class not derived from any MFC class.  Everything works fine 
unless I call the AfxMessageBox() function.  WHen that happens a pointer 
inside my custom data object gets set to NULL.  This eventually crashes the 
program when that pointer later needs to be used.

I cannot determine any reason why calling a message box inside a command 
handler should cause data corruption.  Does anyone have any ideas about what to 
look for?  I assume that it is legal to have a message box inside a command 
handler.

The relevant bits of code are something like this:

ON_COMMAND(ID_VIEW_SUBSET, OnViewSubset)

//command handler for the View-Subset menu item

void CBriefView::OnViewSubset() 
{
    char SubsetName[SUBSETNAMLEN+1];//Subset name
    CSubsetDialog AskSubsetDialog;//dialog box to ask for Subset name

    if(AskSubsetDialog.AskOpen(SubsetName)) != ASK_ABORT)
    {	//ask for Subset name
		if(m_pRecBrowser->SelectSubset(SubsetName) != ERR) 
		{   //change browse method to Subset
			/***DO STUFF TO CHANGE TO BROWSE SUBSET*****/
		}
    }
}

//Select subset of database to view

int CRecBrowser::SelectSubset(char *SubsetName)
{
    try
    {
         CurrentPos.pSubset = new CSubset;//create subset object
    }
    catch(CMemoryException *e)
    {
         e->Delete;
         Message_Memory();
         return(ERR);
    }

    if(CurrentPos.pSubset->OpenSubset(SubsetName))
    {	//open database subset
        return(ERR);
    }

    if(FirstRec() == 0)
    {	//go to first record in subset

		/*** AT THIS POINT CurrentPos.pSubset POINTS TO THE SUBSET OBJECT***/

		AfxMessageBox(IDS_SUBSET_EMPTY);//message indicating subset has no records

		/*** AT THIS POINT CurrentPos.pSubset IS SET TO NULL
			THIS CAUSES THE NEXT FUNCTION TO CRASH *****/

       CurrentPos.pRecList->CloseList();

       delete CurrentPos.pRecList;
       return(ERR);
    }
	return(0);
}

Thanks for any suggestions.

Harry Hahne
hahne@chass.utoronto.ca



Mike Blaszczak -- mikeblas@nwlink.com
Thursday, November 21, 1996

At 09:36 11/20/96 +0000, Harry Hahne wrote:
>Environment: Win 95, VC 4.1

> if(FirstRec() == 0)
> { //go to first record in subset
>
>   /*** AT THIS POINT CurrentPos.pSubset POINTS TO THE SUBSET OBJECT***/
>
>   AfxMessageBox(IDS_SUBSET_EMPTY);//message indicating subset has no records
>
>   /*** AT THIS POINT CurrentPos.pSubset IS SET TO NULL
>      THIS CAUSES THE NEXT FUNCTION TO CRASH *****/
>
>   CurrentPos.pRecList->CloseList();

How is pSubset related to pRecList?

Anyway, if you think the call to AfxMessageBox() is changing one of these
values, prove it: use the "Data" tab in the Breakpoint dialog, which is
reachable by using the "Breakpoints" command in the "Edit" menu to set
a breakpoint that fires when the value of that variable changes.

Then, you'll be able to see _exactly_ what causes it to change firsthand.

.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.



Harry Hahne -- hahne@epas.utoronto.ca
Tuesday, November 26, 1996

Environment: Win 95, VC 4.1

.B ekiM wrote:

> How is pSubset related to pRecList?

Sorry, in an attempt to simply the code I did not post it to the list 
correctly.  Here is the corrected code (pRecList should be pSubset):

> int CRecBrowser::SelectSubset(char *SubsetName)
> {
>     try
>     {
>          CurrentPos.pSubset = new CSubset;//create subset object
>     }
>     catch(CMemoryException *e)
>     {
>          e->Delete;
>          Message_Memory();
>          return(ERR);
>     }
> 
>     if(CurrentPos.pSubset->OpenSubset(SubsetName))
>     {	//open database subset
>         return(ERR);
>     }
> 
>     if(FirstRec() == 0)
>     {	//go to first record in subset
> 
>   /*** AT THIS POINT CurrentPos.pSubset POINTS TO THE SUBSET OBJECT***/
> 
>   AfxMessageBox(IDS_SUBSET_EMPTY);//message indicating subset has no
> records
> 
>   /*** AT THIS POINT CurrentPos.pSubset IS SET TO NULL
>    THIS CAUSES THE NEXT FUNCTION TO CRASH *****/
> 
>        CurrentPos.pSubset->CloseList();
> 
>        delete CurrentPos.pSubset;
>        return(ERR);
>     }
>  return(0);
> }

> Anyway, if you think the call to AfxMessageBox() is changing one of these
> values, prove it: use the "Data" tab in the Breakpoint dialog, which is
> reachable by using the "Breakpoints" command in the "Edit" menu to set a
> breakpoint that fires when the value of that variable changes.

When I set a data Breakpoint, the program stops in CWinApp::DoMessageBox() 
in the line:

   MessageBox(pWnd->GetSafeHwnd(), lpszPrompt, m_pszAppName, nType);

The data breakpoint confirms that this pointer is changed at this time.

There are actually other variables in the CurrentPos structure.  They are also 
changed as well.

Harry Hahne
hahne@chass.utoronto.ca



Mike Blaszczak -- mikeblas@nwlink.com
Wednesday, November 27, 1996

[Mini-digest: 2 responses]

At 10:18 11/26/96 +0000, Harry Hahne wrote:
>Environment: Win 95, VC 4.1

>When I set a data Breakpoint, the program stops in CWinApp::DoMessageBox() 
>in the line:

>   MessageBox(pWnd->GetSafeHwnd(), lpszPrompt, m_pszAppName, nType);

>The data breakpoint confirms that this pointer is changed at this time.

Has it yet made the call to the API, or not?  It's pretty easy to show that
this code doesn't do anything but call the API.  This line of code generates
about a dozen lines of assembler code.

If the call to the API has been made, maybe something is happening on
a killfocus message in your application.  But, if that were the case,
it would seem that the debugger should have trapped on that message handler
and not here.

The evidence points at memory corruption in your application.

>There are actually other variables in the CurrentPos structure.  They are also 
>changed as well.

Is your pointer to the CurrentPos structure changed, or are the actual values
changed?  Nobody in CWinApp::DoMessageBox() is doing a memset().  Are the values
changed to something totally bogus, or are they changed to something
identifiable?

Just before this line of code, MFC goes looking for the thread state. 
Are you using multiple threads in your application?  Was your database access
via DAO or ODBC?  Do you have more than one CWinApp instance in your
application?
What message are you handling when you pop up this message box?

.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.

-----From: "Dean Wiles" 

Is your CurrentPos variable a global, member, or auto variable, and where
else does it get changed?  MessageBox won't mess with your data but it does
allow your message queue to run, so window messages like paint, focus, etc
will get dispatched.  Check the rest of your code or set some breakpoints
where CurrentPos can get changed - like maybe where SelectSubset() gets
called from.

Hope this helps. Dean.

--------------------------------------------------------------------------
Dean Wiles (deanw@mail.isc-br.com)          Olivetti North America
Phone:  (509)927-7037                       22425 East Appleway Ave
Fax:    (509)927-2499                       Liberty Lake, WA 99019-9534
If the Son sets you free, you will be free indeed.  (John 8:36)





| Вернуться в корень Архива |