ESP not properly saved (DLL calling an exe's object function).
Hi everyone,
I'm stress-testing an application of mine.
This application is a service, so it has to be able to support quite a heavy
loan of work.
It is installed and working fine at several customers. But one of them has
very heavy traffic, so there it crashes once a day. The service
automatically restarts but its clients have to reconnect and stuff, so the
customer is not very happy... So that's why I'm stress-testing it, to see
if I catch the bug.
The service is an exe file using a DLL, both are code of mine.
After half an hour of stress-testing I get this debug error:
File: i386\chkesp.c Line: 42 The value of ESP was not properly saved across
a function call. This is usually a result of calling a function declared
with one calling convention with a function pointer declared with a
different calling convention.
The line where it crashes is within the DLL:
-------------
if (el) el->DeviceStatus((char *)(LPCTSTR)deviceId, numCallStates,
csList);
-------------
'deviceId' is a valid CString (I can read its value is "30").
'numCallStates' is an int (I realize that it should be an unsigned int; but,
should this be the problem?); its value is 1.
'csList' is:
-------------
long *csList = NULL;
(...)
csList = new long[1];
csList[0] = 0;
-------------
and, in fact, I can see its value is a pointer to a long with 0 value.
The 'el' is a pointer to an CClientThread object (IEventListener interface)
that was created at the exe file:
-------------
IEventListener *el = NULL;
(...)
bRes = operationsRunning.Lookup(invokeId, (void *&)el);
-------------
This is the prototype of the function at the DLL:
-------------
class IEventListener
{
public:
char clientId[128];
CRITICAL_SECTION *exitCs;
IEventListener() {};
virtual ~IEventListener() {};
virtual void LockRef() = 0;
virtual void UnlockRef() = 0;
(...)
virtual void DeviceStatus(char * deviceId, unsigned int numCalls, long
*callStatusList) = 0;
(...)
};
-------------
And this is the prototype within the exe file:
-------------
class CClientThread : public IEventListener
{
public:
int Stop();
int Start();
int Run();
void LockRef();
void UnlockRef();
(...)
void DeviceStatus(char * deviceId, unsigned int numCalls, long
*callStatusList);
(...)
CClientThread(SOCKET s, CServerThread *st);
virtual ~CClientThread();
CServerThread * server;
SOCKET clientSocket;
HANDLE hClientThread;
private:
(...)
};
-------------
Its implementation is, -within the exe file code-:
-------------
void CClientThread::DeviceStatus(char * deviceId, unsigned int numCalls,
long *callStatusList)
{
CString msg;
CString cl, status;
for (UINT i = 0; i < numCalls; i++) {
status.Format("%ld", callStatusList[i]);
cl += status;
cl += ";";
}
msg.Format("[%s, %ld] <---- DeviceStatus(%s, %d, %s)",
clientId, clientSocket, deviceId, numCalls, cl);
g_logSystem.logNormal(2, msg);
msg.Format("24$%s$%d$%s", deviceId, numCalls, cl);
send(msg);
}
-------------
Calling convention in both project settings is __cdecl*
Please notice that this is not an exe calling a DLL function, but a DLL
calling an exe's object function.
And also notice that it normally runs just fine. It is only when subjected
to stress-testing, and after 20 or 30 minutes, when the error raises.
Any hints or clues on what may be happening? Why do I get that "ESP not
properly saved" after hundreds of calls?
Thanks a lot!!
Ricardo V?zquez
Madrid, Spain.