cURL / Mailing Lists / curl-library / Single Mail

curl-library

Access Violation in libcurl in Win32 service application on XP

From: Michael Smith <mikes_at_VERTIGO.NET>
Date: Tue, 11 Jan 2005 13:39:10 -0500

Hello I am using libcurl in a win32 service application running on XP sp2. I statically linking a curl lib file we build ourselves from curl 7.12.1. The runtime libs I am linking with for the curl lib file and our service executable are "Multithreaded DLL".

I am receiving an Access Violation and it stems from the following code in the curl source code:

CURLSHcode
Curl_share_unlock(struct SessionHandle *data, curl_lock_data type)
{
  struct Curl_share *share = data->share;

  if (share == NULL)
    return CURLSHE_INVALID;

  --> if(share->specifier & (1<<type)) {
    if(share->unlockfunc) /* only call this if set! */
      share->unlockfunc (data, type, share->clientdata);
  }

  return CURLSHE_OK;
}

The arrow points to code where the debugger took me too when I invoked the debugger following the Access Violation.
At the time of the exception, the service process was seamingly idle although it is possible that some background processing was underway.

The following code segment is that with which we interface with to make calls into the curl lib, hopefully it will give you some insight.

Thanks to all of you who have taken the time to look at this.

#include "Vxs_Internet.h"

#include <tchar.h>
#include <malloc.h>
#include <curl/types.h>
#include <curl/easy.h>

class _ccurl_initializer
{
        CRITICAL_SECTION m_cs;
        LONG m_ldone;
public:
        _ccurl_initializer ()
                : m_ldone(0)
        {
                InitializeCriticalSection (&m_cs);
        }
        ~_ccurl_initializer ()
        {
                DeleteCriticalSection (&m_cs);
                if (m_ldone != 0)
                        curl_global_cleanup();
        }

        CURLcode Init ()
        {
                if (InterlockedExchangeAdd (&m_ldone, 0L) != 0)
                        return CURLE_OK;
                CURLcode rc;
                EnterCriticalSection (&m_cs);
                if ((rc = curl_global_init(CURL_GLOBAL_DEFAULT)) == CURLE_OK)
                        InterlockedIncrement (&m_ldone);
                LeaveCriticalSection (&m_cs);
                return rc;
        }
} _curl_initializer;

struct _cgeturl_callback_buf
{
        unsigned char* buf;
        size_t len;
        _cgeturl_callback_buf ()
                : buf(NULL), len(0)
        {}
};

int writemem_curl_cb(void *buffer, size_t size, size_t nmemb, void *pmem)
{
        size_t newlen = size * nmemb;
        size_t offset = 0;
        struct _cgeturl_callback_buf *out=(struct _cgeturl_callback_buf *)pmem;
        if (out->len == 0)
        {
                out->len = newlen;
                out->buf = new unsigned char [out->len];
        }
        else
        {
                size_t _len = out->len;
                out->len += newlen;
                unsigned char* _buf = new unsigned char [out->len];
                memcpy (_buf, out->buf, _len);
                out->buf = _buf;
                offset = _len;
        }
        memcpy (out->buf + offset, buffer, newlen);
        return (int)nmemb;
}

struct _cgeturl_callback_file
{
        FILE* fp;
        size_t len;

        _cgeturl_callback_file ()
                : fp (NULL), len (0)
        {}
};

int writefile_curl_cb(void *buffer, size_t size, size_t nmemb, void *pfile)
{
        _cgeturl_callback_file* fp = (_cgeturl_callback_file*)pfile;
        if (fwrite (buffer, nmemb, size, fp->fp))
        {
                fp->len += (size * nmemb);
                //printf ("size := %3d nmemb:=%8d tot:= %10d (ret:=%8d)\n", size, nmemb, fp->len, fwrite (buffer, nmemb, size, fp->fp));
                return (int)nmemb;
        }
        return 0;
}

#include "fstools.h"

CURLcode Vxs_GetURL (Vxs_GetURLData* purl)
{
        CURL* curl = NULL;
        _cgeturl_callback_buf hdr;
        CURLcode curlrc = CURLE_FAILED_INIT;
        long lval = 0;
        double dval = 0.0L;
        char* p = NULL;
        int ilen;
        char* url = NULL;
        _cgeturl_callback_file fp;

        if ((curlrc = _curl_initializer.Init ()) != CURLE_OK)
                return curlrc;
        
        ilen = WideCharToMultiByte (CP_ACP, 0, purl->lpszURL, _tcslen (purl->lpszURL) + 1, NULL, 0, 0, 0);
        url = (char*)_alloca (ilen);
        if (url == NULL)
                return CURLE_OUT_OF_MEMORY;
        
        ilen = WideCharToMultiByte (CP_ACP, 0, purl->lpszURL, _tcslen (purl->lpszURL) + 1, url, ilen, 0, 0);

        curl = curl_easy_init ();
        if (curl != NULL)
        {
                curl_easy_setopt (curl, CURLOPT_URL, url);
                if (! purl->fGetBodyContent)
                {
                        curl_easy_setopt (curl, CURLOPT_NOBODY, TRUE);
                }
                else
                {
                        fp.fp = _tfopen (purl->lpszOutputFileName, _T("wb"));
                        if (fp.fp == NULL)
                        {
                                curl_easy_cleanup(curl);
                                return CURLE_WRITE_ERROR;
                        }
                        curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writefile_curl_cb);
                        curl_easy_setopt (curl, CURLOPT_WRITEDATA, &fp);
                }
                curl_easy_setopt (curl, CURLOPT_FILETIME, TRUE);
                if (purl->lLastModified > 0)
                {
                        curl_easy_setopt (curl, CURLOPT_TIMECONDITION, TRUE);
                        curl_easy_setopt (curl, CURLOPT_TIMEVALUE, purl->lLastModified);
                }
                if (purl->fVerbose)
                        curl_easy_setopt (curl, CURLOPT_VERBOSE, TRUE);

                if (purl->fNoEPSV)
                        curl_easy_setopt (curl, CURLOPT_FTP_USE_EPSV, FALSE);
                else
                        curl_easy_setopt (curl, CURLOPT_FTP_USE_EPSV, TRUE);

                curlrc = curl_easy_perform (curl);
                curl_easy_getinfo (curl, CURLINFO_FILETIME, &lval);
                purl->lLastModified = lval;
                curl_easy_getinfo (curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &dval);
                purl->dwFileSize = (DWORD)dval;
                curl_easy_getinfo (curl, CURLINFO_CONTENT_TYPE, &p);
                if (p)
                        MultiByteToWideChar (CP_ACP, 0, p, strlen (p) + 1, purl->szContentType, 255);
                else
                        purl->szContentType[0] = NULL;

                if (fp.fp && purl->fGetBodyContent)
                        fclose (fp.fp);

                curl_easy_cleanup(curl);
        }
        else
                curlrc = CURLE_FAILED_INIT;

        return curlrc;
}
Received on 2005-01-11