Windows 在调试器下加载DLL时发生访问冲突

Windows 在调试器下加载DLL时发生访问冲突,windows,dll,windbg,access-violation,Windows,Dll,Windbg,Access Violation,我试图用WinDbg调试一个C/C++Win32 DLL,但目前无法加载,访问冲突。以下是日志中经过编辑的片段: ModLoad: 77bd0000 77bd7000 C:\WINDOWS\system32\midimap.dll ModLoad: ...\PyFM.fmx <-- THIS IS MY DLL *** ERROR: Symbol file could not be found. Defaulted to export symbols for ..

我试图用WinDbg调试一个C/C++Win32 DLL,但目前无法加载,访问冲突。以下是日志中经过编辑的片段:

ModLoad: 77bd0000 77bd7000   C:\WINDOWS\system32\midimap.dll
ModLoad: ...\PyFM.fmx       <-- THIS IS MY DLL
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for
    ...\FMWrapper.dll - 
ModLoad: ...\FMWrapper.dll   <-- THIS IS ANOTHER DLL I LINK AGAINST
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for
    C:\WINDOWS\WinSxS\x86_Microsoft.VC90.
    DebugCRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_f863c71f\MSVCR90D.dll - 
ModLoad: 10200000 10323000  C:\WINDOWS\WinSxS\x86_Microsoft.VC90.
    DebugCRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_f863c71f\MSVCR90D.dll
(564.970): 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=05e79b68 ecx=b79a0c61 edx=0049e000 esi=05e79c0c edi=00000080
eip=02887094 esp=0012fa0c ebp=00120000 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
DBEngine!Draco::DBPlugIn::MakeCall+0x94:
02887094 c745fcffffffff  
    mov     dword ptr [ebp-4],0FFFFFFFFh ss:0023:0011fffc=????????
如果我尝试一步一步地继续(尽管我不理解汇编指令),我会看到控制权被传递到
ntdll
;e、 g.下一个指示是:

ntdll!KiUserExceptionDispatcher+0x4:
7c90e480 8b1c24
    mov     ebx,dword ptr [esp]  ss:0023:0012f71c=0012f724
我尝试的:不多,因为我不明白发生了什么。最初,我是通过DLL的非调试构建得到这个错误的;然后我尝试使用调试版本,但错误仍然存在。我曾经怀疑过这些清单,也读过一些关于它们的文章,但这一部分似乎没有什么错;我甚至检查了清单文件大小是4的倍数:)

为什么会这样?我要去哪里看?

“第一次机会例外”通常是正常的,通常可以忽略

如果您在调试器中继续执行该程序——不仅是下一条指令,还要使其再次运行;我认为这是WinDbg中的“g”命令——它是工作的还是在另一个异常(不是“第一次机会异常”)下崩溃的

(如果您得到了另一个“第一次机会异常”,那么您也可以忽略它;这意味着第一个异常已经由异常处理程序处理,现在您看到的是一个完全不同的异常,它也可以处理。)

一些代码使用(或者说滥用)异常进行正常的流控制,这使得在调试器下运行代码变得困难,调试器设置为在抛出异常时立即中断。您可以将调试器配置为仅在未处理异常时中断


另一方面,如果继续执行程序确实会导致未处理的异常,那么代码中可能存在错误(可能是由调试器更改某些事情的运行速度或运行顺序而触发的争用条件),或者您没有像往常一样在同一上下文中运行程序(例如,当前目录、DLL路径、环境变量或其他内容是不同的)。或者,您正在使用的DLL可能会显式检查调试器,以尝试并阻止人们对其进行反向工程(但这非常罕见)。

是的,主程序预期并处理此异常,并自行继续,但没有my DLL:)据我所知,主程序试图调用我的DLL中的函数,但失败了。让我困惑的是,它在调用之前似乎失败了:我试图在DLL函数中设置断点,但要么设置错误,要么从未命中。@Mikhail:主程序是如何链接到您的DLL的?听起来像是使用延迟加载,然后可能找不到DLL或函数。我还尝试在VisualStudio中设置断点,而不是在WinDbg中设置断点;WinDbg功能更强大,但VS调试器在用户不需要额外功能的情况下更友好、更好(IMO)。在VS调试器中,请确保断点有一个红色实心圆圈,而不仅仅是一个轮廓(这意味着您的DLL尚未加载)和/或DLL,其调试符号和源代码不同步);我还没有找到问题的根源,但至少我发现我在原因上是错的:库加载并实际被调用了几次,接下来会发生异常。这意味着我写的一切都不相关;我现在正在探索代码。不知何故,我不习惯IDE,所以WinDbg对我来说更好;我发现它类似于gdb,尽管使用起来比较困难。
ntdll!KiUserExceptionDispatcher+0x4:
7c90e480 8b1c24
    mov     ebx,dword ptr [esp]  ss:0023:0012f71c=0012f724