来个样例

我的符号目录设置是:

用我们在windows下调试必须用到的ntdll.dll模块来讲下windbg加载符号文件的过程。windbg加载符号文件时,会首先根据配置的符号目录信息,在本地符号目录中查找对应的符号文件。一个典型的搜索过程如下:
F:\Debug_Symbol\Symbols32\
F:\Debug_Symbol\Symbols32\pingme.txt
F:\Debug_Symbol\Symbols32\flat.txt
F:\Debug_Symbol\Symbols32\index2.txt
F:\Debug_Symbol\Symbols32\ntdll.pdb\2505F15902821D2C6931BBFF1B941EBF1\ntdll.pdb
F:\Debug_Symbol\Symbols32\ntdll.pdb\2505F15902821D2C6931BBFF1B941EBF1\ntdll.pd_
F:\Debug_Symbol\Symbols32\ntdll.pdb\2505F15902821D2C6931BBFF1B941EBF1\file.ptr

首先解释一下路径中的那一串字母和数字混合的东西是什么玩意儿,这个字符串是编译器根据编译时的时间、版本、程序类型等信息生成的一个类似GUID一样的东西(VC6编译的符号文件其内部编号是编译时间的绝对秒,就是
time
函数返回的32位从1970年1月1日0点开始的秒数,后面加上程序的特征,例如目标机器的类型、程序类型等;VC7.0、7.1、8.0、9.0
编译的符号文件编号是一个
GUID,这可能是为了避免多线程同时编译相同特征的程序引发内部编号冲突),存储在PE文件的DebugDirecotry数据目录指向的数据中,暂且称之为pdb的索引串,对于每个编译出来的文件而言它是唯一的。同名文件的不同版本,它的这个索引串也不同。

过程详解

下面我来逐一解释下上面看到的这个搜索过程:

  1. 调试器先检查符号目录是否存在
  2. 检查符号目录下是否存在flat.txt、pingme.txt或index2.txt。这三个文件的存在与否,决定了搜索过程中的一些细节。
    如果存在pingme.txt,说明该目录下存在自动下载的符号文件。那么windbg将按照自动下载时的存放路径来检查符号文件是否存在。若没有pingme.txt,将不会采用这种路径来搜索。具体搜索方式参考第3条。
    如果存在flat.txt(即使同时也存在pingme.txt),将忽略上面这种采用pdb索引串的快捷搜索方式,只以文件名和文件类型等信息进行搜索。
    如果存在index2.txt,将按照文件名称分组进行搜索。分组方式是:使用符号文件名称的前两个字母最为一级目录,符号文件的名称作为二级目录,符号文件的编号作为三级目录,如此可对大量的文件进行分级索引,避免Symbols 目录下的子目录过多。比如以下路径:
    F:\Debug_Symbol\Symbols32\ke\kernel32.pdb\
    F:\Debug_Symbol\Symbols32\nt\ntdll.pdb\
    F:\Debug_Symbol\Symbols32\nt\ntkrnlpa.pdb\
  3. 按pdb索引搜索(要求pingme.txt存在)
    对于windbg自动下载的符号文件,会以"符号目录+符号文件名+pdb索引串+符号文件名的方式"为路径存储符号文件,这样,在下次需要查找该符号时,可以直接从PE文件中取得pdb索引串,然后构造出这样一个路径来快速加载符号文件。这就是搜索路径"F:\Debug_Symbol\Symbols32\ntdll.pdb\2505F15902821D2C6931BBFF1B941EBF1\ntdll.pdb"的由来。当存在pingme.txt时,将优先采用这种方式搜索。当然,自动下载符号的目录一般会自动创建一个pingme.txt的。
  4. 检查是否存在压缩的符号文件
    windbg从符号服务器下载的符号文件,有些可能是压缩形式(文件名以_结束,需要用expand.exe解压缩),所以windbg会检查ntdll.pd_的存在,若存在就会将其解压缩。file.ptr可能也是某种方式的临时文件,暂时我无法完全解释它。
  5. 以符号文件名作为文件夹名进行搜索
    如果以上都没有找到,那么就检查符号目录下ntdll.pdb这个文件夹是否存在,注意这里是文件夹。如果该文件夹存在,就会继续查找F:\Debug_Symbol\Symbols32\ntdll.pdb\ntdll.pdb。若文件夹不存在,就会直接在符号目录下查找符号文件ntdll.pdb(注意是文件)。
  6. 以目标文件的类型作为分类搜索
    如果仍然没有找到,那么将根据PE文件的类型(dll,exe,sys,ocx等)作为子目录进行查找(安装的符号文件一般是以这种路径形式存放的)。
  7. 以目标文件Debug信息中指定的符号路径进行搜索
    对于我们自己编译的驱动,通常是包含了pdb文件的全路径的,随便用一个编辑器打开一个sys文件都可以看到文件中出现的pdb路径信息。
  8. 搜索windbg所在路径
  9. 到符号服务器查找符号
    如果以上都没有找到的话,也就是说本地符号库中无法找到匹配的符号文件,如果符号设置中允许自动到符号服务器下载符号(比如出现了"SRV*F:\Debug_Symbol\Symbols32*http://msdl.microsoft.com/download/symbols"这样的配置),那么windbg就会根据PE文件的pdb索引串到符号服务器上查找是否有与该pdb索引串匹配的符号文件,若有,就将其下载到本地,若没有,那就是真的没有了,windbg将返回"ERROR: Symbol file could not be found."

windbg是如何搜索符号文件的?的更多相关文章

  1. 【旧文章搬运】关于windbg搜索符号文件的一点说明

    原文发表于百度空间,2010-09-07========================================================================== 本来只是打 ...

  2. Windbg调试命令详解

    作者:张佩][原文:http://www.yiiyee.cn/Blog] 1. 概述 用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是:cdb.exe.ntsd. ...

  3. Windbg符号与源码 《第二篇》

    符号文件是一种辅助数据,它包含了对应用程序代码的一些标注信息,这些信息在调试过程中非常有用.如果没有辅助数据,那么能获得的信息就只有应用程序的二进制文件.二进制文件很难调试,因为无法看到代码中的函数名 ...

  4. Windbg调试命令详解(2)

    转载注明>>  [作者:张佩][原文:http://blog.csdn.net/blog_index] 2. 符号与源码 符号与源码是调试过程中的重要因素,它们使得枯燥生硬的调试内容更容易 ...

  5. Windbg 双机代码同步调试设置

    Windbg的设置 Windbg的设置 Windbg本身可以直接从微软的网站上下载下载地址:http://www.microsoft.com/whdc/devtools/debugging/defau ...

  6. WinDBG快速定位异常位置

    在WinDBG中通过搜索内存中保存的CONTEXT结构来定位发生的异常信息,再通过WinDBG命令.cxr显示对应的调用堆栈信息.   .foreach ( place { s-[1]d 0 L?FF ...

  7. windbg命令分类与概述

    WinDBG的大多数功能是以命令方式工作的, 本系列将介绍WinDBG的三类命令, 标准命令, 元命令和扩展命令. =============== 标准命令 =============== 标准命令用 ...

  8. Windbg内核调试之三: 调试驱动

    这次我们通过一个实际调试驱动的例子,来逐步体会Windbg在内核调试中的作用.由于条件所限,大多数情况下,很多人都是用VMware+Windbg调试内核(VMware的确是个好东西).但这样的调试需要 ...

  9. chromium浏览器开发系列第五篇:Debugging with WinDBG

    Windbg 相信windows开发的人都知道,有些人用的溜儿溜儿的,有个crash,直接拿这个工具一分析,就定位出来了.非常好用.以前有个同事,做sdk开发 的,会各种命令.来北京后,还去过微软面试 ...

随机推荐

  1. 【转】Python入门:Anaconda和Pycharm的安装和配置

    子曰:“工欲善其事,必先利其器.”学习Python就需要有编译Python程序的软件,一般情况下,我们选择在Python官网下载对应版本的Python然后用记事本编写,再在终端进行编译运行即可,但是对 ...

  2. kvm虚拟机日常管理与配置

    1.  查看KVM虚拟机配置文件及运行状态 (1) KVM虚拟机默认配置文件位置: /etc/libvirt/qemu/ autostart目录是配置kvm虚拟机开机自启动目录.    (2) vir ...

  3. WPF 精修篇 静态资源

    原文:WPF 精修篇 静态资源 在WPF中 如果设置好了一个控件样式或者矩形样式 如果Copy出一个新的 那么样式也会双份 比如 下面的矩形 我定义好了一个 Copy 以后 就出现一个新的 但是改变样 ...

  4. 转 Sqlserver_left join 、right join、 inner join 用法

    https://www.cnblogs.com/ingstyle/p/4368064.html   left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right joi ...

  5. ObjC: Foundation Kit

    转自:http://marshal.easymorse.com/tech/objc-foundation-kit Foundation Kit是什么? 你可以把它看作Java JDK中的java.la ...

  6. 【转载】Gradle学习 第一章:引言

    转载地址:http://ask.android-studio.org/?/article/7 We would like to introduce Gradle to you, a build sys ...

  7. Android 一个TextView中设置多种不同大小的字体,设置超链接

    以前项目中要是遇到这样的UI设计,都是傻不拉唧的分为三个TextView来实现,今天在微信中无意中看了一篇公众号文章,发现原来只要一个TextView就可以搞定啦,人生最悲哀的事情莫过于工作了这么久啦 ...

  8. JavaWeb 过滤敏感词汇

    提交的表单数据,常常要检查有没有敏感词汇,如果有,需要给出提示,或者替换为*. 检查.替换敏感词汇有3种常用的方式 (1)在Servlet中操作. (2)在Filter中先检查.如果要替换敏感词汇,r ...

  9. Java中的equals与==

    package demo; public class Test { public static void main(String[] args) { String str1 = new String( ...

  10. win10自带截屏操作

    1.win+shift+S,自由截屏 2.win+W,截屏后编辑 3.alt+PrtSc,截取当前活动界面,鼠标在微信就是微信,在浏览器就是浏览器.在桌面就是所有界面. 4.PrtScn,截取所有屏幕 ...