尝试调试调用 C++ DLL 的 VBA,“未加载 wntdll.pdb”

Posted

技术标签:

【中文标题】尝试调试调用 C++ DLL 的 VBA,“未加载 wntdll.pdb”【英文标题】:Trying to debug VBA that calls a C++ DLL, "wntdll.pdb not loaded" 【发布时间】:2013-11-01 18:18:09 【问题描述】:

这是一个很长的解释,但我不确定问题出在我的调试过程中。

我有一个调用 C++ DLL 中的函数的 Excel 宏。每次调用此函数时,Excel 实例都会突然强制退出,没有警告或错误消息。我正在尝试通过在 Visual Studio Express 中设置调试来跟踪发生的情况,如下所示:

配置属性->调试->命令:C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE

配置属性->C/C++->浏览信息->启用浏览信息:是(/FR)

然后我通过单击要测试的函数、设置断点并按 F5 开始调试。我收到一条错误消息,告诉我调试信息不​​适用于 Excel.exe,然后单击“是”继续调试。

打开一个 Excel 实例。 C++ 断点现在已更改为白色的“不会命中断点”圆圈。我打开包含宏的工作簿,然后运行宏。

在 Visual Studio 中,我收到一条消息,指出 EXCEL.EXE 已触发断点,我猜这是我在 C++ 代码中设置的断点,然后单击“Break”。将打开一个新选项卡,并显示一条消息:

wntdll.pdb not loaded

此时,调试器将无法继续,所以我手动停止它,Excel 强制退出;输出窗口说

EXCEL.EXE 已退出,代码为 0

我进入 Debug options->Symbols 并选中“Microsoft Symbol Server”框;我不知道哪些 DLL 需要符号,所以我选择“自动为所有模块加载符号”。我启动调试器。

我收到关于 Excel 不可用的调试信息的相同消息,然后 Excel 实例打开。我再次打开工作簿并启动宏。同时,在 VS 中加载了很多 DLL 的符号。

在 VS 中弹出一个选项卡,上面写着:

Source not available
Source information is missing from the debug information in this module.

可能还没有加载正确的 DLL 符号,但我不想等待所有符号加载;我之前尝试过,10 分钟过去了,符号仍在加载。

查看调用堆栈,以下调用是最近的:

ntdll.dll!_RtlReportCriticalFailure@8() Unknown
ntdll.dll!_RtlpReportHeapFailure@4()    Unknown
ntdll.dll!_RtlpLogHeapFailure@24()  Unknown

我的 C++ 应用程序的代码还没有被调用;这些调用紧跟在 VBE7 和 ole32 调用之后。

我只想能够调试我的代码并找出 Excel 退出的原因。任何人都可以理解这里发生的事情吗?

编辑:这是发生错误时的完整调用堆栈:

ntdll.dll!_RtlReportCriticalFailure@8() Unknown
ntdll.dll!_RtlpReportHeapFailure@4()    Unknown
ntdll.dll!_RtlpLogHeapFailure@24()  Unknown
ntdll.dll!_RtlSizeHeap@12() Unknown
ole32.dll!CRetailMalloc_GetSize(IMalloc * pThis, void * pv) Line 710    C++
oleaut32.dll!APP_DATA::FreeCachedMem(void *,unsigned long)  Unknown
oleaut32.dll!_SysFreeString@4() Unknown
VBE7.DLL!_lblEX_FFreeStr()  Unknown
VBE7.DLL!_lblEX_VCallHresult()  Unknown
VBE7.DLL!_lblEX_ImpAdCall() Unknown
VBE7.DLL!InvokeImmedSub(struct RTMI *,class GEN_PROJECT *,class EXFRAME *,struct IDispatch *)   Unknown
VBE7.DLL!WATCHMGR::ExecuteImmedLogln(char * *,unsigned int,int,class GEN_PROJECT *,unsigned long,int,int,class WATCH *) Unknown
VBE7.DLL!ExecProcUnderCursor(void)  Unknown
VBE7.DLL!_EbInvokeItem@4()  Unknown
VBE7.DLL!CmdFDispatchCommand(unsigned short)    Unknown
VBE7.DLL!FTranslateAccelerator(struct tagMSG *,int) Unknown
VBE7.DLL!FRubyMsg(struct tagMSG *)  Unknown
VBE7.DLL!MainFTranslateMessage(struct tagMSG *,unsigned long)   Unknown
VBE7.DLL!CMsoComponent::FPreTranslateMessage(struct tagMSG *)   Unknown
EXCEL.EXE!2f9f874a()    Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for EXCEL.EXE] 
EXCEL.EXE!2f9f73f4()    Unknown
MSO.DLL!637b77f1()  Unknown
MSO.DLL!637e0143()  Unknown
EXCEL.EXE!2f990ec5()    Unknown
msvcr90.dll!___set_flsgetvalue()    Unknown
msvcr90.dll!__getptd_noexit()   Unknown
msvcr90.dll!__getptd()  Unknown
msvcr90.dll!_LocaleUpdate::_LocaleUpdate(struct localeinfo_struct *)    Unknown
msvcr90.dll!__ismbcalpha()  Unknown
msvcr90.dll!__ismbblead()   Unknown
0062430d()  Unknown
kernel32.dll!@BaseThreadInitThunk@12()  Unknown
ntdll.dll!___RtlUserThreadStart@8() Unknown
ntdll.dll!__RtlUserThreadStart@8()  Unknown

【问题讨论】:

出错时能否给出完整的调用栈? @IlyaBursov,刚刚发布。 0062430d() Unknown 看起来很可疑,但无法确定,尝试另一种方法:不调试运行 excel,然后使用 studio 到 attach to process,然后尝试执行 excel 宏 @IlyaBursov,当我这样做时,没有一个断点被命中,Excel 就退出了。但是,来自宏的 DLL 调用正在执行——其中一个涉及创建文件,并且正在生成该文件。 尝试以下操作:在dll函数的最开始添加对winapiDebugBreak的调用,在调试模式下编译你的dll,尝试运行excel和宏,你会得到一个关于断点到达的消息,然后点击调试/重试 - 不记得究竟会出现哪个按钮 【参考方案1】:

程序数据库 (PDB) 文件包含调试和项目状态信息,允许增量链接程序的调试配置。 Visual Studio 只是告诉你,他找不到相关的调试信息,让你用源代码进行调试。

我认为wntdll.pdbntdll.dll 相关,您可以通过进入工具 -> 选项 -> 调试 -> 符号来设置 VS 中的符号目录。

这个页面有一些信息,特别是关于使用symchk.exe下载符号的部分:

Windows Debugging Symbols - Not Loading

symchk.exe的使用说明在:

http://support.microsoft.com/kb/311503

现在这个问题可能与您的崩溃无关,我建议您使用Process Monitor 来监控来自进程的消息。这可能会极大地帮助您找出问题所在。

【讨论】:

我下载了 Process Monitor,并运行了与上述相同的调试方法。我不确定如何解释这些消息。最后,有很多 WDEXPRESS.EXE 和 EXCEL.EXE 消息说“关闭文件”。我应该寻找什么? 很难判断,因为您目前没有足够的信息来缩小范围。您是否尝试停止视觉工作室中的异常?你有你调用的DLL的代码吗?尝试在 DLL 上的 ProcMon 中进行过滤。

以上是关于尝试调试调用 C++ DLL 的 VBA,“未加载 wntdll.pdb”的主要内容,如果未能解决你的问题,请参考以下文章

有啥方法可以调试从 C# DllImport 调用的 c++ dll?

使用指针调用 C++ DLL 函数

如何调试 c++ dll 的 ctypes 调用?

从 python 调试 VS2010 中的 c++ dll

使用 VBA 和 C++ DLL 的伪逆计算

C#调用C++DLL的小总结5---和C++的DLL的联合调试