My library was working fine in Visual Studio 2010 but now whenever I run it compiled in 2012, I get these memory errors:
First-chance exception at 0x76884B32 in Example.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0101F3A0.
First-chance exception at 0x76884B32 in Example.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0101F3A0.
Unhandled exception at at 0x76884B32 in Example.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0101F3A0.
First-chance exception at 0x76FF3541 (ntdll.dll) in Example.exe: 0xC0000005: Access violation reading location 0xFEFEFF02.
According to the call stack, the errors are coming up everytime return wstring(cMD5.hexdigest()); is called from the following code:
wstring GetMachineHash() {
BYTE szHash[48];
LPBYTE pIdentifierHash;
ZeroMemory(szHash, 48);
MachineNameIdentifier cNameId;
pIdentifierHash = cNameId.GetIdentifierHash();
memcpy(szHash, pIdentifierHash, 16);
NetworkAdapterIdentifier cNetAdaptId;
pIdentifierHash = cNetAdaptId.GetIdentifierHash();
memcpy(szHash+16, pIdentifierHash, 16);
VolumeInfoIdentifier cVolInfo;
pIdentifierHash = cVolInfo.GetIdentifierHash();
memcpy(szHash+32, pIdentifierHash, 16);
MD5 cMD5(szHash, 48);
return wstring(cMD5.hexdigest());
}
If your wondering what MD5 class I'm using, its the one port by Frank Thilo but its modified to return LPBYTE instead of std::string like so:
// return 16 byte md5 hash
LPBYTE MD5::hash() const {
if (!finalized)
return 0;
return (LPBYTE)digest;
}
// return hex representation of digest as string
LPTSTR MD5::hexdigest() const
{
if (!finalized)
return NULL;
LPTSTR szBuf = new TCHAR[33];
ZeroMemory(szBuf, 33);
for (int i=0; i<16; i++)
_stprintf_s(szBuf+i*2, 33, _T("%02X"), digest[i]);
szBuf[32]=0;
return szBuf;
}
After doing some research here on SO, it says these errors are because of a possible memory leak somewhere else in my program. But I have looked and everything seems to be freed correctly. Any ideas? I was wondering if this also might have something to do with calling a DLL library from an EXE through LoadLibrary() and GetProcAddress()?
(I should also note that the Platform Toolset is set to Visual Studio 2012 - Windows XP (v110_xp))
Related
My code for loading the file from resource is given below
void LoadFileInResource(int name, int type, DWORD& size, const char*& data)
{
HMODULE handle = ::GetModuleHandle(NULL);
HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name),MAKEINTRESOURCE(type));
HGLOBAL rcData = ::LoadResource(handle, rc);
size = ::SizeofResource(handle, rc);
data = static_cast<const char*>(::LockResource(rcData));
}
This code works perfect if its just an application. When the same code is used as a DLL, I am getting null in rc, which is post the FindResource.
I have defined the symbols in resourceful file as shows below:
#define TEXTFILE 256
#define IDR_MYTEXTFILE 105
Also the file which I need to add is defined in rc file:
IDR_MYTEXTFILE TEXTFILE "C:/Docs/Lib.XML"
As I mentioned earlier, this code is perfectly working when its an application, converting it to DLL is creating issue.
LoadFileInResource function is called as given below:
LoadFileInResource(IDR_MYTEXTFILE, TEXTFILE, size, data);
With the following code:
static void Main()
{
try
{
var context = uno.util.Bootstrap.bootstrap();
}
catch (Exception ex)
{
Console.WriteLine(ex.toString());
}
}
This code works fine in win 7 but getting "SEH Exception handled by user code External component has thrown an exception".
Lastest Version:Libreoffice 5.0.3.2..Please help me to resolve this problem immediately.
Look the response of another topic:
Bootstrap Uno API LibreOffice exception
var unoPath = #"C:\Program Files\LibreOffice 5\program"
// when running 32-bit LibreOffice on a 64-bit system, the path will be in Program Files (x86)
// var unoPath = #"C:\Program Files (x86)\LibreOffice 5\program"
SetEnvironmentVariable("UNO_PATH", unoPath, EnvironmentVariableTarget.Process);
SetEnvironmentVariable("PATH", GetEnvironmentVariable("PATH") + #";" + unoPath, EnvironmentVariableTarget.Process);````
My application uses MS Access mdb files because of legacy reasons. It connects to the database using ADO with the following connection string:
Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;Data Source=Dummy.mdb
Recently I started porting my application to 64 bit. Because of that Jet OLEDB provider is not available on 64 bit systems I used ACE OLEDB provider with the following connection string:
Provider=Microsoft.ACE.OLEDB.12.0;Persist Security Info=False;Data Source=Dummy.mdb
The application also uses MS XML DOM to work with XML files. Sometimes the 64 bit version crashes with access violation exception in SysFreeString which is called from one of the MS XML wrapper methods. The 32 bit version does not have these problems. I distilled the problem into the tester applicaiton.
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <conio.h>
#include <ObjBase.h>
#import <msxml6.dll>
#import <msado15.dll> rename("EOF", "EndOfFile")
using namespace ADODB;
bool s_bRepeat = true;
unsigned __stdcall XmlThreadFunc(void*)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
MSXML2::IXMLDOMDocumentPtr l_pXMLDom;
l_pXMLDom.CreateInstance(__uuidof(DOMDocument), NULL, CLSCTX_INPROC_SERVER);
l_pXMLDom->async = VARIANT_FALSE;
MSXML2::IXMLDOMElementPtr l_pRoot = l_pXMLDom->createElement("root");
l_pXMLDom->appendChild(l_pRoot);
unsigned int l_nCnt = 0;
while (s_bRepeat)
{
if (0 == l_nCnt++ % 1000)
{
printf(".");
}
l_pRoot->setAttribute("test", "Test1");
Sleep(0);
}
CoUninitialize();
_endthreadex(0);
return 0;
}
unsigned __stdcall DbThreadFunc(void*)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
_ConnectionPtr l_pConnection;
l_pConnection.CreateInstance(__uuidof(Connection));
#ifdef _WIN64
LPCSTR l_cszConnectStr = "Provider=Microsoft.ACE.OLEDB.12.0;Persist Security Info=False;Data Source=Dummy.mdb";
#else
LPCSTR l_cszConnectStr = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;Data Source=Dummy.mdb";
#endif
while (s_bRepeat)
{
l_pConnection->Open(l_cszConnectStr, "", "", adConnectUnspecified);
Sleep(1000);
printf("(");
l_pConnection->Close();
printf(")");
}
CoUninitialize();
_endthreadex(0);
return 0;
}
int main()
{
HANDLE l_hXmlThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &XmlThreadFunc, NULL, 0, NULL));
HANDLE l_hDbThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &DbThreadFunc, NULL, 0, NULL));
_getch();
s_bRepeat = false;
HANDLE l_Handles[2] = { l_hXmlThread, l_hDbThread };
WaitForMultipleObjects(2, l_Handles, TRUE, INFINITE);
CloseHandle(l_hXmlThread);
CloseHandle(l_hDbThread);
return 0;
}
The crash call stack is the following:
OLEAUT32!SysFreeString
TestCrash64Lean!_bstr_t::Data_t::_Free
TestCrash64Lean!_bstr_t::Data_t::~Data_t
TestCrash64Lean!_bstr_t::Data_t::`scalar deleting destructor'
TestCrash64Lean!_bstr_t::Data_t::Release
TestCrash64Lean!_bstr_t::_Free
TestCrash64Lean!_bstr_t::~_bstr_t
TestCrash64Lean!MSXML2::IXMLDOMElement::setAttribute
TestCrash64Lean!XmlThreadFunc
MSVCR80D!_callthreadstartex
MSVCR80D!_threadstartex
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart
At the crash the DB thread is always in the following state:
MSVCR90!memset
mso!Ordinal4118
mso!Ordinal7994
mso!MsoUninitOffice
ACECORE
ACECORE
ACEOLEDB!DllGetClassObject
ACEOLEDB!DllGetClassObject
ACEOLEDB!DllGetClassObject
ACEOLEDB!DllGetClassObject
oledb32!CAcm::FinalRelease
oledb32!ATL::CComPolyObject<CDCM>::~CComPolyObject<CDCM>
oledb32!ATL::CComPolyObject<CDCM>::Release
oledb32!CDCMCreator::DestroyResource
comsvcs!CHolder::SafeDispenserDriver::DestroyResource
comsvcs!CHolder::ProcessDestroyList
comsvcs!CHolder::FreeResource
oledb32!CDCMCreator::ReleaseResource
oledb32!CDPO::ReturnDCMToPool
oledb32!CDPO::FinalRelease
oledb32!ATL::CComPolyObject<CDPO>::`scalar deleting destructor'
oledb32!ATL::CComPolyObject<CDPO>::Release
msado15!CConnection::_Close
msado15!CConnection::Close
TestCrash64Lean!ADODB::Connection15::Close
TestCrash64Lean!DbThreadFunc
MSVCR80D!_callthreadstartex
MSVCR80D!_threadstartex
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart
I found that as a workaround if I keep one open connection to some empty database file, I can open and close connections to actual database files and the application does not crash. Anyway I would rather understand the actual cause of the crash. I would appreciate any suggestions.
My configuration is the following:
Microsoft Visual Studio 2005 Version 8.0.50727.4039 (QFE.050727-4000)
Windows Server 2008 R2 Standard 64 bit
Processor: Intel(R) Xeon(R) E5645 # 2.40GHz
Memory: 16.0 GB
It looks like this is a problem of ACE OLEDB provider from Microsoft Access Database Engine 2010 Redistributable. Switching to the provider from Microsoft Access 2013 Runtime resolved the problem.
Both node console and Qt5's V8-based QJSEngine can be crashed by the following code:
a = []; for (;;) { a.push("hello"); }
node's output before crash:
FATAL ERROR: JS Allocation failed - process out of memory
QJSEngine's output before crash:
#
# Fatal error in JS
# Allocation failed - process out of memory
#
If I run my QJSEngine test app (see below) under a debugger, it shows a v8::internal::OS::DebugBreak call inside V8 code. If I wrap the code calling QJSEngine::evaluate into __try-__except (SEH), then the app won't crash, but this solution is Windows-specific.
Question: Is there a way to handle v8::internal::OS::DebugBreak in a platform-independent way in node and Qt applications?
=== QJSEngine test code ===
Development environment: QtCreator with Qt5 and Windows SDK 7.1, on Windows XP SP3
QJSEngineTest.pro:
TEMPLATE = app
QT -= gui
QT += core qml
CONFIG -= app_bundle
CONFIG += console
SOURCES += main.cpp
TARGET = QJSEngineTest
main.cpp without SEH (this will crash):
#include <QtQml/QJSEngine>
int main(int, char**)
{
try {
QJSEngine engine;
QJSValue value = engine.evaluate("a = []; for (;;) { a.push('hello'); }");
qDebug(value.isError() ? "Error" : value.toString().toStdString().c_str());
} catch (...) {
qDebug("Exception");
}
return 0;
}
main.cpp with SEH (this won't crash, outputs "Fatal exception"):
#include <QtQml/QJSEngine>
#include <Windows.h>
void runTest()
{
try {
QJSEngine engine;
QJSValue value = engine.evaluate("a = []; for (;;) { a.push('hello'); }");
qDebug(value.isError() ? "Error" : value.toString().toStdString().c_str());
} catch (...) {
qDebug("Exception");
}
}
int main(int, char**)
{
__try {
runTest();
} __except(EXCEPTION_EXECUTE_HANDLER) {
qDebug("Fatal exception");
}
return 0;
}
I don't believe there's a cross-platform way to trap V8 fatal errors, but even if there were, or if there were some way to trap them on all the platforms you care about, I'm not sure what that would buy you.
The problem is that V8 uses a global flag that records whether a fatal error has occurred. Once that flag is set, V8 will reject any attempt to create new JavaScript contexts, so there's no point in continuing anyway. Try executing some benign JavaScript code after catching the initial fatal error. If I'm right, you'll get another fatal error right away.
In my opinion the right thing would be for Node and Qt to configure V8 to not raise fatal errors in the first place. Now that V8 supports isolates and memory constraints, process-killing fatal errors are no longer appropriate. Unfortunately it looks like V8's error handling code does not yet fully support those newer features, and still operates with the assumption that out-of-memory conditions are always unrecoverable.
I hooked native api ZwCreateFile, and wdk doc says windows use ZwCreateFile to create or open a directory. I can detect the operation of opening testdir, but i failed to stop the open directory operation.
My code of my own FakeZwCreateFile like this:
NTSTATUS FakeZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
)
{
NTSTATUS rtStatus = STATUS_SUCCESS;
UNICODE_STRING test = RTL_CONSTANT_STRING(L"\\??\\c:\\testdir");
if (!RtlCompareUnicodeString(ObjectAttributes->ObjectName, &test, TRUE))
{
DbgPrint("%wZ\n", &test);
FileHandle = NULL;
IoStatusBlock->Status = rtStatus = STATUS_ACCESS_DENIED;
goto exit;
}
Orig:
OrigZwOpenFile = (NTOPENFILE)oldServiceAddr[SYSTEM_INDEX(ZwOpenFile)];
rtStatus = OrigZwOpenFile(
FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
ShareAccess,
OpenOptions
);
exit:
return rtStatus;
}
Why i failed to stop opening the c:\testdir directory?? And what shoud i do to intercept the operations of creating new folders????
In this case is better to use File System Filter Drivers instead of SSDT hooking, Because FS Filter Drivers work correctly in 64Bit version of windows but SSDT only can use in 32Bit (If you can bypass windows Patch Guard then you can use SSDT hook in 32Bit) !