我想我不需要强调在调试时拥有有效的PDB文件有多重要。通常,PDB文件是由调试器静默加载的,并且您很高兴在modules窗口中看到解析的所有符号。不幸的是,您还可能遇到调试器找不到匹配符号的情况。其原因可能与断开的互联网连接或更复杂的签名不匹配一样微不足道。在本文中,我将向您展示如何在调试之前检查符号文件,以及如何从中提取源文件信息。由于有不同的方法(和工具)来操作符号文件,我将介绍我所知道的那些。

下载给定PE文件的PDB文件

由于PDB文件格式是微软的秘密,所以我介绍的所有工具都只是API的包装器。要处理PDB文件,我们首先需要获取它们。让我们列出能帮助我们的工具。

symchk.exe

符号检查器(Symchk.exe)是一个应用程序,它将可执行文件与符号文件进行比较,以验证匹配的符号是否可用。Symchk也可以用于填充符号缓存。它可以从PE文件(exe,dll)、转储文件和进程中读取符号信息。它还支持递归目录搜索和批处理文件。

我们将从加载kernel32.dll库的符号开始:

c:\Windows\System32>echo %_NT_SYMBOL_PATH%
 
c:\Windows\System32>symchk /v /os kernel32.dll
[SYMCHK] Searching for symbols to c:\Windows\System32\kernel32.dll in path SRV*C:\Symbols\MSS*http://referencesource.microsoft.com/symbols;SRV*C:\Symbols\MSS*http://msdl.microsoft.com/download/symbols
DBGHELP: Symbol Search Path: SRV*C:\Symbols\MSS*http://referencesource.microsoft.com/symbols;SRV*C:\Symbols\MSS*http://msdl.microsoft.com/download/symbols
[SYMCHK] Using search path "SRV*C:\Symbols\MSS*http://referencesource.microsoft.com/symbols;SRV*C:\Symbols\MSS*http://msdl.microsoft.com/download/symbols"
DBGHELP: No header for c:\Windows\System32\kernel32.dll.  Searching for image on disk
DBGHELP: c:\Windows\System32\kernel32.dll - OK
SYMSRV:  C:\Symbols\MSS\kernel32.pdb\9B30FD7CD6B44975BF34B43B6EF668212\kernel32.pdb not found
SYMSRV:  kernel32.pdb from http://msdl.microsoft.com/download/symbols: 704453 bytes - copied
DBGHELP: kernel32 - public symbols
         C:\Symbols\MSS\kernel32.pdb\9B30FD7CD6B44975BF34B43B6EF668212\kernel32.pdb
[SYMCHK] MODULE64 Info ----------------------
[SYMCHK] Struct size: 1680 bytes
[SYMCHK] Base: 0x0000000078D20000
[SYMCHK] Image size: 1175552 bytes
[SYMCHK] Date: 0x4e21213b
[SYMCHK] Checksum: 0x0012386d
[SYMCHK] NumSyms: 0
[SYMCHK] SymType: SymPDB
[SYMCHK] ModName: kernel32
[SYMCHK] ImageName: c:\Windows\System32\kernel32.dll
[SYMCHK] LoadedImage: c:\Windows\System32\kernel32.dll
[SYMCHK] PDB: "C:\Symbols\MSS\kernel32.pdb\9B30FD7CD6B44975BF34B43B6EF668212\kernel32.pdb"
[SYMCHK] CV: RSDS
[SYMCHK] CV DWORD: 0x53445352
[SYMCHK] CV Data:  kernel32.pdb
[SYMCHK] PDB Sig:  0
[SYMCHK] PDB7 Sig: {9B30FD7C-D6B4-4975-BF34-B43B6EF66821}
[SYMCHK] Age: 2
[SYMCHK] PDB Matched:  TRUE
[SYMCHK] DBG Matched:  TRUE
[SYMCHK] Line nubmers: FALSE
[SYMCHK] Global syms:  FALSE
[SYMCHK] Type Info:    FALSE
[SYMCHK] ------------------------------------
SymbolCheckVersion  0x00000002
Result              0x00030001
DbgFilename
DbgTimeDateStamp    0x4e21213b
DbgSizeOfImage      0x0011f000
DbgChecksum         0x0012386d
PdbFilename         C:\Symbols\MSS\kernel32.pdb\9B30FD7CD6B44975BF34B43B6EF668212\kernel32.pdb
PdbSignature        {9B30FD7C-D6B4-4975-BF34-B43B6EF66821}
PdbDbiAge           0x00000002
[SYMCHK] [ 0x00000000 - 0x00030001 ] Checked "c:\Windows\System32\kernel32.dll"
 
SYMCHK: FAILED files = 0
SYMCHK: PASSED + IGNORED files = 1

正如您在详细模式(/v开关)中看到的,您收到了很多关于symchk正在做什么的信息。我们甚至可以读取它使用的符号API(dbghelp消息)。/os开关通知symchk打印输出消息中符号文件的完整路径。运行此命令后,kernel32.pdb文件应该在符号存储中。如果您想索引整个System32目录,您需要使用/r开关,它通知symchk递归地遍历提供的目录并下载找到的所有文件的符号,eg. symchk /r /v c:\windows\system32\*.dll

让我们尝试加载notepad.exe进程的符号:

c:\temp\symtest>tasklist /FI "IMAGENAME eq notepad.exe"
 
Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
notepad.exe                   2264 Console                    1      6 036 K
 
c:\temp\symtest>symchk /ip 2264 /s SRV*.*http://msdl.microsoft.com/download/symbols
 
SYMCHK: FAILED files = 0
SYMCHK: PASSED + IGNORED files = 26

使用/ip开关,我们可以只提供进程ID,symchk将为进程中加载的所有模块下载符号文件。在这个例子中,我们还使用了/s开关,它为symchk提供它应该使用的符号路径(如果设置了,则覆盖symchk的_NT_SYMBOL_PATH)。在我们的例子中,我们将符号文件从Microsoft公共服务器下载到当前目录。运行此命令后,此目录的列表如下所示:

c:\temp\symtest>tree .
Folder PATH listing
Volume serial number is 00000002 C622:C13F
C:\TEMP\SYMTEST
├───advapi32.pdb
│   └───6AEFDCFF7F2A429B8532CD2BFDDF85D12
├───CLBCatQ.pdb
│   └───60B9D310C472440BA13F66BFF0FC39E32
├───comctl32.pdb
│   └───943BA638A2CD4D88A1C7E7418EAF796C1
├───comdlg32.pdb
│   └───631B57376F8549FDB2E7A8AB3D2D1FDF2
├───cryptbase.pdb
│   └───F03E074BB9E74C9F9BBFB0E42EF3A0AB2
├───dwmapi.pdb
│   └───8683ED0C3DBE4053883EC22FD9B4F2102
├───gdi32.pdb
│   └───FB9403C3B1304DA192C4D0E3485E25ED2
├───imm32.pdb
│   └───98F27BA5AEE541ECBEE00CD03AD50FEE2
├───kernel32.pdb
│   └───9B30FD7CD6B44975BF34B43B6EF668212
├───kernelbase.pdb
│   └───61044362232B410AA600843CEBFD11612
...

另一个有趣的开关是(/id),它使您能够调试转储文件。symchk.exe的另一个伟大功能是称为清单文件的东西。清单文件包含有关必须下载的所有符号的信息。然后,可以使用/om开关运行symchk,该开关将生成清单文件,而无需下载任何符号。然后,可以将清单文件复制到具有Internet连接的任何计算机上,并使用/im开关下载符号文件。下面的代码片段显示了一个使用示例:

c:\temp\symtest>symchk /om notepad-symbols.man /ip 2264
 
SYMCHK: FAILED files = 0
SYMCHK: PASSED + IGNORED files = 26
 
c:\temp\symtest>type notepad-symbols.man
notepad.pdb,36CFD5F9888C4483B522B9DB242D84782,1
notepad.exe,4a5bc9b335000,1
ntdll.pdb,6192BFDB9F04442995FFCB0BE95172E12,1
ntdll.dll,4ce7c8f91a9000,1
kernel32.pdb,9B30FD7CD6B44975BF34B43B6EF668212,1
kernel32.dll,4e21213b11f000,1
kernelbase.pdb,61044362232B410AA600843CEBFD11612,1
KernelBase.dll,4e21213c6c000,1
...
c:\temp\symtest>symchk /im notepad-symbols.man /s SRV*.*http://msdl.microsoft.com/download/symbols
 
SYMCHK: FAILED files = 0
SYMCHK: PASSED + IGNORED files = 52

dbh.exe

这个工具是DbgHelp.dll库的包装器,它揭示了几乎所有的功能。我们将只看一个使用示例,因此如果您想更深入地了解Windows帮助的调试工具。当以模块名作为参数运行dbh.exe时,它将自动下载符号文件。因此,只要调用dbh c:\ windows\system32\kernel32.dll info,您就可以下载符号文件(使用了_NT_SYMBOL_PATH环境变量),并打印有关该文件及其PE文件(kernel32.dll)的信息:

c:\temp>dbh c:\windows\system32\kernel32.dll info
 
    SizeOfStruct : 0x690
     BaseOfImage : 0x1677721664x
       ImageSize : 0x1000000
   TimeDateStamp : 0x4e21213b
        CheckSum : 0x12386d
         NumSyms : 0x0
         SymType : SymPdb
      ModuleName : kernel32
       ImageName : c:\windows\system32\kernel32.dll
 LoadedImageName : c:\windows\system32\kernel32.dll
   LoadedPdbName : C:\Symbols\MSS\kernel32.pdb\9B30FD7CD6B44975BF34B43B6EF668212\kernel32.pdb
           CVSig : 0x53445352
          CVData : kernel32.pdb
          PdbSig : 0x0
        PdbSig70 : 0x9b30fd7c, 0xd6b4, 0x4975, 0xbf, 0x34, 0xb4, 0x3b, 0x6e, 0xf6, 0x68, 0x21
          PdbAge : 0x2
    PdbUnmatched : false
    DbgUnmatched : false
     LineNumbers : false
   GlobalSymbols : false
        TypeInfo : false
   SourceIndexed : false
   PublicSymbols : true
     MachineType : X64

如果您想查看有关加载的PDB文件的详细信息,请使用-n开关。要更改默认符号路径(或覆盖符号路径设置),请使用-s:开关。

dumpbin.exe

您可能会惊讶于这个工具出现在这里,但是您是否注意到它的/PDBPATH[:VERBOSE]开关?在kernel32.dll库中发出dumpbin/pdbpath:verbose将导致从公共符号存储下载PDB文件:

c:\temp\symtest>dumpbin /pdbpath:verbose c:\windows\system32\kernel32.dll
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.
 
Dump of file c:\windows\system32\kernel32.dll
 
File Type: DLL
  PDB file 'c:\windows\system32\kernel32.pdb' checked.  (File not found)
  PDB file 'c:\temp\symtest\kernel32.pdb' checked.  (File not found)
  PDB file found at 'C:\Symbols\MSS\kernel32.pdb\9B30FD7CD6B44975BF34B43B6EF668212\kernel32.pdb'
 
  Summary
 
        2000 .data
        A000 .pdata
       6E000 .rdata
        8000 .reloc
        1000 .rsrc
       9B000 .text

从源服务器下载源代码

srctool.exe

这个工具非常有趣,因为它允许您检查PDB文件中索引的源文件,并最终提取它们。使用-r开关,您可以检查PDB文件中哪些源代码路径是硬编码的

c:\temp>srctool -r ConsoleApplication1.pdb
D:\lab\symbols-lab\symbols\ConsoleApplication1\Program.cs
D:\lab\symbols-lab\symbols\ConsoleApplication1\AdvertQuickView.cs

没有任何开关,SRCooT将检查PDB文件中的源服务器流(如果存在)和将执行以提取源文件的打印命令,例如:

c:\temp>srctool ConsoleApplication1.pdb
[D:\lab\symbols-lab\symbols\ConsoleApplication1\Program.cs] cmd: cmd /c svn.exe cat "svn://localhost/test2/Program.cs@1" --non-interactive --username admin --password admin > "
[D:\lab\symbols-lab\symbols\ConsoleApplication1\AdvertQuickView.cs] cmd: cmd /c svn.exe cat "svn://localhost/test2/AdvertQuickView.cs@1" --non-interactive --username admin --password admin > "
 
ConsoleApplication1.pdb: 2 source files are indexed

要运行命令并提取源文件,只需在上面的调用中添加-x开关。此外,还可以使用-d开关指定要将源文件提取到的目录(默认情况下是当前目录)。

pdbstr

如果希望更好地控制源服务器流,可以检查pdbstr命令。借助它,您可以读取和更新PDB文件中的源服务器信息。源服务器流实际上是一个带有预定义节的文本块(可以在这里找到更多信息)。您可以通过发布以下内容来转储其内容:

c:\temp>pdbstr -r -p:ConsoleApplication1.pdb -s:srcsrv > stream.txt

stream.txt文件应包含如下内容:

SRCSRV: ini ------------------------------------------------
VERSION=1
INDEXVERSION=2
VERCTRL=Subversion
DATETIME=Thu Nov 17 13:31:46 2011
SRCSRV: variables ------------------------------------------
SVNUSER=admin
SVNPASS=admin
SVN_EXTRACT_TARGET=%targ%\%fnbksl%(%var3%)\%var4%\%fnfile%(%var1%)
SVN_EXTRACT_CMD=cmd /c svn.exe cat "%var2%%var3%@%var4%" --non-interactive --username %svnuser% --password %svnpass% > "
%svn_extract_target%"
SRCSRVTRG=%SVN_extract_target%
SRCSRVCMD=%SVN_extract_cmd%
SRCSRV: source files ---------------------------------------
D:\lab\symbols-lab\symbols\ConsoleApplication1\Program.cs*svn://localhost/*test2/Program.cs*1
D:\lab\symbols-lab\symbols\ConsoleApplication1\AdvertQuickView.cs*svn://localhost/*test2/AdvertQuickView.cs*1
SRCSRV: end ------------------------------------------------
然后,可以应用所需的更改并将新的源流定义保存回PDB文件:
c:\temp>pdbstr -w -p:ConsoleApplication1.pdb -s:srcsrv -i:stream.txt

Pdbstr不会为您提取源代码文件,而是从源流内容中提取,您可以很容易地在哪里找到它们。这将结束我们的PDB工具列表-我希望您会发现它很有用。

PDB files out of the debugger的更多相关文章

  1. PDB Files: What Every Developer Must Know

    Reference:  http://www.wintellect.com/blogs/jrobbins/pdb-files-what-every-developer-must-know Most d ...

  2. PDB文件:每个开发人员都必须知道的 PDB Files

    PDB文件:每个开发人员都必须知道的   PDB Files: What Every Developer Must Knowhttp://www.wintellect.com/CS/blogs/jro ...

  3. Do PDB Files Affect Performance?

    After a detour into Historical Debugging, it's time to come back to return to answering questions ab ...

  4. Why is Visual Studio 2015 not able to find or open PDB files?

    first change parameters, Tools->Options->Debugging->Symbols->Microsoft Symbol Server, ye ...

  5. vs2010调试程序出现“Cannot find or open the PDB file”

    项目中源程序编写好以后, (一个简单的小程序) #include int main(void) { int age; int day; age = 24; printf("tom is %d ...

  6. PDB文件:每个开发人员都必须知道的

    PDB Files: What Every Developer Must Knowhttp://www.wintellect.com/CS/blogs/jrobbins/archive/2009/05 ...

  7. C# dmp debug, can't load pdb file

    1.  Project->Properties->Build->Advance, Debug Info : Full/pdb-only . set to [none] will no ...

  8. pdb文件 PDB文件:每个开发人员都必须知道的 .NET PDB文件到底是什么?

    pdb文件包含了编译后程序指向源代码的位置信息,用于调试的时候定位到源代码,主要是用来方便调试的. 在程序发布为release模式时,建议将 pdb文件删除, 同时,对外发布的时候,也把 pdb删除, ...

  9. pdb文件及引发的思考

    最初只想知道线上iis里需要不需要pdb文件,了解部分之后对于.net底层产生了浓厚的兴趣,看了一点点资料 资料来源: https://www.cnblogs.com/itech/archive/20 ...

随机推荐

  1. jar解压后重新打包

    因为一些原因修改了jar中的配置文件,但用WinRAR压缩成zip文件后该后缀名为jar,发现重新压缩的文件不可用,所有这些情况下我们必须用jar重新打包. 配置Java环境,让jar命令可用: ja ...

  2. 互联网基础知识------OSI七层网络模型梗概

    OSI七层模型 七层网络结构: 应用层.表示层.会话层.传输层.网络层.数据链路层.物理层 一般也作五层 应用层.传输层.网络层.数据链路层.物理层(实体层) 引申问题:TCP/IP协议与http协议 ...

  3. windows10下录屏

    windows10自带了录屏功能.运行win+G即可打开.如果出现错误,可以运行如下PS脚本. https://files.cnblogs.com/files/mqingqing123/reinsta ...

  4. ​ Markdown

    Cygwin ​ Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. ​ Markdown具有一系列衍生版本,用于扩展Markdown ...

  5. TCP/UDP协议(二)

    面试问题:Tcp/Udp协议是什么,各有什么异同点,各自的使用场景? Tcp协议(传输控制协议) tcp是面向连接的协议,在收发数据之前,必须与对方建立可靠的连接: 三次握手:简单形象通俗描述: 主机 ...

  6. saltstack手册(含官方pdf)

    官方手册 https://docs.saltstack.com/en/pdf/Salt-2019.2.1.pdf 快速入门 SALTSTACK是什么? Salt是一种和以往不同的基础设施管理方法,它是 ...

  7. 在Go1.11.1中使用go module管理依赖

    今天试验了一下go的版本管理Go moule,只是安装了下,由于目前还没有进行大的项目开发,暂时没有碰到坑. 使用了模块后,可以不用在GOPATH中再建立src目录了,直接在GOPATH中就行 另外, ...

  8. Fortify漏洞之Portability Flaw: File Separator 和 Poor Error Handling: Return Inside Finally

    继续对Fortify的漏洞进行总结,本篇主要针对 Portability Flaw: File Separator 和  Poor Error Handling: Return Inside Fina ...

  9. oracle OCCI编程

    1. 创建OCCI环境变量 Environment *env = Environment::createEnvironment(); Environment对象的建立必须放在第一位,而且也必须是最后一 ...

  10. elasticsearch 安装 可视化工具

    一.windows下安装Elasticsearch首先计算机需要JAVA环境(已有次此环境跳过)1.java环境安装网址:http://www.oracle.com/technetwork/java/ ...