Discussion:
Access Violation in ADODB
(too old to reply)
Anton Lee
2009-01-14 13:02:29 UTC
Permalink
Hi everybody. I'm not sure if I am posting to the right group. Correct
me if I am wrong.

Here is a C++ code that throws "Access Violation" exception when
executed.
Basically I need to open Recordset objects asynchronously (then
everything runs OK),
but sometimes synchronous calls to ADODB::Recordset::Open are
performed,
and then an exception shows up.

The problem seems to be with ADODB::Recordset's ActiveConnection
property
that is set to zero in Connection object's "ExecuteComplete" event.

If you comment out the the line where PutRefActiveConnection is
called, everything runs just fine.

Exception occurs in msdart.dll. Text says:
"Unhandled exception at 0x76588f09 in <application>: 0xC0000005:
Access violation reading location 0x0008006c."

Callstack of the failed thread looks like this:
msdart.dll!76588f09()
[Frames below may be incorrect and/or missing, no symbols loaded for
msdart.dll]
msdart.dll!76588f40()
msado15.dll!4ddd3987()
msado15.dll!4ddfb06a()
msdart.dll!765891fa()
ntdll.dll!7c96c5cf()
msdart.dll!76588f0c()
msado15.dll!4ddd28c8()
msado15.dll!4ddd3c5b()
msado15.dll!4ddd570a()
msado15.dll!4dddbe4c()
msdart.dll!76588f0c()
msdart.dll!76588f40()
msado15.dll!4ddda2b9()
msado15.dll!4ddda1c2()
sqloledb.dll!4dd015f6()
msado15.dll!4ddd1364()
msado15.dll!4dddeb23()
msado15.dll!4ddd9edb()
msado15.dll!4ddd39e5()
msado15.dll!4ddd62e3()
msado15.dll!4ddd4e8e()
msado15.dll!4dddf2f5()
msado15.dll!4ddd60fd()
msado15.dll!4ddd3c11()
msado15.dll!4ddd53ea()
msado15.dll!4ddd164c()


OS is Windows XP Pro SP3. MDAC version is 2.81.1132.0

In the code below only _tmain function and
ConnectionEventReceiver::raw_ExecuteComplete method are the points of
interest.
Can somebody tell me if there is anything wrong with the code? Or
maybe there could be a bug in MSADO?

Thanks in advance.


// Compiles well with Visual Studio 2005
#import "c:\Program Files\Common Files\System\ado\msado15.dll"
no_namespace rename("EOF", "adoEOF")

// Class to capture ADODB::Connection's events.
// Only raw_ExecuteComplete method actually does work
class ConnectionEventReceiver: public ConnectionEventsVt
{
private:
public:
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
{
*ppv = NULL;
if (riid == __uuidof(IUnknown) ||
riid == __uuidof(ConnectionEventsVt)) *ppv = this;
if (*ppv == NULL)
return ResultFromScode(E_NOINTERFACE);
AddRef();
return NOERROR;
}

STDMETHODIMP_(ULONG) AddRef(void){return 1;}
STDMETHODIMP_(ULONG) Release(void){return 1;}

STDMETHODIMP raw_InfoMessage(Error* pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}

STDMETHODIMP raw_BeginTransComplete(
LONG TransactionLevel,
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}

STDMETHODIMP raw_CommitTransComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}

STDMETHODIMP raw_RollbackTransComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}

STDMETHODIMP raw_WillExecute(
BSTR *Source,
CursorTypeEnum *CursorType,
LockTypeEnum *LockType,
long *Options,
EventStatusEnum *adStatus,
struct _Command *pCommand,
struct _Recordset *pRecordset,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}

STDMETHODIMP raw_WillConnect(
BSTR *ConnectionString,
BSTR *UserID,
BSTR *Password,
long *Options,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}

STDMETHODIMP raw_ConnectComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}

STDMETHODIMP raw_Disconnect(
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}

STDMETHODIMP raw_ExecuteComplete(LONG,
Error*, EventStatusEnum*, _Command*,
_Recordset *pRecordset, _Connection*)
{
// We need to disconnect asynchronous-gotten recordsets.
// This causes access violation if recordset is being
opened synchronously
if(pRecordset)
{
pRecordset->PutRefActiveConnection((IDispatch*)NULL);
}
return S_OK;
}
};


int _tmain(int argc, _TCHAR* argv[])
{
::CoInitializeEx(NULL,COINIT_MULTITHREADED);
ConnectionEventReceiver events;
DWORD cookie = 0;

_ConnectionPtr conn(__uuidof(Connection));
conn->CursorLocation = adUseClient;
IConnectionPointContainerPtr connp_c = conn;
IConnectionPointPtr connp;
connp_c->FindConnectionPoint(__uuidof(ConnectionEvents), &connp);

connp->Advise((IUnknown*)&events, &cookie);

conn->Open(
L"Provider='sqloledb'; Data Source=(local); "
L"Initial Catalog=Northwind; Integrated Security=SSPI",
L"", L"", -1);

_RecordsetPtr rst(__uuidof(Recordset));

// Syncronous call will cause Access Violation
rst->Open(L"SELECT * FROM Employees",
_variant_t(conn.GetInterfacePtr()),
adOpenStatic,
adLockOptimistic,
adCmdText/*|adAsyncExecute*/); // If you add 'adAsyncExecute'
flag, then no execption is thrown

// Run message loop to get events when the recordset
// is being opened asynchronously.
MSG msg;
while(GetMessage(&msg, NULL, NULL, NULL))
{
DispatchMessage(&msg);
}

// Of course, we can never get here, but this
// is OK for an example application
connp->Unadvise(cookie);

return 0;
}
Vicky
2009-02-02 19:11:02 UTC
Permalink
I have this same error and it seems to be happening on Win XP Sp3 machines.
Anybody has any ideas?
-
Vikram Kulkarni
Principal Software Engg.
Captools Co.
Post by Anton Lee
Hi everybody. I'm not sure if I am posting to the right group. Correct
me if I am wrong.
Here is a C++ code that throws "Access Violation" exception when
executed.
Basically I need to open Recordset objects asynchronously (then
everything runs OK),
but sometimes synchronous calls to ADODB::Recordset::Open are
performed,
and then an exception shows up.
The problem seems to be with ADODB::Recordset's ActiveConnection
property
that is set to zero in Connection object's "ExecuteComplete" event.
If you comment out the the line where PutRefActiveConnection is
called, everything runs just fine.
Access violation reading location 0x0008006c."
msdart.dll!76588f09()
[Frames below may be incorrect and/or missing, no symbols loaded for
msdart.dll]
msdart.dll!76588f40()
msado15.dll!4ddd3987()
msado15.dll!4ddfb06a()
msdart.dll!765891fa()
ntdll.dll!7c96c5cf()
msdart.dll!76588f0c()
msado15.dll!4ddd28c8()
msado15.dll!4ddd3c5b()
msado15.dll!4ddd570a()
msado15.dll!4dddbe4c()
msdart.dll!76588f0c()
msdart.dll!76588f40()
msado15.dll!4ddda2b9()
msado15.dll!4ddda1c2()
sqloledb.dll!4dd015f6()
msado15.dll!4ddd1364()
msado15.dll!4dddeb23()
msado15.dll!4ddd9edb()
msado15.dll!4ddd39e5()
msado15.dll!4ddd62e3()
msado15.dll!4ddd4e8e()
msado15.dll!4dddf2f5()
msado15.dll!4ddd60fd()
msado15.dll!4ddd3c11()
msado15.dll!4ddd53ea()
msado15.dll!4ddd164c()
OS is Windows XP Pro SP3. MDAC version is 2.81.1132.0
In the code below only _tmain function and
ConnectionEventReceiver::raw_ExecuteComplete method are the points of
interest.
Can somebody tell me if there is anything wrong with the code? Or
maybe there could be a bug in MSADO?
Thanks in advance.
// Compiles well with Visual Studio 2005
#import "c:\Program Files\Common Files\System\ado\msado15.dll"
no_namespace rename("EOF", "adoEOF")
// Class to capture ADODB::Connection's events.
// Only raw_ExecuteComplete method actually does work
class ConnectionEventReceiver: public ConnectionEventsVt
{
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
{
*ppv = NULL;
if (riid == __uuidof(IUnknown) ||
riid == __uuidof(ConnectionEventsVt)) *ppv = this;
if (*ppv == NULL)
return ResultFromScode(E_NOINTERFACE);
AddRef();
return NOERROR;
}
STDMETHODIMP_(ULONG) AddRef(void){return 1;}
STDMETHODIMP_(ULONG) Release(void){return 1;}
STDMETHODIMP raw_InfoMessage(Error* pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_BeginTransComplete(
LONG TransactionLevel,
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_CommitTransComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_RollbackTransComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_WillExecute(
BSTR *Source,
CursorTypeEnum *CursorType,
LockTypeEnum *LockType,
long *Options,
EventStatusEnum *adStatus,
struct _Command *pCommand,
struct _Recordset *pRecordset,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_WillConnect(
BSTR *ConnectionString,
BSTR *UserID,
BSTR *Password,
long *Options,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_ConnectComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_Disconnect(
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_ExecuteComplete(LONG,
Error*, EventStatusEnum*, _Command*,
_Recordset *pRecordset, _Connection*)
{
// We need to disconnect asynchronous-gotten recordsets.
// This causes access violation if recordset is being
opened synchronously
if(pRecordset)
{
pRecordset->PutRefActiveConnection((IDispatch*)NULL);
}
return S_OK;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
::CoInitializeEx(NULL,COINIT_MULTITHREADED);
ConnectionEventReceiver events;
DWORD cookie = 0;
_ConnectionPtr conn(__uuidof(Connection));
conn->CursorLocation = adUseClient;
IConnectionPointContainerPtr connp_c = conn;
IConnectionPointPtr connp;
connp_c->FindConnectionPoint(__uuidof(ConnectionEvents), &connp);
connp->Advise((IUnknown*)&events, &cookie);
conn->Open(
L"Provider='sqloledb'; Data Source=(local); "
L"Initial Catalog=Northwind; Integrated Security=SSPI",
L"", L"", -1);
_RecordsetPtr rst(__uuidof(Recordset));
// Syncronous call will cause Access Violation
rst->Open(L"SELECT * FROM Employees",
_variant_t(conn.GetInterfacePtr()),
adOpenStatic,
adLockOptimistic,
adCmdText/*|adAsyncExecute*/); // If you add 'adAsyncExecute'
flag, then no execption is thrown
// Run message loop to get events when the recordset
// is being opened asynchronously.
MSG msg;
while(GetMessage(&msg, NULL, NULL, NULL))
{
DispatchMessage(&msg);
}
// Of course, we can never get here, but this
// is OK for an example application
connp->Unadvise(cookie);
return 0;
}
Vikram Kulkarni
2009-02-02 19:04:10 UTC
Permalink
I have this same error and it seems to be happening on Win XP Sp3 machines.
Anybody has any ideas?

Thanks
Post by Anton Lee
Hi everybody. I'm not sure if I am posting to the right group. Correct
me if I am wrong.
Here is a C++ code that throws "Access Violation" exception when
executed.
Basically I need to open Recordset objects asynchronously (then
everything runs OK),
but sometimes synchronous calls to ADODB::Recordset::Open are
performed,
and then an exception shows up.
The problem seems to be with ADODB::Recordset's ActiveConnection
property
that is set to zero in Connection object's "ExecuteComplete" event.
If you comment out the the line where PutRefActiveConnection is
called, everything runs just fine.
Access violation reading location 0x0008006c."
msdart.dll!76588f09()
[Frames below may be incorrect and/or missing, no symbols loaded for
msdart.dll]
msdart.dll!76588f40()
msado15.dll!4ddd3987()
msado15.dll!4ddfb06a()
msdart.dll!765891fa()
ntdll.dll!7c96c5cf()
msdart.dll!76588f0c()
msado15.dll!4ddd28c8()
msado15.dll!4ddd3c5b()
msado15.dll!4ddd570a()
msado15.dll!4dddbe4c()
msdart.dll!76588f0c()
msdart.dll!76588f40()
msado15.dll!4ddda2b9()
msado15.dll!4ddda1c2()
sqloledb.dll!4dd015f6()
msado15.dll!4ddd1364()
msado15.dll!4dddeb23()
msado15.dll!4ddd9edb()
msado15.dll!4ddd39e5()
msado15.dll!4ddd62e3()
msado15.dll!4ddd4e8e()
msado15.dll!4dddf2f5()
msado15.dll!4ddd60fd()
msado15.dll!4ddd3c11()
msado15.dll!4ddd53ea()
msado15.dll!4ddd164c()
OS is Windows XP Pro SP3. MDAC version is 2.81.1132.0
In the code below only _tmain function and
ConnectionEventReceiver::raw_ExecuteComplete method are the points of
interest.
Can somebody tell me if there is anything wrong with the code? Or
maybe there could be a bug in MSADO?
Thanks in advance.
// Compiles well with Visual Studio 2005
#import "c:\Program Files\Common Files\System\ado\msado15.dll"
no_namespace rename("EOF", "adoEOF")
// Class to capture ADODB::Connection's events.
// Only raw_ExecuteComplete method actually does work
class ConnectionEventReceiver: public ConnectionEventsVt
{
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
{
*ppv = NULL;
if (riid == __uuidof(IUnknown) ||
riid == __uuidof(ConnectionEventsVt)) *ppv = this;
if (*ppv == NULL)
return ResultFromScode(E_NOINTERFACE);
AddRef();
return NOERROR;
}
STDMETHODIMP_(ULONG) AddRef(void){return 1;}
STDMETHODIMP_(ULONG) Release(void){return 1;}
STDMETHODIMP raw_InfoMessage(Error* pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_BeginTransComplete(
LONG TransactionLevel,
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_CommitTransComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_RollbackTransComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_WillExecute(
BSTR *Source,
CursorTypeEnum *CursorType,
LockTypeEnum *LockType,
long *Options,
EventStatusEnum *adStatus,
struct _Command *pCommand,
struct _Recordset *pRecordset,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_WillConnect(
BSTR *ConnectionString,
BSTR *UserID,
BSTR *Password,
long *Options,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_ConnectComplete(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_Disconnect(
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus=adStatusUnwantedEvent;
return S_OK;
}
STDMETHODIMP raw_ExecuteComplete(LONG,
Error*, EventStatusEnum*, _Command*,
_Recordset *pRecordset, _Connection*)
{
// We need to disconnect asynchronous-gotten recordsets.
// This causes access violation if recordset is being
opened synchronously
if(pRecordset)
{
pRecordset->PutRefActiveConnection((IDispatch*)NULL);
}
return S_OK;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
::CoInitializeEx(NULL,COINIT_MULTITHREADED);
ConnectionEventReceiver events;
DWORD cookie = 0;
_ConnectionPtr conn(__uuidof(Connection));
conn->CursorLocation = adUseClient;
IConnectionPointContainerPtr connp_c = conn;
IConnectionPointPtr connp;
connp_c->FindConnectionPoint(__uuidof(ConnectionEvents), &connp);
connp->Advise((IUnknown*)&events, &cookie);
conn->Open(
L"Provider='sqloledb'; Data Source=(local); "
L"Initial Catalog=Northwind; Integrated Security=SSPI",
L"", L"", -1);
_RecordsetPtr rst(__uuidof(Recordset));
// Syncronous call will cause Access Violation
rst->Open(L"SELECT * FROM Employees",
_variant_t(conn.GetInterfacePtr()),
adOpenStatic,
adLockOptimistic,
adCmdText/*|adAsyncExecute*/); // If you add 'adAsyncExecute'
flag, then no execption is thrown
// Run message loop to get events when the recordset
// is being opened asynchronously.
MSG msg;
while(GetMessage(&msg, NULL, NULL, NULL))
{
DispatchMessage(&msg);
}
// Of course, we can never get here, but this
// is OK for an example application
connp->Unadvise(cookie);
return 0;
}
Loading...