WinDbg 说在图像列表中找不到“.dll”

Posted

技术标签:

【中文标题】WinDbg 说在图像列表中找不到“.dll”【英文标题】:WinDbg says ".dll" was not found in the image list 【发布时间】:2014-09-29 13:15:32 【问题描述】:

我正在尝试在 WinDbg 中加载 dll 并收到此错误。这里是细节。

    使用 VisualC++ express 构建 A.dll。

    将 A.pdb 和 A.dll 放在 d:\test\ 目录中。

    设置图片路径和符号路径为d:\test

    .sympath gives 
    OK                 D:\test
    

    尝试使用以下命令加载

    .reload /f A.dll
    

    它给了

    "A.dll" was not found in the image list.
     Debugger will attempt to load "A.dll" at given base 00000000.
    
    Please provide the full image name, including the extension (i.e. kernel32.dll)
    for more reliable results.Base address and size overrides can be given as
    .reload <image.ext>=<base>,<size>.
    DBGENG:  wined3dwddm.dll - Partial symbol image load missing image info
    DBGHELP: No header for wined3dwddm.dll.  Searching for dbg file
    DBGHELP: d:\test\A.dbg - file not found
    DBGHELP: d:\test\dll\A.dbg - path not found
    DBGHELP: d:\test\symbols\dll\A.dbg - path not found
    DBGHELP: .\A.dbg - file not found
    DBGHELP: .\dll\A.dbg - path not found
    DBGHELP: .\symbols\dll\A.dbg - path not found
    DBGHELP: A.dll missing debug info.  Searching for pdb anyway
    
    DBGHELP: wined3dwddm - private symbols & lines 
            d:\test\A.pdb - unmatched
    Unable to add module at 00000000
    

在最后一行“d:\test\A.pdb - unmatched”中,虽然它这么说,但我确信 pdb 文件是来自生成已安装 dll 的构建结果的文件。

其他问题

由于答案表明 A.dll 可能未加载,这里有一个可能的反例。为此,我需要稍微修改一下问题以反映我遇到的现实。

我有一组从开源项目构建的 dll(比如 A 到 Z dll)。老实说,我对整个项目的全貌不是很了解,我想用 WinDbg 通过跟踪函数来解决这个问题。

此外,当我在进程资源管理器中找到 A.dll 时,它就在那里。 而且,如果我尝试加载 A.dll 的符号,我会收到上述消息。有什么我想念的吗?

为什么我认为 A.dll 已加载

    我在 A.dll 中打印了一条 uniqe 消息,例如 ("this_is_uniqe_message_from_A.dll"),我可以看到该消息正在连续打印。

    我可以在进程资源管理器中看到 A.dll,链接到资源管理器进程。

另外,(我不确定这是否重要),我在 QEMU 版本 1.7.0 上使用 Windows 8.1。

此问题的原因及解决方法

原因:原因其实很简单。我要调试的进程在用户空间,当我尝试列出加载的模块时,我处于内核模式。

解决方案:我需要进入用户空间(进入我要调试的进程),然后,我可以看到模块列表。另外,我可以设置断点等。

我在 MSDN 论坛上发布了同样的问题,他们回答了我。见

http://social.msdn.microsoft.com/Forums/vstudio/en-US/263a3d84-8256-4f03-a70e-47d482a24cfb/windbg-lm-command-does-not-show-all-loaded-modules?forum=windbg#263a3d84-8256-4f03-a70e-47d482a24cfb

【问题讨论】:

通过您的编辑,请提供有关您告诉我们的内容的证据。 lm 中的模块名称可能与 DLL 的名称不同。请提供lmf 的输出作为A.dll 确实加载到进程中的证据。 首先,lmf没有在列表中显示A.dll。我添加了我相信 A.dll 已加载的原因。请看一看。 您能否提供该情况的转储或是否包含敏感数据?如果没有,能否提供源代码(SSCCE),以便我们重现问题? 【参考方案1】:

路径信息不完整

您尚未描述您是在进行实时调试还是分析故障转储。在崩溃转储的情况下,路径信息可能会丢失(例如,如果转储是使用 .dump /marR 创建的)。如果是这种情况,则需要指定可执行路径。

在第 3 步中,您说您已将图像路径和符号路径设置为 D:\test。但是,该命令的输出看起来不像典型的.sympath 输出。它应该是这样的:

0:022> .sympath d:\test
Symbol search path is: d:\test
Expanded Symbol search path is: d:\test

接下来你说你也指定了图片路径,但是你还没有显示.exepath的输出:

0:022> .exepath d:\test
Executable image search path is: d:\test
Expanded Executable image search path is: d:\test

如果您没有指定图像路径,我不确定 WinDbg 是否会在符号路径中查找 DLL。在这一点上,我会说你有两个选择:

如前所述设置.exepath 指定要加载的DLL全名:.reload /f D:\test\A.dll

意外的模块名称

一个问题可能是 WinDbg 使用的模块名称与 DLL 名称不匹配。该名称可以例如是image01000 或类似名称。如果名称不像A.dll 那样简单并且包含特殊字符,这些字符可能会被替换,例如如果是记事本++:

0:007> lm m note*
start    end        module name
00400000 005f5000   notepad__   (deferred)

要查看 DLL 名称,请使用 lmf:

0:007> lmf m note*
start    end        module name
00400000 005f5000   notepad__ C:\Program Files (x86)\Notepad++\notepad++.exe

不匹配的符号

如果您不信任 WinDbg 的匹配或不匹配符号,您还可以在 WinDbg 之外验证 PDB 文件是否与 DLL 匹配。

使用 Symchk(调试工具)检查

检查您是否有私有符号:

Symchk /if <dll> /s <pdbdir> /av /od /pf

检查您是否有公共符号:

Symchk /if <dll> /s <pdbdir> /av /od /ps

使用 ChkMatch 检查

下载ChkMatch并执行

ChkMatch -c <dll> <pdb>

【讨论】:

【参考方案2】:

您不能强制 WinDbg 将 DLL 加载到进程中,进程必须加载它,然后您可以使用 WinDbg 查看内存中的 DLL。

【讨论】:

输出显示开始和结束地址相同,这对于有效加载的图像没有意义。您如何确认它实际上已加载到该地址?尝试检查 Process Explorer 或 VMMap。当您使用 .reload 加载图像时,它实际上只会影响 WinDbg 对已加载模块列表的内部表示,它不一定会在进程中加载​​图像(因为您需要在进程中注入和执行代码) 感谢您的回答。我有一个后续问题。你能看看这个吗?【参考方案3】:

如果这个问题是关于强制 windbg 将 dll 加载到进程中,是的,即使进程不想加载它,也可以强制 windbg 将 dll 加载到进程中

0:000> .load sdbgext ; !loaddll f:\masm32\icztutes\tute17\skeleton.dll ; g
kernel32!LoadLibraryA() will be run when execution is resumed

ModLoad: 10000000 10005000   f:\masm32\icztutes\tute17\skeleton.dll
kernel32!LoadLibraryA() returned 10000000
(7a8.aac): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=0030020e ecx=7c91ead5 edx=0034fd7d esi=7c801d7b edi=7c81cb12
eip=7c90120e esp=0034ff9c ebp=0034fff0 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
ntdll!DbgBreakPoint:
7c90120e cc              int     3
0:001> lmDvm sk*
Browse full module list
start    end        module name
10000000 10005000   skeleton   (deferred)             
    Image path: f:\masm32\icztutes\tute17\skeleton.dll
    Image name: skeleton.dll
    Browse all global symbols  functions  data
    Timestamp:        Wed Sep 14 11:13:41 2005 (4327B88D)
    CheckSum:         00000000
    ImageSize:        00005000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4

编辑地址评论

原来的 .reload output says missing symbol info 虽然你说你有 a.pdb for a.dll 你do not provide the real name and a real output and one may not be able to infer 你的问题是from your descriptions 但是你是专家let the tools speak for themselves 他们会说更好和通用的语言。

除非绝对必要 refrain from moving dlls and pdbs around symsrv dll 完全能够在构建目录中找到您的 dll exe 和 pdb

building an exe (mydlluser.exe) that depends on a dll (mydll.dll) 在 Visual Studio 2010 中表达 必须类似于此演练(all defaults nothing except a header inclusion and a single line of code that references the function in header added to default project below)

开始->程序->msvcvs2010e->msvcvs2010e 新建项目->win32XXXXX(使用控制台在 示例->mydlluser->ok->完成 新建项目->win32XXXXX(再次使用控制台)->mydll->添加到 解决方案->好的 不要点击完成更改应用设置来构建 dll ->应用程序设置->dll & 导出符号->完成 设置项目属性的包含路径和库路径 项目->属性->配置属性->vc++目录 -> 包含 -> 选择 mydll 文件夹的路径 设置项目依赖关系 项目 -> 项目依赖项 -> mydll 确认依赖项中的构建顺序(默认情况下会构建 mydll 首先,依赖于 mydll 的 mydlluser 将在 mydll 之后构建 只要确保它是这样设置的

add the header mydll.h to mydlluser-&gt;header files(如果您正确地来到这里,intellisense 应该在您开始输入时显示 mydll.h)

add code调用vsstudio fnmydll()提供的默认虚拟函数;

clickf7 构建both the exe and dll

load mydlluser.exe in windbg 导航到文件夹 xxxxx\mydlluser\debug\

并且 dll 应该在 lm 列表中自动可用

0:000> lm m my*
start    end        module name
00400000 0041b000   mydlluser   (deferred)             
10000000 1001b000   mydll      (deferred)             

.reload 应该能正确找到 dll 和 pdb

查找 pdbcopy or binplace 以将 dll 正确存储在 symsrv 目录结构中 可通过 _NT_SYMBOL_PATH 环境变量引用

:000> .reload /f my*
SYMSRV:  f:\symbols\mydlluser.pdb\2C83FCEAE7EE4AEC822172C75022549E2\mydlluser.pdb not found
SYMSRV:  http://msdl.microsoft.com/download/symbols/mydlluser.pdb/2C83FCEAE7EE4AEC822172C75022549E2/mydlluser.pdb not found
*** WARNING: Unable to verify checksum for mydlluser.exe
DBGHELP: mydlluser - private symbols & lines 
         C:\Documents and Settings\Admin\My Documents\Visual Studio 2010\Projects\mydlluser\Debug\mydlluser.pdb

如果您已关注to a T,您现在可以开始添加任意数量的 dll 以及您需要添加到所有这些不同 dll 的任何代码和 以您希望构建它们的任何顺序构建它,windbg 应该能够 在构建目录中找到所有 dll / exe / 和它们的 pdb

无需设置 .sympath .imgpath .whateverpath 全部在默认位置,由 Visual Studio 正确复制

:\>dir /b *.exe *.dll *.pdb
mydlluser.exe
mydll.dll
mydll.pdb
mydlluser.pdb
vc100.pdb

:\>

【讨论】:

问题是关于为已加载的模块加载符号。看起来我的模块(我认为加载正确)不在 lm 列表中。我不知道为什么会发生这种情况......(顺便说一句,我添加了一个关于此评论的附加问题) 既然有3 ways to inject your code into another process,我想知道为什么WinDbg不能开箱即用。 +1 @jaeyong 您原始输入中的信息没有传达任何线索我已在我的答案中添加了一些内容,看看您是否可以关注它【参考方案4】:

就像snoone 提到的那样,您收到该消息是因为您的 DLL 尚未被您的进程使用。也就是说,它不存在于内存中。

你可以试试这个

一个。 sxe ld:a.dll -- 这将确保您在内存中加载 A.DLL 时中断调试器

b.在此之后,您加载符号的尝试应该会成功!

【讨论】:

以上是关于WinDbg 说在图像列表中找不到“.dll”的主要内容,如果未能解决你的问题,请参考以下文章

错误“在 Visual Studio 中找不到元数据文件 '...\Release\project.dll'”

Win7下在Visual Studio 2008里运行程序时出现找不到MFC90D.dll文件, Command Prompt找不指定路径

项目在 Visual Studio 2015 PrivateAssemblies 中找不到 dll

在 Hololens 项目中找不到 DLL。 (您是不是缺少 using 指令或程序集引用?)

在模块 WindowsBase.dll 中找不到类型 System.Windows.DependencyObject

maven-shade-plugin 错误:在“资源”的 org.apache.maven.plugins.shade.resource.ManifestResourceTransformer 中找不