惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
A
About on SuperTechFans
小众软件
小众软件
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
博客园 - 聂微东
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
量子位
博客园 - 三生石上(FineUI控件)
Recent Announcements
Recent Announcements
The GitHub Blog
The GitHub Blog
B
Blog RSS Feed
T
The Blog of Author Tim Ferriss
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
Last Week in AI
Last Week in AI
宝玉的分享
宝玉的分享
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

博客园 - Kevin-moon

在IE中本地浏览与服务器浏览同一Html后,出现了奇异的结果 如何避免JQuery Dialog的内存泄露 JQuery另类视角-动态执行脚本的BUG JQuery另类视角-动态扩展对象 - Kevin-moon - 博客园 如何重构代码-简单、灵活的实现对象复制 如何重构代码-重构计划 如何重构代码-思路和方法 谈谈多线程的思维方式 简单的数据移动算法(C#) [ASP.NET MVC]-理解Routing 笑死人的十项大奖 深入APM,实现自己的APM 深入线程,实现自定义的SynchronizationContext 重温ASP.NET的配置信息(简单、常用) 奇妙的SynchronizationContext 线程之间的通讯---SynchronizationContext "对象"到"山寨对象"的完整转换 我真的就只能在远方看你吗?!!! "测试驱动开发(TDD)" 动态进行"自定义公式"计算
[Windbg基础]-了解Symbols
Kevin-moon · 2009-02-19 · via 博客园 - Kevin-moon

     对于NET下的开发人员,可能对Symbol不了解的人还不少,因为MS给了我们太多方便的工具,让我们只需要去关注代码,对于其他的东西基本上不需要去关注,所以就养成了一个习惯(过多的依赖MS,依赖VS)。这里只是抛开VS,讲一下调试要用到的东西-Symbol。认识Symbol


     用于程序调试的数据,它包含了调试中需要用到的各种数据,例如:全局变量、本地变量、函数名、函数类型、源代码行、程序入口地址.....,这些所有的东西都叫做Symbol。
     在windows系统中,windows2000将这些信息保存在.pdb和.dbg这些的文件中,而windowsXP和以后的版本都将这些信息保存在.pdb文件中。
     Symbol一般分为两种:Public和Private,其实我们应该很容易理解他们,就是允许公开的数据和私有的数据。我们在发布产品的时候,可以同时发布Symbol数据,对于Symbol数据发布的粒度,我们也是可以去查看和控制的(下面会介绍PDBCopy和Symchk)。
     在NET中,我们也可以看到VS生成的Symbols,在VS生成的DLL目录下面,我们除了DLL外,还可以看到另外的一类文件.pdb(如下图),VS能提供给我们这么大的调试能力和它是分不开的。

     同时,我们也可以在VS中去设定是否输出Symbols或输出Public或Private的Symbols。如下图,在"Debug Info"中设置

通过Windbg查看Symbols


在Windbg查看Symbols前,我们可以设置一些Symbol Option:
     例如:
          SYMOPT_NO_PUBLICS屏蔽Public的Symbol [.symbol +0x8000]
          SYMOPT_AUTO_PUBLICS:Public和Private的Symbol  [.symbol +0x4000]
          SYMOPT_PUBLICS_ONLY:屏蔽Private的Symbol  [.symbol +0x10000]
          SYMOPT_DEBUG:当Windbg加载Symbol文件的时候,显示Symbol的路径,默认情况下是不显示的。
          打开命令[!sym noisy]

          关闭命令[!sym quiet]

     通过上面两个截图应该很容易看到区别了。

下面让我们用具体的命令来查看Symbol数据:

1、lm(命令):显示出程序运行加载的模块信息
2、!lmi [模块名]:显示模块的详细信息,并且还有命令(!db [模块名]),它显示的信息要比!lmi多些

3、X modulename!symbols(命令):显示出所有的Symbols数据或者是指定模块的Symbols数据


设置Windbg中的Sympath


    在Windbg中,运行上面的命令去查看Symbols数据,那么Windbg在什么地方去搜索这些数据呢?有些编译器会将这些pdb文件和dll文件或exe文件放在同一个目录下面,例如Visual Studio,所以通过VS调试的时候,VS会在dll的目录中搜索,不同用Windgb来调试程序的话,就需要我们来自己设置下搜索路径。
    1、设置Windbg的环境变量:_NT_SYMBOL_PATH_NT_ALT_SYMBOL_PATH
       2、在命令行启动Windbg的时候,通过-y(command line)来设置,例如:windbg -y path
    3、.sympath和.symfix
     .sympath[+] [Path [; ...]]指定一个新的路径

       .sympath:查看设置的路径

     .Symfix[+] [path]:设置指向Microsoft symbol storeSymbols文件路径
          
等于sympatp[+] srv*DownstreamStore*http://msdl.microsoft.com/download/symbols(MS中所有Symbol文件的存放地址)
         4、通过Windbg的图形界面”File | Symbol file path”也可以设置

重新加载Symbol以及Symbol的状态


    Symbol的状态,我们可以先看下上面的图(lm命令),在每个模块名称后面都有deferred、export。下面简单说下它的几个状态:
    deferred:模块已经加载,但是模块的symbol文件并没有加载,这是属于延迟加载的,当需要的时候才加载,或者我们通过ld [模块名称](命令)来加载指定模块的symbol。
    export:没有对应的symbol文件,目前只能把dll或exe文件当做symbol来加载
    private:表示加载的是私有的Symbol
    public:表示加载的是共有的Symbol

    
    .reload(命令):重新加载Symbol
    当有些时候我们已经加载了symbol,但是该文件不存在,这时候我们把symbol文件从其他地方拷贝过来后,我们可以用该命令使windbg重新加载。

Symchk和PDBCopy


Symchk:用来检测Symbol文件和执行文件是否匹配
     symchk [/r] FileNames /s SymbolPath
看下下面的执行结果:

PDBCopy:用来分离Symbol,它可以将一个完整的Symbol文件分离成Public和Private的Symbol文件
1、把Private的Symbol删除,创建只有Public的Symbol
     pdbcopy mysymbols.pdb publicsymbols.pdb -p 
2、不仅删除Private的symbol,而且还可以删除Public中的一些指定数据
     pdbcopy mysymbols.pdb publicsymbols.pdb -p -f:@c:\delete.txt
     delete.txt就是指定需要删除的数据,例如希望去删除_myGlobal1和_myGlobal2这两个数据,那么你在该文件中只需要输入两行:
     _myGlobal1
     _myGlobal2

     由于Windbg在国内的资料很少,所以自己边学边写点东西,虽然这些都是些简单的基础知识,但是希望和大家一起慢慢玩通它,呵呵!