来个样例

我的符号目录设置是:

用我们在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. spring bean的三种管理方式·

    1.无参构造函数 1.xml文件配置内容 <!--无参构造函数--> <bean id="bean1" class="com.imooc.ioc.dem ...

  2. Eureka概述

    1:Eureka是什么 Eureka是Spring Cloud Netflix的一个子模块,也是核心模块之一.Eureka是一个基于REST的服务,用于定位服务,以及·实现云端中间层服务发现和故障转移 ...

  3. 我的周记9——"所以快乐才是真谛"

    七月又名:巧月.瓜月.霜月.相月.凉月.初商.肇秋.初秋.首秋.早秋.新秋.上秋.孟秋.夷则.申月等. 你好七月 ,想起大学的时候我在校园的点歌台点了一首歌,歌名是July . 七月一号,新的一月,新 ...

  4. OCC与MVCC 的区别

    一.前言 在数据库中,并发控制是指在多个用户/进程/线程同时对数据库进行操作时,如何保证事务的一致性和隔离性的,同时最大程度地并发. 当多个用户/进程/线程同时对数据库进行操作时,会出现3种冲突情形: ...

  5. 【题解】C2Crni - Crni [COCI2010] [SP7884]

    [题解]C2Crni - Crni [COCI2010] [SP7884] 传送门:\(\text{C2Crni - Crni}\) \(\text{[COCI2010]}\) \(\text{[SP ...

  6. nginx报错111: Connection refused

    最近遇到了nginx疯狂抛错,access.log一天一共5W多条,但error.log中有大概9K多条,基本都是111: Connection refused,这到底是为什么呢? 从日志看起 我们还 ...

  7. 2019-11-29-win10-UWP-Controls-by-function

    原文:2019-11-29-win10-UWP-Controls-by-function title author date CreateTime categories win10 UWP Contr ...

  8. winform加快窗体加载速度

    //加快控件加载的速度 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams ...

  9. C# 简单日志帮助类LogHelper

    调用: LogHelper.Debug(""); LogHelper.Info(""); LogHelper.Error(""); 项目添加 ...

  10. babel plugin和presets是什么,怎么用?

    https://www.fullstackreact.com/articles/what-are-babel-plugins-and-presets/ 当开发react或者vuejs app时,开发者 ...