我想我不需要强调在调试时拥有有效的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. HTML连载30-CSS显示模式&模式转换

    一.CSS显示模式​ 1.在HTML中HTML将所有的标签分为两类,分别是容器类和文本级.在CSS中CSS也将所有的标签分为两类,分别是块级元素和行内元素 2.什么是块级元素呢?什么是行内元素​? ( ...

  2. 【转】python实现Telnet操作

    # -*- coding: utf-8 -*- import logging import telnetlib import time import sys import os host_ip = ' ...

  3. 猫狗识别——PyTorch

    猫狗识别 数据集下载: 网盘链接:https://pan.baidu.com/s/1SlNAPf3NbgPyf93XluM7Fg 提取密码:hpn4 1. 要导入的包 import os import ...

  4. jquery validate 动态生成的多个同名input的验证

    我的应用场景是,添加和修改入库单的明细,明细是以表格的形式呈现,可以动态添加商品,用jquery.validate插件做数据验证. 由于jquery.validate插件验证同名的input时只验证第 ...

  5. python 练习题:计算的BMI指数,并根据BMI指数条件选择

    小明身高1.75,体重80.5kg.请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数:低于18.5:过轻18.5-25:正常25-28:过重28-32:肥胖高于32:严 ...

  6. Linux纯小白操作(以安装JDK为例)

    [本文只针对纯小白,有基础的请略过] 最近公司给分配工作使用的虚拟机都是Linux系统的,以前完全没接触过,今天按照网上一些教程操作,好多地方感觉对小白不够友好(有些问题非常小白那些教程没有写出来.我 ...

  7. Centos中编辑php扩展库

    今天需要在Centos中编译Exif库以便获取图片的exif信息,可在Linux中从来没有编译过扩展库呀,只好查资料了.发现是用phpize这个东东来编译扩展. 首先执行了下 php -i | gre ...

  8. Python【day 9】函数入门2

    本节内容:1. 什么是函数2. 函数定义, 函数名, 函数体以及函数的调⽤3. 函数的返回值4. 函数的参数 一.什么是函数 我们可以先去定义一个事情或者功能(接口.服务.函数.功能). 等到需要的时 ...

  9. [VSTO] 区分MAILITEM的ATTACHMENT是真正的附件还是内嵌资源

    在遍历MailItem的Attachments集合的时候发现,不管是真正的附件还是内嵌资源,比如邮件内容中内嵌的图片(Embedded Image),都是Attachments集合的元素,通过查看at ...

  10. Object.freeze

    Object.freeze() 方法可以冻结一个对象.一个被冻结的对象再也不能被修改:冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性.可配置性.可写性, ...