WinDbg says “.dll” was not found in the image list

2019-05-29 02:07发布

问题:

I'm trying to load a dll in WinDbg and got this error. Here goes the detail.

  1. Build A.dll using VisualC++ express.

  2. Place A.pdb and A.dll in d:\test\ directory.

  3. Set the image path and symbol path to d:\test

    .sympath gives 
    OK                 D:\test
    
  4. try loading by using the following command

    .reload /f A.dll
    

    and it gives

    "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
    

In the last line "d:\test\A.pdb - unmatched", although it says this, I'm sure that the pdb file is the one from the build-result where the installed dlls are also generated from.

additional question

As the answers suggest that A.dll is probably not loaded, here is an possible counter example. For this, I need to revise the question a bit to reflect the reality that I ran into.

I have set of dlls (say, A to Z dlls) which are built from open-source project. To be honest, I don't understand the full picture of the whole project and I want to figure this out with WinDbg by tracing functions.

Moreover, when I find A.dll in process explorer, it is there. And, if I try to load A.dll's symbol, I've got the above message. Is there something I miss here?

Why I believe A.dll is loaded

  1. I print a uniqe message such as ("this_is_uniqe_message_from_A.dll") in A.dll and I can see the message is printing continuously.

  2. I can see A.dll in process explorer, linked to explorer process.

Additionally, (I'm not sure if it matters), I'm using Windows 8.1 on QEMU version 1.7.0.

The cause of this problem and the solution

The cause: The cause was actually very simple. The process that I want to debug is in user-space and I was in kernel-mode when I try to list the loaded modules.

The solution: I need to break into user-space (to the process that I want to debug) and then, I can see the module lists. Also, I can set breakpoint, etc.

I've posted the same question in MSDN forum and they answered me. See

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

回答1:

Incomplete path information

You have not described whether you're doing live debugging or analyzing a crash dump. In case of a crash dump, the path information can be missing (e.g. if the dump was created using .dump /marR). If this is the case, you need to specify the executable path.

In step 3 you say you have set the image path and symbol path to D:\test. However, the output of the command does not look like a typical .sympath output. It should look like this:

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

Next you say that you have specified the image path as well, but you have not shown the output of .exepath:

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

If you didn't specify the image path, I'm not sure whether WinDbg would look in the Symbol path to find the DLL. At this point I would say you have two choices:

  • set .exepath as described before
  • Specify the full name of the DLL to load: .reload /f D:\test\A.dll

Unexpected module names

One problem might be that the name of the module used by WinDbg does not match the DLL name. The name can e.g. be image01000 or similar. In case the name is not as simple as A.dll and contains special characters, these characters might be replaced, e.g. in case of Notepad++:

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

To see the DLL names, use lmf:

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

Unmatched symbols

If you don't trust WinDbg about matching or non-matching symbols, you can also verify outside of WinDbg whether or not the PDB file matches the DLL.

Check with Symchk (Debugging Tools)

To check if you have private symbols:

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

To check if you have public symbols:

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

Check with ChkMatch

Download ChkMatch and execute

ChkMatch -c <dll> <pdb>


回答2:

You can't force WinDbg to load a DLL into a process, the process has to load it and then you can use WinDbg to look at the DLL in memory.



回答3:

if this question is about forcing windbg to load a dll into process yes one can force windbg to load a dll into process even if the process doesn't want to load it

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

edit to address comment

the original .reload output says missing symbol info though you say you have a.pdb for a.dll
you do not provide the real name and a real output and one may not be able to infer
what your problem is from your descriptions however expert you are
let the tools speak for themselves they speak a better and common language.

unless absolutely necessary refrain from moving dlls and pdbs around
symsrv dll is perfectly capable of finding your dlls exes and pdb in the build directory

building an exe (mydlluser.exe) that depends on a dll (mydll.dll) in visual studio 2010 express
must resemble this walkthorugh (all defaults nothing except a header inclusion and a single line of code that references the function in header added to default project below)

  • start->programs->msvcvs2010e->msvcvs2010e
  • new project->win32XXXXX(using console in example->mydlluser->ok->finish
  • new project->win32XXXXX(using console again)->mydll->add to solution->ok
  • do not click finish change app settings to build a dll
  • ->application settings->dll & Export symbols -> finish
  • set include and lib paths to project properties
  • project -> properties-> configuaration properties -> vc++ directories -> include -> choose path to mydll folder
  • set project dependencies
  • project -> project dependencies -> mydll
  • confirm build order in dependencies (by default mydll will be built first and mydlluser that depends on mydll will be built after mydll
    just make sure that is how it is setup

add the header mydll.h to mydlluser->header files (intellisense should show mydll.h as you start typing if you have come upto here correctly)

add code that calls the default dummy function provided by vsstudio fnmydll();

clickf7 to build both the exe and dll

load mydlluser.exe in windbg by navigating to the folder xxxxx\mydlluser\debug\

and the dll should be automatically available in lm list

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

.reload should find the dll and pdb correctly

lookup pdbcopy or binplace to properly store the dlls in a symsrv directory structure referable by _NT_SYMBOL_PATH environment variable

: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

if you have followed to a T you can now start adding as many dlls as you wish and whatever code you need to add to all those different dlls and
build it in whatever order you wish to build them and windbg should be able to
find all the dlls / exes / and thier pdbs in build directory

no need to set .sympath .imgpath .whateverpath it is all in thier default places properly copied by visual studio

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

:\>


回答4:

Like snoone mentioned your are getting that message coz your DLL is not being used by your process yet. That is, it is not present in the memory.

You may want to try this

a. sxe ld:a.dll -- this will ensure that you break in the debugger whenever A.DLL is loaded in the memory

b. after this your attempt to load symbols should succeed!