Hi gurus,

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:
Code:
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:
Code:
   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 object that was created at the exe file.

This is the prototype of the function at the DLL:
Code:
class CEventListener
{
public:
	char clientId[128];
	CRITICAL_SECTION *exitCs;
	
	CEventListener() {};
	virtual ~CEventListener() {};
	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:
Code:
class CClientThread : public CEventListener  
{	
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-:
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.