I am basically calling a C++ DLL using LoadLibrary() in my C++ application. The application causes random 0xc0000005 (Access violation) Errors. I have done a lot of study on DLL's having their own heaps and their problems.
Things I've made sure to do so far:
In the DLL :
- All allocations are done in C++ standards. (no usage of malloc or calloc)
- All new's have a reachable equivalent delete.
- There is no memory allocated inside the DLL that is freed in the Host exe or vice versa.
- Data transfer between the two is done via POD (char* specifically). No STL's.
- All exported function's have a calling convention of __stdcall
- The DLL is built specifying extern "C" and a DEF file.
In the Host Exe:
- Allocated memory using HeapAlloc() with GetProcessHeap()
- The pointer is passed to the DLL which copies bytes on it using memcpy()
- DLL function typedef's are correct.
- Compilers for both the DLL and the exe are same.(built in VS2010).
The crashes occur at random locations :
- While debugging I observed that just as we step over "}" function end brace in the DLL, the exception occurs.
- After successfully returning from the DLL call. Crash occurs randomly.
All the Event logs show "Faulting module name" to be the DLL.
Taking into account all the points that I have stated previously, I would appreciate if anyone guided me on where to look for cause of the exception.
Also does the pointer I send to the DLL get resolved to the correct HEAP in memcpy()?. The data is correct in the host exe though. GetProcessHeaps() return 4 HEAPS.
EDIT Cannot post the full code due to policies. (again, make note that I have accounted for most of the common mistakes made).
Function where the error occurs (DLL)
extern "C" void __stdcall BuildApplicationsList();
Typedef in exe
typedef void(__stdcall *buildAppsList)(void);
UPDATE
In response to @RalfFriedl. You were right!. the program crashes in this location.
}
5822593F mov byte ptr [esp+7A0h],7
58225947 cmp dword ptr [esp+0A0h],0
5822594F jne BuildApplicationsList+1CE2h (58225992h)
58225951 mov eax,dword ptr [esp+74h]
58225955 test eax,eax
58225957 je BuildApplicationsList+1CB1h (58225961h)
58225959 mov ecx,dword ptr [eax]
5822595B mov edx,dword ptr [ecx+8] // Crash Occurs here.
5822595E push eax
5822595F call edx
58225961 mov eax,dword ptr [esp+70h]
58225965 test eax,eax
58225967 je BuildApplicationsList+1CC1h (58225971h)
58225969 mov ecx,dword ptr [eax]
5822596B mov edx,dword ptr [ecx+8]
5822596E push eax
5822596F call edx
58225971 mov eax,dword ptr [esp+6Ch]
58225975 test eax,eax
58225977 je BuildApplicationsList+1CD1h (58225981h)
58225979 mov ecx,dword ptr [eax]
5822597B mov edx,dword ptr [ecx+8]
5822597E push eax
5822597F call edx
58225981 call dword ptr [__imp__CoUninitialize@0 (5823F2C8h)]
edx and ecx are 0 and obviously accessing 0x00000008 is a violation. Where to next?
BuildApplicationsList
. (CoUninitialize
in a DLL looks a bit strange, by the way.) – molbdnilomov ecx,dword ptr [eax]
: fetch the vtable pointer from the object ateax
;mov edx,dword ptr [ecx+8]
: fetch the function pointer at offset 8 in the vtable;push eax
: add thethis
argument;call edx:
call the function.eax
isn't zero, butedx
is, so the vtable pointer must be null. – molbdnilomov ecx, dword ptr [eax]
retrieves the value at the addresseax
, not the value ofeax
. (That is, it's dereferencing a pointer.) – molbdniloedx
when I meantecx
in the comment that explains the virtual function call. Too late to edit, but I might as well nitpick myself. – molbdnilo