Re: CString oversteps bounds in Release compile
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Fri, 01 Aug 2008 15:12:10 -0400
YSee below...
On Fri, 1 Aug 2008 07:40:48 -0700 (PDT), AVee <motion@xxxxxxxxxxxxxxxxxx> wrote:
Thank's Joe. Let me first say how much I appreciate hearing from you,****
Giovanni and Tom. Without exaggeration, this has been the toughest
debugging problem of my career. Just your willingness to help is
humbling and encouraging.
Well, I'd kind of expect it to store to nIDResource, because that's what the code is
*supposed* to do. There is no good way to guarantee in release mode that a particular
piece of code is correlated to a particular piece of source; in fact, with optimizations,
the relationship of object code to source code is problematic.
In this release compile I disabled Optimizations in the Project
Settings, and I am using the "Debug Multithreaded" option for the run
time library. ("Debug Singlethreaded" doesn't work).
"Debug" libraries make no sense in the release version, and it is not permitted to
redistribute them. Therefore, you must use the "multithreaded" library.
****
****
Sp it is not clear what part of the program generated the code you are seeing. I don't trust any alleged
correlation between source and object code in release mode.
( I would recompile MFC to establish correlation - except...)
I established correlation by watching the correct value (verified from
my resource header) for my resource variable, nIDResource, moved to
its stack relative location here:
(+HID_BASE_RESOURCE)
0048C6BA mov edi,dword ptr [nIDResource]
0048C6BD mov esi,ecx
0048C6BF mov dword ptr [esi+8Ch],edi
The problem occurs between this code and the assembler call to
CString::LoadStringA (0047cbe7), so there are only a few disassembled
lines between two distinct correlation points.
The most troubling lines are these:
0048C6C5 mov eax,[_afxPchNil (004be79c)]
0048C6CA mov dword ptr [nIDResource],eax; **** OVERWRITES
***
... where the disassembler actually tells us that it's blasting
nIDResource! I don't know what _afxPchNil() is, or how these two lines
of code are supposed to construct the CString object. The debug
compile calls into the CString constructor. Here is the disassembly
for the debug compile:
687: m_nIDHelp = nIDResource; // ID for help context
(+HID_BASE_RESOURCE)
00528EA6 mov edx,dword ptr [this]
00528EA9 mov eax,dword ptr [nIDResource]
00528EAC mov dword ptr [edx+8Ch],eax
688:
689: CString strFullString;
00528EB2 lea ecx,[strFullString]
00528EB5 call CString::CString (0053acd7)
00528EBA mov dword ptr [ebp-4],0
690: if (strFullString.LoadString(nIDResource))
00528EC1 mov ecx,dword ptr [nIDResource]
00528EC4 push ecx
00528EC5 lea ecx,[strFullString]
00528EC8 call CString::LoadStringA (004f0370)
00528ECD test eax,eax
00528ECF je CFrameWnd::LoadFrame+0C5h (00528eed)
I am not familiar with this syntax, "eax,[_afxPchNil (004be79c)]". The
debug code I understand - but the release code has me stumped.
Because the release code is reordered, various things don't work right in the debugger.
Source correlations, for example, are problematic. Symbol resolution is questionable.
The line in question is not assembler syntax, it is debug display syntax. It says, "Load
into the eax register the data stored at location _afxPchNil, which happens to be memory
location 004be79c"
However, the next instruction definitely is wrong; it should not be trying to store that
into nIDResource, unless, of course, nIDResource happened to get assigned to a register,
in which case it is just storing something in a register whose former use was nIDResource
but whose current use is meaningless. This is based on register lifetime analysis, and
without knowing what the actual instruction bytes are, it is hard to guess. Note also
that it could be reusing a stack location that is no longer needed; if lifetime analysis
says the value is a "dead value" beyond this point, there is no reason not to reuse the
stack location for some completely unrelated purpose, since there will be no interference.
Do not confuse code with logic. The compiler is free to reuse registers and memory as it
sees fit, because it knows the value can never be reused.
joe
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- References:
- CString oversteps bounds in Release compile
- From: AVee
- Re: CString oversteps bounds in Release compile
- From: Joseph M . Newcomer
- Re: CString oversteps bounds in Release compile
- From: AVee
- CString oversteps bounds in Release compile
- Prev by Date: Re: CString oversteps bounds in Release compile
- Next by Date: Re: Run-Time Check Failure #2
- Previous by thread: Re: CString oversteps bounds in Release compile
- Next by thread: Re: CString oversteps bounds in Release compile
- Index(es):
Relevant Pages
|