From: eliza on 11 Jun 2010 09:44 At times it is possible that some operations work fine in Debug mode but not in Release mode and vice-versa. Here are the some of the common errors that lead us to the above problem. 1. In general, the default value of an uninitialzed variable is garbage in Debug and zero in Release . So, the following code works fine in Debug and not in Release . int enabled; if( enabled ) DoSomeThing(); So, Please initialise when a variable is declared. 2. One of the main difference in Debug and Release is Optimization. We can set this from Properties -> C/C++ -> Optimization. http://www.mindfiresolutions.com/Debug-works-fine-but-not-in-Release-and-viceversa-673.php fangtu101 wrote: Release build crashes when creating dialog from DLL 16-May-07 Hi, We are developing an application using MFC, and it works fine in Debug. However, the release build crashes when creating a dialog. The call is from a DLL in case that matters any. At the time of the crash, the call stack looks as shown below, with the top of the call stack being CFrameWnd::OnActivateTopLevel. CFrameWnd::OnActivateTopLevel CWnd::OnWndMsg CWnd::WindowProc AfxCallWndProc AfxWndProc AfxWndProcBase user32.dll Win32 function SetWindowPos was being called in user32.dll at the time of the crash. Further down in the stack (the stack frames below user32 were claimed to not be valid) the original MFC call was to CWnd::SetWindowPos(). We also tried directly calling the Win32 function SetWindowPos(), but the crash was identical, including the call stack. At the time of the crash, the message that appears is as shown below. Unhandled exception at 0x7831726a (mfc80u.dll) in teams.exe: 0xC0000005: Access violation reading location 0x00000020. Looking at the disassembly of the code at this time, there was a null pointer that was being used to read memory at an offset of 20h. Any help on how this problem can be solved would be appreciated. Thanks in advance. Tiger Previous Posts In This Thread: On Wednesday, May 16, 2007 5:34 PM fangtu101 wrote: Release build crashes when creating dialog from DLL Hi, We are developing an application using MFC, and it works fine in Debug. However, the release build crashes when creating a dialog. The call is from a DLL in case that matters any. At the time of the crash, the call stack looks as shown below, with the top of the call stack being CFrameWnd::OnActivateTopLevel. CFrameWnd::OnActivateTopLevel CWnd::OnWndMsg CWnd::WindowProc AfxCallWndProc AfxWndProc AfxWndProcBase user32.dll Win32 function SetWindowPos was being called in user32.dll at the time of the crash. Further down in the stack (the stack frames below user32 were claimed to not be valid) the original MFC call was to CWnd::SetWindowPos(). We also tried directly calling the Win32 function SetWindowPos(), but the crash was identical, including the call stack. At the time of the crash, the message that appears is as shown below. Unhandled exception at 0x7831726a (mfc80u.dll) in teams.exe: 0xC0000005: Access violation reading location 0x00000020. Looking at the disassembly of the code at this time, there was a null pointer that was being used to read memory at an offset of 20h. Any help on how this problem can be solved would be appreciated. Thanks in advance. Tiger On Wednesday, May 16, 2007 5:56 PM David Lowndes wrote: You're not mixing a release build of the EXE with a debug DLL (orvice-versa) You're not mixing a release build of the EXE with a debug DLL (or vice-versa) are you? What's the function definition that you are calling? Are there any heap allocated items involved? Dave On Wednesday, May 16, 2007 10:51 PM Joseph M. Newcomer wrote: As already pointed out, make sure you aren't mixing debug and release As already pointed out, make sure you aren't mixing debug and release components. You can also check out my essay "Surviving the release version" on my MVP TIps site. Note that VS2005 always produces a .pdb file for new projects. joe On 16 May 2007 14:34:13 -0700, fangtu1015(a)gmail.com wrote: Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm On Thursday, May 17, 2007 10:09 AM fangtu101 wrote: Re: Release build crashes when creating dialog from DLL On May 16, 5:56 pm, David Lowndes <Dav...(a)example.invalid> wrote: We are using a release DLL and release EXE. The DLL is being dynamically loaded. Incidentally, what problems would be likely to occur if a debug version of a DLL is used? I ask this because we will be potentially allowing third-party DLLs (plug-ins), and we want to allow as much flexibility as possible. The function being called is CWnd::SetWindowPos(). We also tried obtaining a handle to the window, verifying that the handle is valid, and then calling the Win32 function SetWindowPos(). Interestingly, even the Win32 function called the MFC functions, so it appears that it has a hook that calls them for an MFC application. In either case the crash was at the same location. The crash occurs at the commented line in the partial disassembly of CFrameWnd::OnActivateTopLevel that is shown below. // deactivate current active view CWinThread *pThread = AfxGetThread(); 78317262 call AfxGetModuleThreadState (7830F39Fh) ASSERT(pThread); if (pThread->m_pMainWnd == this) 78317267 mov eax,dword ptr [eax+4] ; ******************** eax appears to be a valid pointer here (at least nonzero) 7831726A cmp dword ptr [eax+20h],esi ; ****************** CRASH IS HERE! -- eax = 0 -> null pointer (but esi appears to be a valid "this" pointer) 7831726D jne CFrameWnd::OnActivateTopLevel+7Ch (78317299h) Thanks again for any suggestions. Tiger On Thursday, May 17, 2007 11:06 AM David Lowndes wrote: If you pass any run-time allocated objects between the EXE/DLLboundary and If you pass any run-time allocated objects between the EXE/DLL boundary and expect to allocate or free them across the boundary, it will only work if both components use the same shared (DLL) version of the run-time libraries. This ties all components to be built with the same version of the tools, and prevents mixing debug/release components. Keep your DLL interfaces to plain old data types and you shouldn't have any problems. I meant the definition of the exported function in your DLL. Dave On Thursday, May 17, 2007 1:22 PM fangtu101 wrote: Re: Release build crashes when creating dialog from DLL On May 16, 5:56 pm, David Lowndes <Dav...(a)example.invalid> wrote: Hi Dave, Sorry if this reply is a repeat -- my first one did not appear for several hours. We are using a release build of the DLL with a release build of the EXE. The DLL is being dynamically loaded. Incidentally, what problems would occur if a debug build of the DLL is used? I ask this question because a similar DLL may possibly be developed by a third party as a plug-in to our main application. The function called is CWnd:SetWindowPos(). We have also tried obtaining a handle to the window, testing if it is vaild, and calling Win32 function SetWindowPos(). Both failed at the same location. Interestingly, it appears that there is a hook in the Win32 SetWindowPos() to call MFC functions in an MFC application. Regarding the allocation question, it is doubtful that this is the problem because we have run DevPartner without seeing any memory allocation problems, except internal to MFC. (There were a few instances where DevPartner stated that free() was being used to release memory allocated by HeapAlloc(). At the time of the crash, the program is executing CFrameWnd::OnActivateTopLevel(), which is disassembled at the point of the crash below. // deactivate current active view CWinThread *pThread = AfxGetThread(); 78317262 call AfxGetModuleThreadState (7830F39Fh) ASSERT(pThread); if (pThread->m_pMainWnd == this) 78317267 mov eax,dword ptr [eax+4] ; ******* eax appears to be a valid pointer before mov 7831726A cmp dword ptr [eax+20h],esi ; ******* CRASH HERE!!! eax = 0 (null pointer), but esi appears to be a valid "this" pointer 7831726D jne CFrameWnd::OnActivateTopLevel+7Ch (78317299h) Thanks again for any assistance! Tiger On Thursday, May 24, 2007 11:10 AM fangtu101 wrote: Finally we found the reason for the crash. Finally we found the reason for the crash. The DLL we build is a dynamically linked MFC dll and it has its own CWinApp object. Before calling the function in the DLL to launch a dialog, I added AFX_MANAGE_STATE(AfxGetStaticModuleState( )); to switch the module state for the resource handle to point to the DLL's own CWinApp object. After that, the code works fine. Besides, we found in the Debug build of the DLL, when the function in the DLL to launch a dialog is called by the main application, AfxGetApp() returns the handle to the main application's CWinApp object, so the program does not crash (although this is not right). However, in the release build, AfxGetApp() returns NULL pointer if the module state is not switched using AFX_MANAGE_STATE(). That causes the crash. Following is what we found in MSDN that is related to our problem: "By default, MFC uses the resource handle of the main application to load the resource template. If you have an exported function in a DLL, such as one that launches a dialog box in the DLL, this template is actually stored in the DLL module. You need to switch the module state for the correct handle to be used. You can do this by adding the following code to the beginning of the function: AFX_MANAGE_STATE(AfxGetStaticModuleState( ));" and also: "The ability to dynamically link a regular DLL to the MFC DLL allows some configurations that are very complicated. For example, a regular DLL and the executable that uses it can both dynamically link to the MFC DLL and to any extension DLLs. This configuration poses a problem with regard to the MFC global data, such as the pointer to the current CWinApp object and handle maps. Before MFC version 4.0, this global data resided in the MFC DLL itself and was shared by all the modules in the process. Because each process using a Win32 DLL gets its own copy of the DLL's data, this scheme provided an easy way to track per-process data. Also, because the AFXDLL model presumed that there would be only one CWinApp object and only one set of handle maps in the process, these items could be tracked in the MFC DLL itself. But with the ability to dynamically link a regular DLL to the MFC DLL, it is now possible to have two or more CWinApp objects in a process - and also two or more sets of handle maps. How does MFC keep track of which ones it should be using? The solution is to give each module (application or regular DLL) its own copy of this global state information. Thus, a call to AfxGetApp in the regular DLL returns a pointer to the CWinApp object in the DLL, not the one in the executable. This per-module copy of the MFC global data is known as a module state and is described in MFC Tech Note 58. The MFC common window procedure automatically switches to the correct module state, so you do not need to worry about it in any message handlers implemented in your regular DLL. But when your executable calls into the regular DLL, you do need to explicitly set the current module state to the one for the DLL. To do this, use the AFX_MANAGE_STATE macro in every function exported from the DLL. This is done by adding the following line of code to the beginning of functions exported from the DLL: AFX_MANAGE_STATE(AfxGetStaticModuleState( ))" On Thursday, May 24, 2007 11:46 AM Tom Serface wrote: Hi fangtu,THanks for posting this reply. Hi fangtu, THanks for posting this reply. I am sure others could experience similar problems and it is great to have this documented. Tom Submitted via EggHeadCafe - Software Developer Portal of Choice ASP.NET GridView: Select Row and Display Item Detail http://www.eggheadcafe.com/tutorials/aspnet/ff14a008-2af9-4f9d-a09d-1af670466a80/aspnet-gridview-select.aspx
From: Tom Serface on 11 Jun 2010 10:12 Is this a question or are you just providing information? Just want to be sure. The threads you quote seem pretty old. Maybe you are just trying to point people to your article? Tom "eliza sahoo" wrote in message news:201061194434eliza.sahoo(a)gmail.com... > At times it is possible that some operations work fine in Debug mode but > not in Release mode and vice-versa. > > Here are the some of the common errors that lead us to the above problem. > > 1. In general, the default value of an uninitialzed variable is garbage in > Debug and zero in Release . > > So, the following code works fine in Debug and not in Release . > > int enabled; > if( enabled ) > DoSomeThing(); > > So, Please initialise when a variable is declared. > 2. One of the main difference in Debug and Release is Optimization. > > We can set this from Properties -> C/C++ -> Optimization. > > http://www.mindfiresolutions.com/Debug-works-fine-but-not-in-Release-and-viceversa-673.php > > > > fangtu101 wrote: > > Release build crashes when creating dialog from DLL > 16-May-07 > > Hi, > > We are developing an application using MFC, and it works fine in > Debug. However, the release build crashes when creating a dialog. The > call is from a DLL in case that matters any. At the time of the crash, > the call stack looks as shown below, with the top of the call stack > being CFrameWnd::OnActivateTopLevel. > > CFrameWnd::OnActivateTopLevel > CWnd::OnWndMsg > CWnd::WindowProc > AfxCallWndProc > AfxWndProc > AfxWndProcBase > user32.dll > > Win32 function SetWindowPos was being called in user32.dll at the time > of the crash. Further down in the stack (the stack frames below > user32 were claimed to not be valid) the original MFC call was to > CWnd::SetWindowPos(). We also tried directly calling the Win32 > function SetWindowPos(), but the crash was identical, including the > call stack. > > At the time of the crash, the message that appears is as shown below. > Unhandled exception at 0x7831726a (mfc80u.dll) in teams.exe: > 0xC0000005: Access violation reading location 0x00000020. > > Looking at the disassembly of the code at this time, there was a null > pointer that was being used to read memory at an offset of 20h. > > Any help on how this problem can be solved would be appreciated. > Thanks in advance. > > Tiger > > Previous Posts In This Thread: > > On Wednesday, May 16, 2007 5:34 PM > fangtu101 wrote: > > Release build crashes when creating dialog from DLL > Hi, > > We are developing an application using MFC, and it works fine in > Debug. However, the release build crashes when creating a dialog. The > call is from a DLL in case that matters any. At the time of the crash, > the call stack looks as shown below, with the top of the call stack > being CFrameWnd::OnActivateTopLevel. > > CFrameWnd::OnActivateTopLevel > CWnd::OnWndMsg > CWnd::WindowProc > AfxCallWndProc > AfxWndProc > AfxWndProcBase > user32.dll > > Win32 function SetWindowPos was being called in user32.dll at the time > of the crash. Further down in the stack (the stack frames below > user32 were claimed to not be valid) the original MFC call was to > CWnd::SetWindowPos(). We also tried directly calling the Win32 > function SetWindowPos(), but the crash was identical, including the > call stack. > > At the time of the crash, the message that appears is as shown below. > Unhandled exception at 0x7831726a (mfc80u.dll) in teams.exe: > 0xC0000005: Access violation reading location 0x00000020. > > Looking at the disassembly of the code at this time, there was a null > pointer that was being used to read memory at an offset of 20h. > > Any help on how this problem can be solved would be appreciated. > Thanks in advance. > > Tiger > > On Wednesday, May 16, 2007 5:56 PM > David Lowndes wrote: > > You're not mixing a release build of the EXE with a debug DLL > (orvice-versa) > You're not mixing a release build of the EXE with a debug DLL (or > vice-versa) are you? > > What's the function definition that you are calling? Are there any heap > allocated items involved? > > Dave > > On Wednesday, May 16, 2007 10:51 PM > Joseph M. Newcomer wrote: > > As already pointed out, make sure you aren't mixing debug and release > As already pointed out, make sure you aren't mixing debug and release > components. You can > also check out my essay "Surviving the release version" on my MVP TIps > site. Note that > VS2005 always produces a .pdb file for new projects. > joe > On 16 May 2007 14:34:13 -0700, fangtu1015(a)gmail.com wrote: > > Joseph M. Newcomer [MVP] > email: newcomer(a)flounder.com > Web: http://www.flounder.com > MVP Tips: http://www.flounder.com/mvp_tips.htm > > On Thursday, May 17, 2007 10:09 AM > fangtu101 wrote: > > Re: Release build crashes when creating dialog from DLL > On May 16, 5:56 pm, David Lowndes <Dav...(a)example.invalid> wrote: > > We are using a release DLL and release EXE. The DLL is being > dynamically loaded. > Incidentally, what problems would be likely to occur if a debug > version of a DLL is used? > I ask this because we will be potentially allowing third-party DLLs > (plug-ins), and we > want to allow as much flexibility as possible. > > The function being called is CWnd::SetWindowPos(). We also tried > obtaining a handle > to the window, verifying that the handle is valid, and then calling > the Win32 > function SetWindowPos(). Interestingly, even the Win32 function > called the MFC > functions, so it appears that it has a hook that calls them for an MFC > application. > In either case the crash was at the same location. > > The crash occurs at the commented line in the partial disassembly of > CFrameWnd::OnActivateTopLevel > that is shown below. > > // deactivate current active view > CWinThread *pThread = AfxGetThread(); > 78317262 call AfxGetModuleThreadState (7830F39Fh) > ASSERT(pThread); > if (pThread->m_pMainWnd == this) > 78317267 mov eax,dword ptr [eax+4] ; > ******************** eax appears to be a valid pointer here (at least > nonzero) > 7831726A cmp dword ptr [eax+20h],esi ; > ****************** CRASH IS HERE! -- eax = 0 -> null pointer (but esi > appears to be a valid "this" pointer) > 7831726D jne CFrameWnd::OnActivateTopLevel+7Ch (78317299h) > > Thanks again for any suggestions. > > Tiger > > On Thursday, May 17, 2007 11:06 AM > David Lowndes wrote: > > If you pass any run-time allocated objects between the EXE/DLLboundary and > If you pass any run-time allocated objects between the EXE/DLL > boundary and expect to allocate or free them across the boundary, it > will only work if both components use the same shared (DLL) version of > the run-time libraries. This ties all components to be built with the > same version of the tools, and prevents mixing debug/release > components. > > > Keep your DLL interfaces to plain old data types and you shouldn't > have any problems. > > > I meant the definition of the exported function in your DLL. > > Dave > > On Thursday, May 17, 2007 1:22 PM > fangtu101 wrote: > > Re: Release build crashes when creating dialog from DLL > On May 16, 5:56 pm, David Lowndes <Dav...(a)example.invalid> wrote: > > Hi Dave, > > Sorry if this reply is a repeat -- my first one did not appear for > several hours. > We are using a release build of the DLL with a release build of the > EXE. > The DLL is being dynamically loaded. Incidentally, what problems > would > occur if a debug build of the DLL is used? I ask this question > because > a similar DLL may possibly be developed by a third party as a plug-in > to our > main application. > > The function called is CWnd:SetWindowPos(). We have also tried > obtaining > a handle to the window, testing if it is vaild, and calling Win32 > function > SetWindowPos(). Both failed at the same location. Interestingly, it > appears that there is a hook in the Win32 SetWindowPos() to call MFC > functions in an MFC application. > > Regarding the allocation question, it is doubtful that this is the > problem because > we have run DevPartner without seeing any memory allocation problems, > except internal to MFC. (There were a few instances where DevPartner > stated that free() was being used to release memory allocated by > HeapAlloc(). > > At the time of the crash, the program is executing > CFrameWnd::OnActivateTopLevel(), > which is disassembled at the point of the crash below. > > // deactivate current active view > CWinThread *pThread = AfxGetThread(); > 78317262 call AfxGetModuleThreadState (7830F39Fh) > ASSERT(pThread); > if (pThread->m_pMainWnd == this) > 78317267 mov eax,dword ptr [eax+4] ; ******* eax > appears to be a valid pointer before mov > 7831726A cmp dword ptr [eax+20h],esi ; ******* CRASH > HERE!!! eax = 0 (null pointer), but esi appears to be a valid "this" > pointer > 7831726D jne CFrameWnd::OnActivateTopLevel+7Ch (78317299h) > > Thanks again for any assistance! > > Tiger > > On Thursday, May 24, 2007 11:10 AM > fangtu101 wrote: > > Finally we found the reason for the crash. > Finally we found the reason for the crash. The DLL we build is a > dynamically linked MFC dll and it has its own CWinApp object. Before > calling the function in the DLL to launch a dialog, I added > AFX_MANAGE_STATE(AfxGetStaticModuleState( )); to switch the module > state for the resource handle to point to the DLL's own CWinApp > object. After that, the code works fine. > > Besides, we found in the Debug build of the DLL, when the function in > the DLL to launch a dialog is called by the main application, > AfxGetApp() returns the handle to the main application's CWinApp > object, so the program does not crash (although this is not right). > However, in the release build, AfxGetApp() returns NULL pointer if the > module state is not switched using AFX_MANAGE_STATE(). That causes the > crash. > > > Following is what we found in MSDN that is related to our problem: > > "By default, MFC uses the resource handle of the main application to > load the resource template. If you have an exported function in a DLL, > such as one that launches a dialog box in the DLL, this template is > actually stored in the DLL module. You need to switch the module state > for the correct handle to be used. You can do this by adding the > following code to the beginning of the function: > > AFX_MANAGE_STATE(AfxGetStaticModuleState( ));" > > and also: > "The ability to dynamically link a regular DLL to the MFC DLL allows > some configurations that are very complicated. For example, a regular > DLL and the executable that uses it can both dynamically link to the > MFC DLL and to any extension DLLs. > > This configuration poses a problem with regard to the MFC global data, > such as the pointer to the current CWinApp object and handle maps. > > Before MFC version 4.0, this global data resided in the MFC DLL itself > and was shared by all the modules in the process. Because each process > using a Win32 DLL gets its own copy of the DLL's data, this scheme > provided an easy way to track per-process data. Also, because the > AFXDLL model presumed that there would be only one CWinApp object and > only one set of handle maps in the process, these items could be > tracked in the MFC DLL itself. > > But with the ability to dynamically link a regular DLL to the MFC DLL, > it is now possible to have two or more CWinApp objects in a process - > and also two or more sets of handle maps. How does MFC keep track of > which ones it should be using? > > The solution is to give each module (application or regular DLL) its > own copy of this global state information. Thus, a call to AfxGetApp > in the regular DLL returns a pointer to the CWinApp object in the DLL, > not the one in the executable. This per-module copy of the MFC global > data is known as a module state and is described in MFC Tech Note 58. > > The MFC common window procedure automatically switches to the correct > module state, so you do not need to worry about it in any message > handlers implemented in your regular DLL. But when your executable > calls into the regular DLL, you do need to explicitly set the current > module state to the one for the DLL. To do this, use the > AFX_MANAGE_STATE macro in every function exported from the DLL. This > is done by adding the following line of code to the beginning of > functions exported from the DLL: > > AFX_MANAGE_STATE(AfxGetStaticModuleState( ))" > > On Thursday, May 24, 2007 11:46 AM > Tom Serface wrote: > > Hi fangtu,THanks for posting this reply. > Hi fangtu, > > THanks for posting this reply. I am sure others could experience similar > problems and it is great to have this documented. > > Tom > > > Submitted via EggHeadCafe - Software Developer Portal of Choice > ASP.NET GridView: Select Row and Display Item Detail > http://www.eggheadcafe.com/tutorials/aspnet/ff14a008-2af9-4f9d-a09d-1af670466a80/aspnet-gridview-select.aspx
From: Joseph M. Newcomer on 11 Jun 2010 13:50 See below.... On Fri, 11 Jun 2010 06:44:37 -0700, eliza sahoo wrote: > >At times it is possible that some operations work fine in Debug mode but not in Release mode and vice-versa. > >Here are the some of the common errors that lead us to the above problem. > >1. In general, the default value of an uninitialzed variable is garbage in Debug and zero in Release . **** In this you are completely wrong. In general, the default value of an uninitialized variable is a very carefully specified invalid value in Debug mode, and some completely indeterminate value in Release mode. In your example, the value will be 0xCCCCCCCC in debug mode and completely unpredictable in release mode, so MAYBE it will think the value is true and MAYBE it won't, but only an idiot would declare a boolean value as an 'int' variable (yes, I know BOOL is just 'int' in sheep's clothing, but it really isn't the same) ***** > > So, the following code works fine in Debug and not in Release . > > int enabled; > if( enabled ) > DoSomeThing(); > > So, Please initialise when a variable is declared. **** Note also that if you had turned on the correct debug /RTC flags, you would have gotten a runtime error about the use of an uninitialized local variable, but this shows you are probably still using the long-dead VS6 for development, not one of the current versions of VS. So the whole discussion above is both erroneous and nonsense. **** >2. One of the main difference in Debug and Release is Optimization. > > We can set this from Properties -> C/C++ -> Optimization. > >http://www.mindfiresolutions.com/Debug-works-fine-but-not-in-Release-and-viceversa-673.php > **** And what does this have to do with anything? In general, a program that does not run when full optimization is enabled was erroneous to start with, but the lack of optimization accidentally concealed the errors. I have yet to find an optimizer-related bug in the compiler, but I have found several cases where the lack of optimization concealed a genuine bug in the code. Yes, I know sometimes code runs in debug and not in release, and I've even written an essay on that topic, but at least I did not make egregiuos errors like claiming that in release mode local variables are initialized to zero. That statement is stupid. **** > > >fangtu101 wrote: > >Release build crashes when creating dialog from DLL >16-May-07 > >Hi, > >We are developing an application using MFC, and it works fine in >Debug. However, the release build crashes when creating a dialog. The >call is from a DLL in case that matters any. At the time of the crash, >the call stack looks as shown below, with the top of the call stack >being CFrameWnd::OnActivateTopLevel. > >CFrameWnd::OnActivateTopLevel > CWnd::OnWndMsg > CWnd::WindowProc > AfxCallWndProc > AfxWndProc > AfxWndProcBase > user32.dll > >Win32 function SetWindowPos was being called in user32.dll at the time >of the crash. Further down in the stack (the stack frames below >user32 were claimed to not be valid) the original MFC call was to >CWnd::SetWindowPos(). We also tried directly calling the Win32 >function SetWindowPos(), but the crash was identical, including the >call stack. > >At the time of the crash, the message that appears is as shown below. >Unhandled exception at 0x7831726a (mfc80u.dll) in teams.exe: >0xC0000005: Access violation reading location 0x00000020. > >Looking at the disassembly of the code at this time, there was a null >pointer that was being used to read memory at an offset of 20h. > >Any help on how this problem can be solved would be appreciated. >Thanks in advance. > >Tiger > >Previous Posts In This Thread: > >On Wednesday, May 16, 2007 5:34 PM >fangtu101 wrote: > >Release build crashes when creating dialog from DLL >Hi, > >We are developing an application using MFC, and it works fine in >Debug. However, the release build crashes when creating a dialog. The >call is from a DLL in case that matters any. At the time of the crash, >the call stack looks as shown below, with the top of the call stack >being CFrameWnd::OnActivateTopLevel. > >CFrameWnd::OnActivateTopLevel > CWnd::OnWndMsg > CWnd::WindowProc > AfxCallWndProc > AfxWndProc > AfxWndProcBase > user32.dll > >Win32 function SetWindowPos was being called in user32.dll at the time >of the crash. Further down in the stack (the stack frames below >user32 were claimed to not be valid) the original MFC call was to >CWnd::SetWindowPos(). We also tried directly calling the Win32 >function SetWindowPos(), but the crash was identical, including the >call stack. > >At the time of the crash, the message that appears is as shown below. >Unhandled exception at 0x7831726a (mfc80u.dll) in teams.exe: >0xC0000005: Access violation reading location 0x00000020. > >Looking at the disassembly of the code at this time, there was a null >pointer that was being used to read memory at an offset of 20h. > >Any help on how this problem can be solved would be appreciated. >Thanks in advance. > >Tiger > >On Wednesday, May 16, 2007 5:56 PM >David Lowndes wrote: > >You're not mixing a release build of the EXE with a debug DLL (orvice-versa) >You're not mixing a release build of the EXE with a debug DLL (or >vice-versa) are you? > >What's the function definition that you are calling? Are there any heap >allocated items involved? > >Dave > >On Wednesday, May 16, 2007 10:51 PM >Joseph M. Newcomer wrote: > >As already pointed out, make sure you aren't mixing debug and release >As already pointed out, make sure you aren't mixing debug and release components. You can >also check out my essay "Surviving the release version" on my MVP TIps site. Note that >VS2005 always produces a .pdb file for new projects. > joe >On 16 May 2007 14:34:13 -0700, fangtu1015(a)gmail.com wrote: > >Joseph M. Newcomer [MVP] >email: newcomer(a)flounder.com >Web: http://www.flounder.com >MVP Tips: http://www.flounder.com/mvp_tips.htm > >On Thursday, May 17, 2007 10:09 AM >fangtu101 wrote: > >Re: Release build crashes when creating dialog from DLL >On May 16, 5:56 pm, David Lowndes <Dav...(a)example.invalid> wrote: > >We are using a release DLL and release EXE. The DLL is being >dynamically loaded. >Incidentally, what problems would be likely to occur if a debug >version of a DLL is used? >I ask this because we will be potentially allowing third-party DLLs >(plug-ins), and we >want to allow as much flexibility as possible. > >The function being called is CWnd::SetWindowPos(). We also tried >obtaining a handle >to the window, verifying that the handle is valid, and then calling >the Win32 >function SetWindowPos(). Interestingly, even the Win32 function >called the MFC >functions, so it appears that it has a hook that calls them for an MFC >application. >In either case the crash was at the same location. > >The crash occurs at the commented line in the partial disassembly of >CFrameWnd::OnActivateTopLevel >that is shown below. > > // deactivate current active view > CWinThread *pThread = AfxGetThread(); >78317262 call AfxGetModuleThreadState (7830F39Fh) > ASSERT(pThread); > if (pThread->m_pMainWnd == this) >78317267 mov eax,dword ptr [eax+4] ; >******************** eax appears to be a valid pointer here (at least >nonzero) >7831726A cmp dword ptr [eax+20h],esi ; >****************** CRASH IS HERE! -- eax = 0 -> null pointer (but esi >appears to be a valid "this" pointer) >7831726D jne CFrameWnd::OnActivateTopLevel+7Ch (78317299h) > >Thanks again for any suggestions. > >Tiger > >On Thursday, May 17, 2007 11:06 AM >David Lowndes wrote: > >If you pass any run-time allocated objects between the EXE/DLLboundary and >If you pass any run-time allocated objects between the EXE/DLL >boundary and expect to allocate or free them across the boundary, it >will only work if both components use the same shared (DLL) version of >the run-time libraries. This ties all components to be built with the >same version of the tools, and prevents mixing debug/release >components. > > >Keep your DLL interfaces to plain old data types and you shouldn't >have any problems. > > >I meant the definition of the exported function in your DLL. > >Dave > >On Thursday, May 17, 2007 1:22 PM >fangtu101 wrote: > >Re: Release build crashes when creating dialog from DLL >On May 16, 5:56 pm, David Lowndes <Dav...(a)example.invalid> wrote: > >Hi Dave, > >Sorry if this reply is a repeat -- my first one did not appear for >several hours. >We are using a release build of the DLL with a release build of the >EXE. >The DLL is being dynamically loaded. Incidentally, what problems >would >occur if a debug build of the DLL is used? I ask this question >because >a similar DLL may possibly be developed by a third party as a plug-in >to our >main application. > >The function called is CWnd:SetWindowPos(). We have also tried >obtaining >a handle to the window, testing if it is vaild, and calling Win32 >function >SetWindowPos(). Both failed at the same location. Interestingly, it >appears that there is a hook in the Win32 SetWindowPos() to call MFC >functions in an MFC application. > >Regarding the allocation question, it is doubtful that this is the >problem because >we have run DevPartner without seeing any memory allocation problems, >except internal to MFC. (There were a few instances where DevPartner >stated that free() was being used to release memory allocated by >HeapAlloc(). > >At the time of the crash, the program is executing >CFrameWnd::OnActivateTopLevel(), >which is disassembled at the point of the crash below. > > // deactivate current active view > CWinThread *pThread = AfxGetThread(); >78317262 call AfxGetModuleThreadState (7830F39Fh) > ASSERT(pThread); > if (pThread->m_pMainWnd == this) >78317267 mov eax,dword ptr [eax+4] ; ******* eax >appears to be a valid pointer before mov >7831726A cmp dword ptr [eax+20h],esi ; ******* CRASH >HERE!!! eax = 0 (null pointer), but esi appears to be a valid "this" >pointer >7831726D jne CFrameWnd::OnActivateTopLevel+7Ch (78317299h) > >Thanks again for any assistance! > >Tiger > >On Thursday, May 24, 2007 11:10 AM >fangtu101 wrote: > >Finally we found the reason for the crash. >Finally we found the reason for the crash. The DLL we build is a >dynamically linked MFC dll and it has its own CWinApp object. Before >calling the function in the DLL to launch a dialog, I added >AFX_MANAGE_STATE(AfxGetStaticModuleState( )); to switch the module >state for the resource handle to point to the DLL's own CWinApp >object. After that, the code works fine. > >Besides, we found in the Debug build of the DLL, when the function in >the DLL to launch a dialog is called by the main application, >AfxGetApp() returns the handle to the main application's CWinApp >object, so the program does not crash (although this is not right). >However, in the release build, AfxGetApp() returns NULL pointer if the >module state is not switched using AFX_MANAGE_STATE(). That causes the >crash. > > >Following is what we found in MSDN that is related to our problem: > >"By default, MFC uses the resource handle of the main application to >load the resource template. If you have an exported function in a DLL, >such as one that launches a dialog box in the DLL, this template is >actually stored in the DLL module. You need to switch the module state >for the correct handle to be used. You can do this by adding the >following code to the beginning of the function: > >AFX_MANAGE_STATE(AfxGetStaticModuleState( ));" > >and also: >"The ability to dynamically link a regular DLL to the MFC DLL allows >some configurations that are very complicated. For example, a regular >DLL and the executable that uses it can both dynamically link to the >MFC DLL and to any extension DLLs. > >This configuration poses a problem with regard to the MFC global data, >such as the pointer to the current CWinApp object and handle maps. > >Before MFC version 4.0, this global data resided in the MFC DLL itself >and was shared by all the modules in the process. Because each process >using a Win32 DLL gets its own copy of the DLL's data, this scheme >provided an easy way to track per-process data. Also, because the >AFXDLL model presumed that there would be only one CWinApp object and >only one set of handle maps in the process, these items could be >tracked in the MFC DLL itself. > >But with the ability to dynamically link a regular DLL to the MFC DLL, >it is now possible to have two or more CWinApp objects in a process - >and also two or more sets of handle maps. How does MFC keep track of >which ones it should be using? > >The solution is to give each module (application or regular DLL) its >own copy of this global state information. Thus, a call to AfxGetApp >in the regular DLL returns a pointer to the CWinApp object in the DLL, >not the one in the executable. This per-module copy of the MFC global >data is known as a module state and is described in MFC Tech Note 58. > >The MFC common window procedure automatically switches to the correct >module state, so you do not need to worry about it in any message >handlers implemented in your regular DLL. But when your executable >calls into the regular DLL, you do need to explicitly set the current >module state to the one for the DLL. To do this, use the >AFX_MANAGE_STATE macro in every function exported from the DLL. This >is done by adding the following line of code to the beginning of >functions exported from the DLL: > >AFX_MANAGE_STATE(AfxGetStaticModuleState( ))" > >On Thursday, May 24, 2007 11:46 AM >Tom Serface wrote: > >Hi fangtu,THanks for posting this reply. >Hi fangtu, > >THanks for posting this reply. I am sure others could experience similar >problems and it is great to have this documented. > >Tom > > >Submitted via EggHeadCafe - Software Developer Portal of Choice >ASP.NET GridView: Select Row and Display Item Detail >http://www.eggheadcafe.com/tutorials/aspnet/ff14a008-2af9-4f9d-a09d-1af670466a80/aspnet-gridview-select.aspx Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
|
Pages: 1 Prev: I (mostly) love MFC Next: How to let a CFrameWnd based SDI application start in full screen? |