【c#】使用WinDbg查看方法表

背景

        《C#从现象到本质》第四章提到了方法表,感觉是语言里很精华的部分,比光学语法规则有趣多了。书里直奔主题(其实是人菜瘾大还爱跳读),被绊了几天,好气哇(书的第二章有提到如何使用WinDbg)。

安装WinDbg

方法一:通过Windows Software Development Kit

旧是旧了点,也能用。方法二里的WinDbg Preview是新版,这是旧版。

 参考 Download Debugging Tools for Windows - WinDbg - Windows drivers | Microsoft Docs

 

方法二:通过Micorsoft Store下载

打开Microsoft Store,搜索windbg,

 点击安装,用了全局代理才安装到,这里大家就八仙过海的下一句。

实操:查看方法表

测试代码

创建项目-c#控制台应用(.Net Framework),名为ConsoleApp2

项目保存路径为:E:\c#\ConsoleApp2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    class A
    {
        public virtual void Foo()
        {
            Console.WriteLine("A.Foo");
        }
    }
    class B:A
    {
        public virtual void Foo()
        {
            Console.WriteLine("B.Foo");
        }
    }
    class C : B
    {
        public override void Foo()
        {
            Console.WriteLine("C.Foo");
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            a.Foo();

            A b = new B();
            b.Foo();

            A c = new C();
            c.Foo();

            Console.WriteLine(typeof(A).FullName); 
        }
    }
}

方法一:使用WinDbg查看

参考:Windbg 32位版本和64位版本的选择_ithzhang的博客-CSDN博客_windbg64

打开WinDbg-File-Open Executable

选中需要调试的程序,打开 

 输入lm,回车,看看加载了什么模块

lm

使用sympath命令,设置pdb所在路径,回车

.sympath E:\c#\ConsoleApp2\bin\Debug

 调用g命令运行程序,回车

g

使用load命令加载sos.dll,(注意sos.dll的路径和上面一步画线的clr.dll路径是一致的,C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll)

.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll

如果没加载 sos.dll,使用name2ee命令,会输出No export name2ee found

查看类A方法表

使用name2ee获取类A方法表地址,输入以下命令,回车

!name2ee ConsoleApp2 ConsoleApp2.A

使用dumpmt命令, 查看方法表。输入以下命令,回车

!dumpmt -md 00704dd0

方法二:使用WinDbg Preview 查看

打开winDbg Preview -文件

 选择Launch executable

 选择需要调试的程序

 

输入lm,查看进程中加载的代码模块列表

 此时并没有加载没有clr模块

 按Go按钮,或者使用g命令,回车,发现加载了clr模块

查看类A方法表

参考SOS.dll (SOS Debugging Extension) - .NET Framework | Microsoft Docs

使用name2ee命令,获取类的EEClass地址。

输入以下命令,回车。

!name2ee ConsoleApp2 ConsoleApp2.A

 使用!dumpmt命令,查看方法表

输入以下命令,回车

!dumpmt -md 00ff4dd0

常用命令

 参考 WinDbg 入门(用户模式) - Windows drivers | Microsoft Docs​​​​​​c

命令描述参考
.load

加载新的扩展 DLL 到调试器中

格式:.load DLLName

例子:.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll

.load、.loadby(加载扩展 DLL) - Windows drivers | Microsoft Docs
.loadby

加载新的扩展 DLL 到调试器中

格式:.loadby DLLName ModuleName

例子:.loadby sos clr

.load、.loadby(加载扩展 DLL) - Windows drivers | Microsoft Docs
.sympath

指定 WinDbg 查找符号 (PDB) 文件的位置;

格式:.sympath[+] [Path [; ...]]

例子:.sympath E:\c#\ConsoleApp2\bin\Debug

.sympath(设置符号路径) - Windows drivers | Microsoft Docs
.reload通知 WinDbg 进行符号文件的初始查找和加载.reload(重新加载模块) - Windows drivers | Microsoft Docs
bu

设置断点;

格式:bu 程序名!函数名

例子:bu notepad!wWinMain

bp、bu、bm(设置断点) - Windows drivers | Microsoft Docs
lm查看进程中加载的代码模块列表lm(列出已加载的模块) - Windows drivers | Microsoft Docs
g运行g(转到) - Windows drivers | Microsoft Docs
k查看堆栈跟踪k、kb、kc、kd、kp、kP、kv(显示堆栈回溯) - Windows drivers | Microsoft Docs
q退出进程q、qq(退出) - Windows drivers | Microsoft Docs
qd退出调试并从进程分离qd(退出和分离) - Windows drivers | Microsoft Docs

  

参考SOS.dll (SOS Debugging Extension) - .NET Framework | Microsoft Docs

语法格式:![command] [options] 

命令描述格式例子
Name2EE 

显示指定模块中指定类型或方法的MethodTable结构和结构。

指定的模块必须在进程中加载。

要获得正确的类型名称,请使用Ildasm.exe (IL Disassembler)浏览模块。

Name2EE <模块名称> <类型或方法名称> -或!name2ee ConsoleApp2 ConsoleApp2.A
DumpMT

显示有关指定地址的方法表的信息。

指定-MD选项会显示使用对象定义的所有方法的列表。

DumpMT [ -MD ] <方法表地址>!dumpmt -md 00704dd0

 其他

c#类的方法表的建立和方法的调用 - seeseaatsea - 博客园对于方法的调用,很是令我头疼,什么静态方法,实例方法,实例虚方法,这里查了很多资料,总结如下: 这里声明,我也是菜鸟,这里只讨论方法的调用相关的技术,属于个人理解,如有错误,请指正 思路: 1 clrhttps://www.cnblogs.com/OneRipple/p/7093876.html

上面链接的内容对我理解方法表帮助蛮大的,在这里马一下。

 方法在方法表中的排列顺序:
继承的实例虚方法、实例虚方法、构造函数、静态方法、实例方法

为什么把“继承的实例虚方法”和“实例虚方法”放在方法表的开头位置?

结论:方法表中虚方法的排序,可以在类的层次结构中保持虚方法的层次结构,这是实现多态的基础,也就是为什么说继承是实现多态的基础了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值