AfxWinApp returns NULL

Anjeneya Murthy
Anjeneya Murthy used Ask the Experts™
on
HI,
One of the module in our application is crashing. When debugged the application, it was found that the WinAfxApp is returning NULL and this pointer is used causing the Access violation and crash.
Scenario:
The Application allows the user to acquires some images (screen shot) and also print the acquired images.
The user has acquired and image and then gave print command. if he does this several times very fast, the application crashed. On debugging this scenario, it was found that the AfxWinApp is returning NULL and is causing the problem.
Some findings from my debugging:
The crashes happens when the application is being acquired.
The print command creates one exe for each print that is passed to the printer. So when it crashes, there are many .exe's pending for printing (visible in process tab of task manager).
The crash happens consistently, but not consistent on the number of times it gets Acquired and printed. It crashes at the n-th time of the acquire print scenario.

I need help in understanding this AfxWinApp function and when it returns NULL.
Why did this return NULL all of a sudden when it worked fine for so many acquire print.
Please help me. its Urgent.
Thanks in Advance
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Firstly I have to ask if it is an MFC application.
Do you mean AfxGetApp() function?
It returns CWinApp* like:
CWinApp* pApp=AfxGetApp();
Probably, it is not NULL. Maybe pApp-->m_pszExeName is NULL or something like that?
Maybe you are talking about AfxGetMainWnd ?
 There is a special macro AFX_MANAGE_STATE, but this is about DLL: http://msdn.microsoft.com/en-us/library/ba9d5yh5(VS.80).aspx

Commented:
If you need only module handle you can use GetModuleHandle(NULL). This handle can be used in LoadResource function.
 
Anjeneya MurthySr. Consultant

Author

Commented:
Firstly I have to ask if it is an MFC application.
>>Yes It is MFC Application

Do you mean AfxGetApp() function?
>>Yes.

CWinApp* pApp=AfxGetApp();
Probably, it is not NULL. Maybe pApp-->m_pszExeName is NULL or something like that?
>> pApp is NULL and hence the call is something like NULL->m_pszExeName. This causes Access violation and crashes
CompTIA Network+

Prepare for the CompTIA Network+ exam by learning how to troubleshoot, configure, and manage both wired and wireless networks.

Commented:
AfxGetApp is not a kind of a complicated function. If you will set a breakpoint and get in into the function, you'll see yourself.
You didn't mention a DLL in your app - you know with the MFC DLL you need to use AFX_MANAGE_STATE macros.
I don't want to suggest a memory problem, but if you have such possibility, you can test the app with an error-detection tool such as BoundChecker or Purify+.
 
>>>> The print command creates one exe for each print that is passed to the printer.
Can you tell how that is implemented?

What application is crashing? One of the print apps or the main app which invokes the printings?

Note, an MFC app has a overloaded main function which creates (or uses) the one and only instance of your application class derived from CWinApp. The AFX framework stores a pointer to that instance when the constructor of the CWinApp baseclass was called. You can't create a second instance of your application class (or of any other CWinApp derived class) nor can you prevent an MFC framework to not creating an application class instance if you don't provide an own instance. So, if AfxGetApp returns NULL either the memory is corrupted, or you were calling it in a dll where the AFX system was not synchronised with that of the main exe. As pgnatyuk already told that was made using the AFX_MANAGE_STATE macro.

Anjeneya MurthySr. Consultant

Author

Commented:
Hi,
I was looking into the same issue. yes looks like sync issue.
I am providing some more info.. please help me resolve this..
There is a module which is a dll (with options: USE MFC IN A SHARED DLL and STATIC LINK TO ATL).
There is an application (.exe) where this AfxGetApp is called and returns NULL.
The dll calls AFX_MANAGE_STATE(AfxGetStaticModuleState()); in the method.
There is a COM call  from this method in dll to the exe . The COM call triggers a method in the (.exe) which intturn calls AfxGetApp method. This AfxGetApp returns NULL and is passed to the dll, which checks for the value and fails.
:(
And yes the exe does not use AFX_MANAGE_STATE(AfxGetStaticModuleState()); in any of the method.

Commented:
Do you need CWinApp* because...?
It can be eaiser to find an appropriate Win API that fil solve the question.
For example, GetModuleFileName will give you the name of the running executable - http://msdn.microsoft.com/en-us/library/ms683197(VS.85).aspx
GetModuleHandle() will give the handle if you need to retrieve a resource.
So what is the question? Just explain why AfxGetApp returns NULL?
 
Anjeneya MurthySr. Consultant

Author

Commented:
Hi pqnatyuk,
The code i am trying to debug is done years before. some how the issue floated up very recentely!!! Though this is issue is a corner case issue, it is reported by the customer and hence has high visibility and needs to be solved.
The Issue itself is to find why AfxGetApp returns NULL. If we get to know the exact reason for this Most probably the issue will be resolved.
Need to look at alternatives API's to get the instance. But for that we need to explain the whole development crowd for why i decided to change the existing API. Thats the toughest job. I Need to be clear as to why AfxGetApp is returning NULL and then suggest to change the API if required or need to look at other solution.
Thanks

Commented:
You are talking like I'm an employee in your company. :)

It is much easier to solve the problem if you see the source code and can debug it. So let's go from generic discussion to the real debugging session. I hope you easly reproduce the problem. It is great if it is reproducable in the debug mode also. If not, please add a tracer/logger and make a release. Put trace just on a high-level in few places to understand what are the conditions for this NULL from AfxGetApp. If you already know - please say.
You have said about a lot of executables generated by a main executable, but I didn't understand which of them causes the crash - the main executable? This executable has a DLL, but the AfxGetApp call is in the executable and not in DLL? Please correct me.

Commented:
There is nothing special in this function.
Just for test - can you change the project settings to use MFC in a static library instead of ".. share dll..".
You said that this is not a new application, so let's check this way. I really think it may help.
AFX_MODULE_STATE* AFXAPI AfxGetModuleState()
{
	_AFX_THREAD_STATE* pState = _afxThreadState;
	ENSURE(pState);
	AFX_MODULE_STATE* pResult;
	if (pState->m_pModuleState != NULL)
	{
		// thread state's module state serves as override
		pResult = pState->m_pModuleState;
	}
	else
	{
		// otherwise, use global app state
		pResult = _afxBaseModuleState.GetData();
	}
	ENSURE(pResult != NULL);
	return pResult;
}

Open in new window

Commented:
Please check this MSDN thread:
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/906e0ced-5188-4376-8d49-b273b0b119e9/
That was a change in the part we are talking about between VS 6 and 8.

Here are few other links:
AfxGetThread: http://msdn.microsoft.com/en-us/library/0aa1ya36(VS.80).aspx

CWinApp: The Application Class: http://msdn.microsoft.com/en-us/library/akdx0603(VS.71).aspx

Managing the State Data of MFC Modules: http://msdn.microsoft.com/en-us/library/0asx94f7(VS.71).aspx

I hope you have read. Otherwise we will talk different languages.

>>>> Just for test - can you change the project settings to use MFC in a static library instead of ".. share dll..".

No, if both the dll and the exe were using MFC that is not an option as both executables would hvae their own static member variables hence you couldn't exchange one lousy string between both without risking a crash. The only solution is to have both the dll and the executables use MFC in a dll so that the static members were defined in the MFC dll and both user dll and app were using the same.


>>>> There is a COM call  from this method in dll to the exe . The COM call triggers a method in the (.exe) which intturn calls AfxGetApp method. This AfxGetApp returns NULL and is passed to the dll, which checks for the value and fails.

Note, if a COM calls a method in an executable it was a callback which runs in the context of the COM (thread). Any call into the AFX nearly necessarily must fail (though I can't oversee all aspects of the AFX system within the very special environment you were describing).

I think the only way out is to post a message from the callback to a currently active window, e. g. the mainframe window. You probably have a chance to pass the HWND of the mainframe from the dll to COM. Then, you could handle that message in either the dll or the application (wherever runs the message loop of the window ehich gets the message) and there the AfxGetApp won't fail.

Anjeneya MurthySr. Consultant

Author

Commented:
>>Note, if a COM calls a method in an executable it was a callback which runs in the context of the >>COM (thread). Any call into the AFX nearly necessarily must fail (though I can't oversee all aspects of >>the AFX system within the very special environment you were describing).

I am not clear as to why the AFX fails when the call back runs in the context of COM thread? The COM component is a part of exe right? and my understanding is that the thread will also be part of this exe and when we call AfxGetApp with in this method, it should return the pointer to the application.
When I debugged the code by placing the TRACE statement, I found the method always returned the same exe pointer. But somehow at one point something goes wrong and returns NULL. This causes the error.

Commented:
What is strange for me is that it does not happen all the time.

"The AFX_MANAGE_STATE macro can be used inside of callbacks or custom window procedures to properly adjust the current module state, but it should be used with AfxGetAppModuleState() or a specific module state instance instead of AfxGetStaticModuleState()." - it is from an old http://support.microsoft.com/kb/161589

I found also an information when this macro cannot be used in the Extension DLL: http://support.microsoft.com/kb/161589
 
Anjeneya MurthySr. Consultant

Author

Commented:
Hi,
Sorry for Not sharing the code earlier. I have given the code below where m_pApp was becoming NULL.
Yes I mean m_pApp is becoming NULL. :)
Today I found that the AfxGetApp did not return NULL, but m_pApp became NULL because of the static cast.
From the code you (pqnatyuk) have provided above (AFX_MODULE_STATE* AFXAPI AfxGetModuleState() ), Always Line 14 should hit to get the correct pointer. But at one instance Line 9 was hit and returned a different pointer and made the static cast to assign NULL to m_pApp.
Still need to find why the code has hit Line 9 all of a sudden when it was all smooth hitting Line 14.

//Code in App.exe where m_pApp is becoming NULL
TClassAImp::TClassAImp()
{
	m_pApp = static_cast<TApp*>(::AfxGetApp());
	if(m_pApp)
	{
		TRACE1("TClassAImp:: %s\n", m_pApp->m_pszExeName);
	}
	else
	{	
		TRACE("TClassAImp:: m_pAPP is still NULL!!\n");		
	}
}

Open in new window

Commented:
You answering fast, so let's test one thing - replace this line:
m_pApp = static_cast<TApp*>(::AfxGetApp());
with:
m_pApp = (TApp*)(::AfxGetApp());
If the compiler will complain, please post the error.
It will be great, if you can show a top of the TApp class declaration. It is something like that:
class TApp : public CWinApp
and then you have few constructors and operators?
Is it possible that a mistake somewhere there and your app crashes/fails there?


Commented:
BTW, if you need only m_pszExeName, you don't need to cast.
AfxGetApp()->m_pszExeName.
Here is about the casting if you need: http://www.codeguru.com/cpp/tic/tic0277.shtml
 
Anjeneya MurthySr. Consultant

Author

Commented:
uff. My assumption was pResult is not NULL, then AfxGetApp is not NULL, But with out static cast also it returns NULL. I have attached the snapshot while I was debugging...

CodeError.JPG
CodeError2.JPG
CodeError3.JPG

Commented:
So let's test the following:
1. add AFX_MANAGE_STATE(AfxGetStaticModuleState()); here:
TClassAImp::TClassAImp()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_pApp = static_cast(::AfxGetApp());
....
}
and check how it will change m_pCurrentWinApp member of the pResult.
2. We can do the same with AfxGetAppModuleState() instead of AfxGetStaticModuleState());
3. It will be nice to see if we will add something like:
TCHAR szName[MAX_PATH] = { 0 };
::GetModuleFileName(szName, MAX_PATH);
and print it out.
Anjeneya MurthySr. Consultant

Author

Commented:
Quite Unfortunate. I tried this earlier and the application crashes somewhere else during startup. This method is being called from many places. if i modify something here, not sure where all it will start affecting.
The fact is the function that called this method DID have the AFX_MANAGE_STATE(AfxGetStaticModuleState()); at the start of its method.
But none of the methods in this class have AFX_MANAGE_STATE(AfxGetStaticModuleState());
I think this is causing the problem.
So I tried to put AFX_MANAGE_STATE(AfxGetStaticModuleState()); in all the methods which is declared STDMETHODIMP.
But still did not work as expected. Is there anything more I need to do To make it work other than just placing the AFX_MANAGE_STATE at the start of the methods?

Commented:
>> The fact is the function that called this method DID have the AFX_MANAGE_STATE(AfxGetStaticModuleState()); >> at the start of its method.
This function you are talking about is in another DLL? Right?
If all calls are in the same DLL you can debug this AFX_MANAGE_STATE and see what's going on there.
Have you teste GetModuleFileName? What is the result?
Anjeneya MurthySr. Consultant

Author

Commented:
Looks like the issue is solved by placing the AFX_MANAGE_STATE(AfxGetAppModuleState() );  
:D
But let me test it more rigoursly

This function you are talking about is in another DLL? Right?
The functions are in different modules. one in a dll another in .exe( a different process)
Will Reply in another few more mins...

Commented:
sounds good. I'm waiting. I'd really know what's going on on your side.
Anjeneya MurthySr. Consultant

Author

Commented:
I tried several times and still did not crash... hopefully this is the solution...
I am asking some more ppl in my ppl to test this and try crashing!!! :)
If this is the solution... I want to know more abt what difference does it make to have
AFX_MANAGE_STATE(AfxGetAppModuleState() );   instead of
AFX_MANAGE_STATE(AfxGetStaticModuleState());
Please clarify me. I tried in google and could not get much of info.. please tell me. I may have to answer this question
Commented:
24948910 - it's in this comment.
http://support.microsoft.com/kb/161589
It's about MFC 4 but... helped:
"The AFX_MANAGE_STATE macro can be used inside of callbacks or custom window procedures to properly adjust the current module state, but it should be used with AfxGetAppModuleState() or a specific module state instance instead of AfxGetStaticModuleState()."
You can find a thread here about the Extension DLL:
http://www.experts-exchange.com/Programming/Languages/CPP/Q_10221529.html
 I remember this thing because of the ATL:
http://support.microsoft.com/kb/231592
http://support.microsoft.com/kb/173974
Here is more explanation: http://www.codeproject.com/KB/COM/ActiveXMfcState.aspx
There is "How to Manage the MFC State" section.
I've not seen the application. I can guess that there are few threads in different dlls and these threads interacts somehow.
The forgotten COM was a good school for such things.
Anjeneya MurthySr. Consultant

Author

Commented:
People are testing this solution tomorrow. In the mean time I am still filled with some doubts....
1. Even with out this macro how was the AfxGetApp() returned the correct pointer several times? It should not change the state automatically since we have not used the macro at all
2. There are many other methods that do not have this macro at the start of their methods and still working fine!! I am facing this question now :)
3. Should this macro really go in all the methods of the class/module? or is it like if any one of the method has the macro that is called first in that specific module will suffice?
Can you please clarify me.... I will also keep searching for answer to these questions...

Thanks

Commented:
Keep searching. Let me know if you'll find something.
I'm okay with the MSDN explanations. You have mutli-threaded multi-component application. With MFC and, probably ATL. Its is avery heavy thing. You've seen the code of the function that failed - we can guess that these set of function Set/Get state does not work fast (In the same situation I'd think that I use that mechanism in a wrong way).
In such cases I avoid to use the MFC - it is a wrapper for Windows API and sometimes it takes to long to understand how exactly it was wrapped. But it is only my private opinion and I don't want somehow influence on your choice.
This application is your responsibility. Points for that question are mine. :)
Anjeneya MurthySr. Consultant

Author

Commented:
I give full points to you for this question whole heartedly. ITS YOURS :)
Anjeneya MurthySr. Consultant

Author

Commented:
Thanks a lot for supporting. EE rocks :)

Commented:
Thanks.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial