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.