libxml2 crash on second use on Windows - c++

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.

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?

AccessViolationException when using std::basic_ifstream::get() in C++/CLI, why?

When I try to run this:
#include <tchar.h>
#include <fstream>
int _tmain(int argc, TCHAR *argv[])
{
std::basic_ifstream<TCHAR> file("TestInput.txt");
file.get();
}
I get an AccessViolationException with this stack trace:
ntdll.dll!_RtlpWaitOnCriticalSection#8() + 0xae bytes
ntdll.dll!_RtlpEnterCriticalSectionContended#4() + 0xa1 bytes
ntdll.dll!_RtlEnterCriticalSection#4() - 0x1f885 bytes
msvcr120.dll!__lock_file() + 0x2ce45 bytes
[Managed to Native Transition]
MyProject.exe!std::basic_filebuf<char,std::char_traits<char> >::_Lock() Line 355 C++
msvcp120d.dll!std::basic_istream<char,std::char_traits<char> >::_Sentry_base::_Sentry_base() + 0x55 bytes
msvcp120d.dll!std::basic_istream<char,std::char_traits<char> >::sentry::sentry() + 0x32 bytes
msvcp120d.dll!std::basic_istream<char,std::char_traits<char> >::get() + 0x5c bytes
[Managed to Native Transition]
MyProject.exe!wmain(int argc = 0x2, wchar_t** argv = 0x054AA3F8) [line # removed] C++
MyProject.exe!__tmainCRTStartup() [line # removed] C
[Managed to Native Transition]
mscoreei.dll!__CorExeMain#0() + 0x71 bytes
mscoree.dll!_ShellShim__CorExeMain#0() + 0x227 bytes
mscoree.dll!__CorExeMain_Exported#0() + 0x8 bytes
ntdll.dll!___RtlUserThreadStart#8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart#8() + 0x1b bytes
Why does this happen, and how can I avoid it when trying to read a file?
It was because I was compiling with the _DEBUG macro (left over from before converting from native).
Removing it fixed the problem.
It sounds like you have macro's doing unexpected things. When you need to figure out what happened in Visual C++, have it dump the preprocessor output. Details on doing that are documented here.

Performance Data Handler hangs for \PhysicalDisk

I have been using PDH (Performance Data Handler) to collect perfmon data about the machine my process is running on. I have had no trouble with PDH objects Processor Information and Memory but when I try to use PhysicalDisk my program hangs.
I reduced the code to this test case.
void
third()
{
char path[ PDH_MAX_COUNTER_PATH ];
DWORD size = 0;
PDH_STATUS status;
strcpy( path, "\\PhysicalDisk(1 E:)\\% Disk Time" );
// hangs
status = PdhExpandWildCardPath( NULL, path, 0, & size, PDH_NOEXPANDCOUNTERS );
HANDLE query;
PDH_HCOUNTER hCounter;
status = PdhOpenQuery( NULL, 0, & query );
// hangs
status = PdhAddCounter( query, path, 0, & hCounter );
}
When I run this code by itself, it works fine. When I run it in my larger program it hangs but only for PhysicalDisk. My larger program monitors a dozen PDH counters with no problems but when I add any PhysicalDisk counter, then it hangs. The counters are defined in an array, so the code is the same for all counters.
When it hangs, this is the stack back trace
ntdll.dll!_ZwDelayExecution#8() + 0x15 bytes
ntdll.dll!_ZwDelayExecution#8() + 0x15 bytes
KernelBase.dll!_Sleep#4() + 0xf bytes
perfdisk.dll!_OpenDiskObject#4() + 0x105 bytes
advapi32.dll!_OpenExtObjectLibrary#4() + 0x1f9 bytes
advapi32.dll!_QueryExtensibleData#4() - 0x250f bytes
advapi32.dll!_PerfRegQueryValue#28() + 0x26d bytes
kernel32.dll!_LocalBaseRegQueryValue#24() + 0x2754e bytes
kernel32.dll!_RegQueryValueExW#24() + 0xae bytes
pdh.dll!_GetSystemPerfData#16() + 0x92 bytes
pdh.dll!_GetObjectId#12() + 0xdb bytes
pdh.dll!_PdhiExpandWildcardPath#24() + 0x38b bytes
pdh.dll!_PdhExpandWildCardPathHA#20() + 0xcb bytes
pdh.dll!_PdhExpandWildCardPathA#20() + 0x10a bytes
> dbb30.dll!third() Line 2472 + 0x16 bytes C++
dbb30.dll!dbbProfileReport::dbbProfileReport() Line 2490 C++
dbb30.dll!`dynamic initializer for 'dbbProfileReportObject''() Line 2367 + 0xd bytes C++
msvcr90d.dll!_initterm(void (void)* * pfbegin=0x0121d380, void (void)* * pfend=0x0121fddc) Line 903 C
dbb30.dll!_CRT_INIT(void * hDllHandle=0x00ae0000, unsigned long dwReason=1, void * lpreserved=0x0018fd24) Line 318 + 0xf bytes C
dbb30.dll!__DllMainCRTStartup(void * hDllHandle=0x00ae0000, unsigned long dwReason=1, void * lpreserved=0x0018fd24) Line 540 + 0x11 bytes C
dbb30.dll!_DllMainCRTStartup(void * hDllHandle=0x00ae0000, unsigned long dwReason=1, void * lpreserved=0x0018fd24) Line 510 + 0x11 bytes C
ntdll.dll!_LdrpCallInitRoutine#16() + 0x14 bytes
ntdll.dll!_LdrpRunInitializeRoutines#4() - 0x352 bytes
ntdll.dll!_LdrpInitializeProcess#8() - 0x765 bytes
ntdll.dll!__LdrpInitialize#8() + 0xb4f9 bytes
ntdll.dll!_LdrInitializeThunk#8() + 0x10 bytes
The PDH code starts 6 threads in my process, one of them is in a function _PerfdiskPnpNotification which seems to be related. When I look at assembly code, the main thread is sleeping waiting for this second thread to set a flag.
I have tried running with Admin permissions, but no change. Googling for _PerfdiskPnpNotification finds it sometimes tries to open a pop up window. I tried running the larger code from a GUI app, but it hangs too. I tried the larger code on two machines (both Windows 7) but no luck. The larger program calls the PDH code from a constructor for a global object, I tried the small test case from a ctor on a global, but it worked.
I tried lodctr /r to rebuild the registry, but no joy.
Compiling with MSVC 2005 and MSVC 2008 Express.

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.