首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >64位ACE OLEDB提供程序导致SysFreeString中的访问冲突

64位ACE OLEDB提供程序导致SysFreeString中的访问冲突
EN

Stack Overflow用户
提问于 2015-07-15 17:18:27
回答 1查看 1.4K关注 0票数 0

由于遗留原因,我的应用程序使用MS访问mdb文件。它使用以下连接字符串使用ADO连接到数据库:

Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;Data Source=Dummy.mdb

最近,我开始将我的应用程序移植到64位。由于Jet提供程序在64位系统上不可用,所以我使用了ACE OLEDB提供程序,其连接字符串如下:

Provider=Microsoft.ACE.OLEDB.12.0;Persist Security Info=False;Data Source=Dummy.mdb

应用程序还使用MS来处理XML文件。有时64位版本会崩溃,SysFreeString中的访问冲突异常是从MS包装器方法中调用的。32位版本没有这些问题。我把这个问题归纳到测试器的应用中。

代码语言:javascript
复制
#define _WIN32_WINNT 0x0501

#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <conio.h>
#include <ObjBase.h>

#import <msxml6.dll>
#import <msado15.dll> rename("EOF", "EndOfFile")

using namespace ADODB;

bool s_bRepeat = true;

unsigned __stdcall XmlThreadFunc(void*)
{
  CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  MSXML2::IXMLDOMDocumentPtr l_pXMLDom;
  l_pXMLDom.CreateInstance(__uuidof(DOMDocument), NULL, CLSCTX_INPROC_SERVER);
  l_pXMLDom->async = VARIANT_FALSE;
  MSXML2::IXMLDOMElementPtr l_pRoot = l_pXMLDom->createElement("root");
  l_pXMLDom->appendChild(l_pRoot);
  unsigned int l_nCnt = 0;
  while (s_bRepeat)
  {
    if (0 == l_nCnt++ % 1000)
    {
      printf(".");
    }
    l_pRoot->setAttribute("test", "Test1");
    Sleep(0);
  }
  CoUninitialize();
  _endthreadex(0);
  return 0;
} 

unsigned __stdcall DbThreadFunc(void*)
{
  CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  _ConnectionPtr l_pConnection;
  l_pConnection.CreateInstance(__uuidof(Connection));
#ifdef _WIN64
  LPCSTR l_cszConnectStr = "Provider=Microsoft.ACE.OLEDB.12.0;Persist Security Info=False;Data Source=Dummy.mdb";
#else
  LPCSTR l_cszConnectStr = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;Data Source=Dummy.mdb";
#endif
  while (s_bRepeat)
  {
    l_pConnection->Open(l_cszConnectStr, "", "", adConnectUnspecified);
    Sleep(1000);
    printf("(");
    l_pConnection->Close();
    printf(")");
  }
  CoUninitialize();
  _endthreadex(0);
  return 0;
} 

int main()
{
  HANDLE l_hXmlThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &XmlThreadFunc, NULL, 0, NULL));
  HANDLE l_hDbThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &DbThreadFunc, NULL, 0, NULL));
  _getch();
  s_bRepeat = false;
  HANDLE l_Handles[2] = { l_hXmlThread, l_hDbThread };
  WaitForMultipleObjects(2, l_Handles, TRUE, INFINITE);
  CloseHandle(l_hXmlThread);
  CloseHandle(l_hDbThread);
  return 0;
}

崩溃调用堆栈如下:

代码语言:javascript
复制
OLEAUT32!SysFreeString
TestCrash64Lean!_bstr_t::Data_t::_Free
TestCrash64Lean!_bstr_t::Data_t::~Data_t
TestCrash64Lean!_bstr_t::Data_t::`scalar deleting destructor'
TestCrash64Lean!_bstr_t::Data_t::Release
TestCrash64Lean!_bstr_t::_Free
TestCrash64Lean!_bstr_t::~_bstr_t
TestCrash64Lean!MSXML2::IXMLDOMElement::setAttribute
TestCrash64Lean!XmlThreadFunc
MSVCR80D!_callthreadstartex
MSVCR80D!_threadstartex
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart

崩溃时,DB线程始终处于以下状态:

代码语言:javascript
复制
MSVCR90!memset
mso!Ordinal4118
mso!Ordinal7994
mso!MsoUninitOffice
ACECORE
ACECORE
ACEOLEDB!DllGetClassObject
ACEOLEDB!DllGetClassObject
ACEOLEDB!DllGetClassObject
ACEOLEDB!DllGetClassObject
oledb32!CAcm::FinalRelease
oledb32!ATL::CComPolyObject<CDCM>::~CComPolyObject<CDCM>
oledb32!ATL::CComPolyObject<CDCM>::Release
oledb32!CDCMCreator::DestroyResource
comsvcs!CHolder::SafeDispenserDriver::DestroyResource
comsvcs!CHolder::ProcessDestroyList
comsvcs!CHolder::FreeResource
oledb32!CDCMCreator::ReleaseResource
oledb32!CDPO::ReturnDCMToPool
oledb32!CDPO::FinalRelease
oledb32!ATL::CComPolyObject<CDPO>::`scalar deleting destructor'
oledb32!ATL::CComPolyObject<CDPO>::Release
msado15!CConnection::_Close
msado15!CConnection::Close
TestCrash64Lean!ADODB::Connection15::Close
TestCrash64Lean!DbThreadFunc
MSVCR80D!_callthreadstartex
MSVCR80D!_threadstartex
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart

我发现,作为解决办法,如果我保持一个打开的连接到一些空数据库文件,我可以打开和关闭连接到实际的数据库文件,并且应用程序不会崩溃。无论如何,我宁愿了解坠机的实际原因。如有任何建议,我将不胜感激。

我的配置如下:

Microsoft Visual Studio 2005版本8.0.50727.4039 (QFE.050727-4000) Windows 2008 R2标准64位 处理器: Intel(R) Xeon(R) E5645 @ 2.40GHz 内存:16.0GB

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-16 15:38:35

看起来这是2010可再发行的ACE OLEDB提供程序的一个问题。从Microsoft 2013运行时切换到提供程序解决了这个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31436950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档