加载DLL时访问冲突

时间:2011-07-19 11:20:01

标签: c windows visual-c++ dll access-violation

普通C应用程序在MSVC6上编译正常,但在运行时会引发访问冲突。

在WinDbg中运行应用程序时,我在加载rasadhlp.dll(一个Windows文件)时出现了AV错误。

问题:加载Windows dll时可能导致访问冲突的原因是什么?

我习惯于处理各种nix而不是windows,因此可能会有一些非常明显的东西我不知道。

[...]
ModLoad: 77920000 77a13000   C:\WINDOWS\system32\SETUPAPI.dll
ModLoad: 76fc0000 76fc6000   C:\WINDOWS\system32\rasadhlp.dll
  (f38.a08): Access violation - code c0000005 (first chance)
  First chance exceptions are reported before any exception handling.
  This exception may be expected and handled.
  eax=00000000 ebx=00000000 ecx=00000000 edx=0049f8f0 esi=0049f8f0 edi=00000000
  eip=7c918fea esp=0012fbdc ebp=0012fc50 iopl=0         nv up ei ng nz na pe nc
  cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010286
  ntdll!RtlpWaitForCriticalSection+0x5b:
  7c918fea ff4010          inc     dword ptr [eax+10h]  ds:0023:00000010=????????
0:000> g
  (f38.a08): Access violation - code c0000005 (!!! second chance !!!)
  eax=00000000 ebx=00000000 ecx=00000000 edx=0049f8f0 esi=0049f8f0 edi=00000000
  eip=7c918fea esp=0012fbdc ebp=0012fc50 iopl=0         nv up ei ng nz na pe nc
  cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000286
  ntdll!RtlpWaitForCriticalSection+0x5b:
  7c918fea ff4010          inc     dword ptr [eax+10h]  ds:0023:00000010=????????

注意:该应用程序是在win2k上编译的,在XP上测试过。 (由于各种奇怪的原因,现在无法改变......)

[edit]:程序跟踪:

ntdll!RtlpWaitForCriticalSection+0x5b
ntdll!RtlEnterCriticalSection+0x46
msvcrt!vprintf+0x18
intl!libintl_vfprintf+0xa8
intl!libintl_fprintf+0x1f
image00400000+0x6239
MSCTF!DllGetClassObject+0x1de9
ntdll!RtlpNtMakeTemporaryKey+0x7ec8
ntdll!RtlInitializeSListHead+0x115c0
ntdll!iswdigit+0x339
ntdll!LdrGetProcedureAddress+0x4b
image00400000+0x626f4

[编辑2]:我知道调试器首先捕获到异常,这是完全正常的。您会在日志中注意到我手动跳过第一次机会异常,并强制它进入我的程序。我想知道这种错误的起源,而不是处理。

2 个答案:

答案 0 :(得分:2)

请参阅Microsoft support - First and second chance exception handling

  

将SEH用作信号传导机制是一种常见做法。一些   应用程序编程接口(API)注册异常   处理程序预期会出现故障情况   发生在较低层。

     

当引发异常时,处理程序可能会更正或忽略该异常   条件而不是允许失败传播   干预层。这在复杂的环境中非常有用   作为预期部分失败的网络,而不是   希望只是因为其中一个操作而导致整个操作失败   可选部件失败。在这种情况下,可以处理异常   应用程序无法识别异常   发生。

     

但是,如果正在调试应用程序,则调试器会查看所有内容   程序之前的异常。这是区别   第一次和第二次机会异常:调试器得到第一个   有机会看到异常(因此得名)。如果调试器允许   程序执行继续并且不处理异常,   该程序将像往常一样看到异常。如果程序没有   处理异常,调试器获得第二次看到的机会   例外。在后一种情况下,程序通常会崩溃   调试器不存在。

     

如果您不想在调试器中看到第一次机会异常,   你应该禁用特定的第一次机会异常处理   异常代码。否则,当第一次机会异常发生时,你   可能需要指示调试器将异常传递给   程序要照常处理。

答案 1 :(得分:2)

加载库时RtlpWaitForCriticalSection中的访问冲突通常是由于库试图在DllMain中使用LoadLibrary或kernel32.dll之外的代码引起的,因为操作系统在调用该例程时持有“加载程序锁定”。