strange behavior with MFC's CString - c++

I am getting the strangest memory behavior using an MFC CString:
line 138: PCD_Dir = m_pRunPCD->m_PCD_Dir;
declarations:
CString PCD_Dir; (file scope, defined as a global outside of CServer )
class CRunPCD {
public:
CString m_PCD_Dir;
}
call stack:
Support.dll!CServer::Init(CCfcController * pv=0x007ebe78) Line 138 C++
Support.dll!CCfcController::OnInitialUpdate() Line 156 + 0xf bytes C++
Support.dll!CCfcApp::CCncApp() Line 140 C++
Support.dll!newInstance() Line 162 + 0x2c bytes C++
memory (from watch window):
(wchar_t**)&(m_pRunPCD->m_PCD_Dir):
0x007ec270 wchar_t * *
m_pRunPCD->m_PCD_Dir.m_pszData:
0x007ee8a0 "C:\ProgramData\WAI\PC-DMIS\" wchar_t *
(wchar_t**)&PCD_Dir:
0x068f4698 class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > PCD_Dir wchar_t * *
PCD_Dir.m_pszData:
0x789cb8f8 "" wchar_t *
I then step into the assignment and my environment looks like this:
code:
// Assignment operators
CStringT& operator=(_In_ const CStringT& strSrc)
{
CThisSimpleString::operator=( strSrc );
return( *this );
}
call stack:
mfc100ud.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >::operator=(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > & strSrc=<Bad Ptr>) Line 1218 C++
Support.dll!CServer::Init(CCfcController * pv=0x007ebe78) Line 141 C++
Support.dll!CCfcController::OnInitialUpdate() Line 156 + 0xf bytes C++
Support.dll!CCfcApp::CCncApp() Line 140 C++
Support.dll!newInstance() Line 162 + 0x2c bytes C++
memory:
&strSrc
0x007ec269 const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > *
strSrc.m_pszData:
0xff000000 <Bad Ptr> wchar_t *
so for some reason the value is not getting passed correctly...?
interestingly, if look in this frame:
CNCSupport.dll!CServer::Init(CCncController * pv=0x007ebe78) Line 141 C++
then the value is correct.
any idea what the problem is?! i am completely stumped. any help would be greatly appreciated! thanks.

Instead of:
PCD_Dir = m_pRunPCD->m_PCD_Dir;
try:
PCD_Dir = (LPCTSTR) m_pRunPCD->m_PCD_Dir;

Turns out that the address of strSrc and m_pRunPCD->m_PCD_Dir were offset by 1, which was the reason the buffer pointer was invalid. turns out I had incorrectly enabled packing in a header file to resolve another issue which led to this issue.

Related

Multithread Access violation reading location C++

I have an C++ application that has a main thread and a Poco::Timer to trigger a callback which writes to a file using Poco::FileOutputStream:
FileOutputStream file("test.txt", ios::binary); <-- *Access violation reading location here*
file.write(reinterpret_cast<char *>(&data), sizeof(data));
file.close();
The code always failed at the first line, here is the call stack:
testProject.exe!std::ctype::widen(char _Byte=' ') Line 1716 + 0xf bytes C++
testProject.exe!std::basic_ios >::widen(char _Byte=' ') Line 126 C++
testProject.exe!std::basic_ios >::init(std::basic_streambuf > * _Strbuf=0x038ef700, bool _Isstd=false) Line 135 + 0xa bytes C++
testProject.exe!std::basic_ostream >::basic_ostream >(std::basic_streambuf > * _Strbuf=0x038ef700, bool _Isstd=false) Line 54 C++
testProject.exe!Poco::FileOutputStream::FileOutputStream(const std::basic_string,std::allocator > & path="c:\Projects\TestProject\test.txt", int mode=32) Line 93 + 0xa3 bytes C++
testProject.exe!OPC_Server::OnTimer(Poco::Timer & timer={...}) Line 3656 + 0x13 bytes C++
testProject.exe!Poco::TimerCallback::invoke(Poco::Timer & timer={...}) Line 212 + 0x14 bytes C++
testProject.exe!Poco::Timer::run() Line 197 + 0x19 bytes C++
testProject.exe!Poco::PooledThread::run() Line 200 + 0x15 bytes C++
testProject.exe!Poco::`anonymous namespace'::RunnableHolder::run() Line 57 + 0x17 bytes C++
testProject.exe!Poco::ThreadImpl::runnableEntry(void * pThread=0x00db6afc) Line 207 + 0x20 bytes C++
testProject.exe!_callthreadstartex() Line 348 + 0xf bytes C
testProject.exe!_threadstartex(void * ptd=0x00db6d00) Line 331 C
Tracing into the stack, the timer thread seemed having problem reading the initialization _Byte at the top of the call stack in xlocale internal header:
_Elem __CLR_OR_THIS_CALL widen(char _Byte) const
{ // widen char
return (do_widen(_Byte)); <-- failed: Access violation reading location
}
Second entry in the stack in ios standard header:
_Elem __CLR_OR_THIS_CALL widen(char _Byte) const
{ // convert _Byte to character using imbued locale
const _Ctype& _Ctype_fac = _USE(getloc(), _Ctype);
return (_Ctype_fac.widen(_Byte)); <-- call the top of the stack
}
Third entry in the stack in ios standard header:
protected:
void __CLR_OR_THIS_CALL init(_Mysb *_Strbuf = 0,
bool _Isstd = false)
{ // initialize with stream buffer pointer
_Init(); // initialize ios_base
_Mystrbuf = _Strbuf;
_Tiestr = 0;
_Fillch = widen(' '); <-- call the second entry
But very strangely, the same code runs fine without any error when being used on the main thread.
Is there any permission settings that I need to set for the Poco::Timer to be able to function properly? Or am I missing something very obvious? Thanks for any help.
EDIT: ----------------------
Poco version: 1.7.3
Platform: windows
It turns out that the application exits immediately after the timer is created, but the exit is not cleanly done so it appears that the app is still running and the timer is still ticking, when actually some of the resource has already been released, which causes the error.
MS's _tmain() does something extra than main() apparently.
Sorry it is not _tmain(), but _tmainCRTStartup that is calling _tmain(). When _tmain() exits, other clean up code is run, my project isn't terminated somehow and the application appears still "running".

Visual Studio 2008 release call stack to point

I've a crash on my program, that seems to happens only when I run my application in release mode.
When I start my program from Visual Studio and it crashes, I go to call stack window and I got something like this:
ntdll.dll!00000000774ef0c1()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!000000007749fcc4()
ntdll.dll!00000000774934d8()
ntdll.dll!00000000775170dd()
ntdll.dll!00000000774db5aa()
ntdll.dll!00000000774934d8()
msvcr90.dll!0000000073b9cb87()
vsgu5.dll!vuAllocRefBase::malloc(unsigned __int64 nbytes=314263224, unsigned short id=0) Line 123 + 0x9 bytes C++
vsgr5.dll!vrFont2D::generate(vrDrawContext * context=0x0000000012e6cab7) Line 371 + 0x15 bytes C++
vsgr5.dll!vrFont2D::displayString(vrDrawContext * pContext=0x000000003f800000, const char * kpStr=0x000000003f800000) Line 698 + 0xf bytes C++
vsgr5.dll!vrFont2D::displayStringAt(vrDrawContext * context=0x0000000012f2cac8, const char * str=0x0000000002c6cdc8, const vuVec4<float> & color={...}, float x=-16.634912, float y=-188.33476, float z=0.00000000) Line 786 C++
vsgr5.dll!vrString::draw(vrDrawContext * pContext=0x0000000012bb46b8, const vuVector<vrDrawFunc::InstanceRecord,vuLockOpen,vuAllocSTL<vrDrawFunc::InstanceRecord>,vuAllocRaw> * pInstances=0x0000000012bb2cb8) Line 290 + 0x54 bytes C++
vpoverlay5.dll!vpOverlay2DText::draw(const vsChannel * kpVsChannel=0x0000000012bb2cb8, vrDrawContext * pContext=0x0000000000000002) Line 289 C++
vpoverlay5.dll!vpOverlayDrawMgr::drawOverlay(const vsChannel * channel=0x000000001462c040, vrDrawContext * context=0x0000000013293cd0) Line 258 + 0x12 bytes C++
vsgs5.dll!vsChannel::draw(vrDrawContext * context=0x0000000012bb6018) Line 3134 C++
vsgs5.dll!vsPipeline::processDraw(vsChannel * channel=0x0000000012bb2cb8, vrDrawContext * context=0x0000000012bb46b8) Line 2857 C++
vsgs5.dll!vsPipeline::draw() Line 3528 + 0x2d bytes C++
vsgs5.dll!vsPipeline::endFrame() Line 2159 C++
vsgs5.dll!vsServiceMgr::endFrame() Line 862 C++
VegaPrime.dll!000007feda746b67()
VegaPrime.dll!000007feda7443a8()
VegaPrime.dll!000007feda73545a()
VegaPrime.dll!000007feda75da6e()
QtCore4.dll!000000006663a38b()
msvcr90.dll!0000000073b52fdf()
Is there a way to find, for example from this line
VegaPrime.dll!000007feda746b67()
The corresponding line of code, or method that it's called?

Stack overflow exception before main()

this is my first question here on stackoverflow so I'll try to be specific. I searched the forums for any related topic but no luck. Anyway here goes:
I'm using Visual Studio 2005.I encountered a stack overflow exception :Unhandled exception at 0x775715de in IHR.exe: 0xC00000FD: Stack overflow. ,when attempting to debug my project. The call stack does not help as it stops at ntdll.dll, before even entering the main() function.
At first I suspected that it may be a compilation settings thing, but when I sent the executable compiled on my computer to a second computer, it could run fine, it just won't run on my machine.
The same happens in reverse, I compiled the executable on the second computer, it could run fine on that. But when I tried to run the executable that was compiled on the second computer on my computer, it couldn't run. All that appeared was a blank command prompt and a windows message saying the program was not responding.
I'm using Windows 7 Professional SP1, 64 bit. The other computer has the same OS version. Due to company policy, I can't post any source code here, but anyway I don't think it has anything to do with the source code. I suspect it may be a problem in the runtime environment. Appreciate any help. Thanks.
Here's all there is on the call stack:
->ntdll.dll!775715de()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!775715de()
ntdll.dll!7756014e()
Thanks to #WhozCraig's suggestion, I have managed to get a more meaningful message on the call stack. Still stumped though.
IHR.exe!_mbscmp(const unsigned char * s1=0x00fe8c10, const unsigned char * s2=0x00fe8c10) Line 84 + 0xf bytes
IHR.exe!_mbscmp(const unsigned char * s1=0x00fe8c10, const unsigned char * s2=0x00fe8c10) Line 84 + 0xf bytes
IHR.exe!strcmp(const char * _s1=0x00fe8c10, const char * _s2=0x00fe8c10) Line 1646 + 0x2b bytes
IHR.exe!_mbscmp_l(const unsigned char * s1=0x00fe8c10, const unsigned char * s2=0x00fe8c10, localeinfo_struct * plocinfo=0x00000000) Line 58 + 0xd bytes
IHR.exe!_mbscmp(const unsigned char * s1=0x00fe8c10, const unsigned char * s2=0x00fe8c10) Line 84 + 0xf bytes
IHR.exe!strcmp(const char * _s1=0x00fe8c10, const char * _s2=0x00fe8c10) Line 1646 + 0x2b bytes
here's some more, leading up to the stack above
IHR.exe!_mbscmp_l(const unsigned char * s1=0x00fe8c10, const unsigned char * s2=0x00fe8c10, localeinfo_struct * plocinfo=0x00000000) Line 58 + 0xd bytes C++
IHR.exe!_mbscmp(const unsigned char * s1=0x00fe8c10, const unsigned char * s2=0x00fe8c10) Line 84 + 0xf bytes C++
IHR.exe!strcmp(const char * _s1=0x00fe8c10, const char * _s2=0x00fe8c10) Line 1646 + 0x2b bytes
IHR.exe!_setlocale_get_all(threadlocaleinfostruct * ploci=0x002f13a0) Line 1147 + 0x24 bytes
IHR.exe!_setlocale_nolock(threadlocaleinfostruct * ploci=0x002f13a0, int _category=0, const char * _locale=0x00000000) Line 966 + 0x9 bytes C
IHR.exe!setlocale(int _category=0, const char * _locale=0x00000000) Line 826 + 0x1b bytes
IHR.exe!std::_Locinfo::_Locinfo_ctor(std::_Locinfo * pLocinfo=0x0018f8f8, const char * locname=0x00ea591c) Line 192 + 0x9 bytes
IHR.exe!std::_Locinfo::_Locinfo(const char * _Pch=0x00ea591c) Line 78 + 0xd bytes
IHR.exe!std::ctype::ctype(const short * _Table=0x00000000, bool _Deletetable=false, unsigned int _Refs=0) Line 1740 + 0x10 bytes
IHR.exe!std::ctype::_Getcat(const std::locale::facet * * _Ppf=0x0018fbd8) Line 1760 + 0x4d bytes
IHR.exe!std::use_facet >(const std::locale & _Loc={...}) Line 478 + 0x9 bytes
IHR.exe!std::basic_ios >::widen(char _Byte=' ') Line 124 + 0x34 bytes
IHR.exe!std::basic_ios >::init(std::basic_streambuf > * _Strbuf=0x00ff7908, bool _Isstd=false) Line 135 + 0xa bytes
IHR.exe!std::basic_ostream >::basic_ostream >(std::basic_streambuf > * _Strbuf=0x00ff7908, bool _Isstd=false) Line 53
IHR.exe!std::`dynamic initializer for 'cout''() Line 13 + 0x16 bytes
IHR.exe!_initterm(void (void)* * pfbegin=0x00e8d10c, void (void)* * pfend=0x00e9dca0) Line 855
IHR.exe!_cinit(int initFloatingPrecision=1) Line 293 + 0xf bytes
IHR.exe!tmainCRTStartup() Line 310 + 0x7 bytes
IHR.exe!mainCRTStartup() Line 196
kernel32.dll!#BaseThreadInitThunk#12() + 0x12 bytes
ntdll.dll!RtlUserThreadStart#8() + 0x27 bytes
ntdll.dll!_RtlUserThreadStart#8() + 0x1b bytes
It keeps repeatedly calling strcmp, mbscmp, mbscmp_l until it hits a stack overflow exception.
Update(11 April 2013): I've found the line that causes the problem, but am still totally clueless on why it's causing it. It's the usage of a strcmp.
struct Foo
{
char text[4];
bool operator < (const Foo &rhs) const
{
return strcmp(text, rhs.text) < 0;
}
}
When this strcmp was commented out. The program did not crash. Any ideas or experience with dealing with such a problem? The same program still runs fine on other machines, but only crashes on my machine due to this line. other strcmp is used throughout the program with no issue. Thanks
It is likely that you have global/static variables and they are trying to initialize before you run main. Probably the order of actual initialization is not what you expect, as if you have them in different files, there is no way to tell in which order they should be created.
Either remove those variables or arrange them into the same file.

WCHAR overflow when performing wcscpy_s

When trying to retrieve a massive folder path from an outlook mailbox (no 255 char max length in path) I seem not be be handling it correctly, yet i have tried everything on the code and nothing seems to shine some light on the issue.
Path: \\Mailbox - long\Inbox\fgsegesgrgesrgegthtrhrthyerytyertytthgfhgdfhdfh\sfhsjkdfhsjkhfweuifhskjefhjksdhjsdhfusehfklahdfajkehwfuasdf\sadfhjaehjfhaeufhuaseh9oa3heufhshudhjksahdfjkshadmldhasnf\awefuyawefioaw3yfiuapgpapwqq0uwqfeiusdfsgpsadncabpaw\iawehfiowaeghuiaegfwuioaghpaweufrhasdfhlkasvjdhlaehfuawieghgawgwaef\fasbclajsbvbwaubhvwabveuabvdjklzbdvjkhzusefhzlhsdf\vshiuwhpqphdfhvjsamhashmasdfvhnakjdsfiawjeijfvsadkjfsa\aefrghjksadfhjklshareuhsadhsahvsandvnlsdffalsdfh384fhsduafhl\fasfdlashjklefrhuaehfskhaahsdfhuhaiyeifoa38fodasfhsahdfklkkasdf\jkfhsakdfjhsjkladfhdsjkahfjkajkflashdfjkshafjksahfsdjafhsdjahfjsahldfkasf\fauiwehfeawhfjkhsakjfhsjkaefheuifhjksdhjkafhjksadhfjhaseuhfasjhdjkfhasfjhaskjdfhslaf\jklshadjkfhasjkhfjkaheuyhruiyq3y83yuryvnzxcvxzcviouxzcvzxvklzxvkl
Path Length: 766 to 812 char
Hopefully explaining it a bit better, the code;
if(....)
{
size_t n = wcslen(outlookFolderPath->Value.lpszW);
if(n < 100)
wcscpy_s(m_szInheritedFolderPath, outlookFolderPath->Value.lpszW);
else
{
WCHAR szTemp[2048] = {}, szText[2048]= {};
LoadStringW(ghInstDLL, IDS_PATH_TRUNCATED, szText, 2048);
swprintf_s(szTemp, szText, outlookFolderPath->Value.lpszW + ((n-80) * sizeof(WCHAR)));
wcscpy_s(m_szInheritedFolderPath, szTemp); // *** Dies Here ***
}
}
...
The fatal error occurrs at string.h line;
__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, wcscpy_s, wchar_t, _Dest, _In_z_ const wchar_t *, _Source)
(n-80) * sizeof(WCHAR).
That copies 160 characters in an array that's 100 characters long. Kaboom.
You want to count characters, not bytes. Delete * sizeof(WCHAR). And you ought to check for a surrogate.
swprintf_s(szTemp, szText, outlookFolderPath->Value.lpszW + ((n-80) * sizeof(WCHAR)));
Here the second argument is supposed to be the size of the buffer.

libxml2 crash on second use on Windows

I've been using libxml2 push parsing (SAX) to parse an incoming XML stream, this works well first time but crashes on the second attempt every time, my code looks like this:
xmlSAXHandler saxHandler;
memset(&saxHandler, 0, sizeof(m_SaxHandler));
xmlSAXVersion(&saxHandler, 2);
saxHandler.initialized = XML_SAX2_MAGIC; // so we do this to force parsing as SAX2.
saxHandler.startElementNs = &startElementNs;
saxHandler.endElementNs = &endElementNs;
saxHandler.warning = &warning;
saxHandler.error = &error;
saxHandler.characters = &characters;
xmlParserCtxtPtr pSaxCtx = xmlCreatePushParserCtxt(&m_SaxHandler, this, 0, 0, 0);
I then feed in the XML stream using xmlParseChunk() and use the callbacks to process the data, once parsing is complete, I call xmlFreeParserCtxt(pSaxCtx) to free the context. As I mentioned, this all works perfectly on the first set of data but when the code is run again I get an access violation, the stack trace is:
ntdll.dll!_RtlpWaitOnCriticalSection#8() + 0x99 bytes
ntdll.dll!_RtlEnterCriticalSection#4() + 0x168d8 bytes
ntdll.dll!_RtlpWaitOnCriticalSection#8() + 0x99 bytes
ntdll.dll!_RtlEnterCriticalSection#4() + 0x168d8 bytes
libxml2.dll!xmlGetGlobalState() Line 716 C
libxml2.dll!__xmlDefaultBufferSize() Line 814 + 0x5 bytes C
libxml2.dll!xmlAllocParserInputBuffer(xmlCharEncoding enc) Line 2281 + 0x5 bytes C
libxml2.dll!xmlCreatePushParserCtxt(_xmlSAXHandler * sax, void * user_data, const char * chunk, int size, const char * filename) Line 11695 + 0x9 bytes C
TestApp.exe!XMLProcessor::XMLProcessor(const wchar_t * szHost=0x00d3d80c, const wchar_t * szUri=0x00d3db40, bool secure=false) Line 16 + 0x19 bytes C++
TestApp.exe!WorkerThread::ThreadProc(void * lpParameter=0x00a351c0) Line 34 + 0x15 bytes C++
kernel32.dll!#BaseThreadInitThunk#12() + 0x12 bytes
ntdll.dll!___RtlUserThreadStart#8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart#8() + 0x1b bytes
It seems to be trying to lock a critical section which is either non-existant or corrupted but I cannot figure how/why it works first time and not second.
Any ideas?
Thanks,
J
Are the two calls in different threads?
Have you called the xmlInitParser function to initialize the library. A missing call to xmlInitParser will produce a call stack like yours in multi-threaded applications.