zoukankan      html  css  js  c++  java
  • 在托管代码中设置断点(Windbg)

    CLR中执行的托管代码分为Jitted 代码和ngened代码。区Jitted代码是动态编译生成的而ngened代码是预编译生成的。本文将讲述使用Windbg在这两种不同的代码中设置断点的方法。本文将使用如下的例子进行说明:

     

    using System;

     

    public class Test {

     

        public static void Main() {

     

            Console.WriteLine("Test");

     

        }

     

    }

     

    编译上面的代码生成test.exe

     

     

     

    Jitted代码(Test.Main

     

     

     

    同一个托管方法的Jitted代码地址并不固定,所以在托管方法中设置断点较麻烦。托管方法对应的CLR数据结构是MethodDescMethodDesc中有一个变量DWORD_PTR m_CodeOrIL储存Jitted代码地址(编译后)或IL相对地址(编译后)。JIT在编译一个方法后会改变该变量的值。下面是设置断点的步骤:

     

     

     

    1       mscorjitJIT Engine)设置模块加载断点:“sxe ld:mscorjit.dll”。然后输入输入g命令。

     

    2       载入sos“.loadby sos mscorwks”

     

    3       查找Test.MainMethodDesc“!name2ee test.exe Test.Main”.

     

    MethodDesc: 975070

     

    Name: [DEFAULT] Void test.Main()

     

    4        在该MethodDescm_CodeOrIL域(MethodDesc的地址加4)上设置一个内存断点:

     

           ba w4 975070+0x04 "bp poi(975070+0x04);g"

     

    上面的断点的意思是在m_CodeOrIL被改变后在m_CodeOrIL中存储的地址上设置代码断点并继续执行。

     

    5        Debugger会停在Test.Main的入口处。输入!clrstack

     

    ESP       EIP    

     

    0012f6ac 06cb0058 [DEFAULT] Void test.Main()

     

     at [+0x0] [+0x0] g:"t.cs:7

     

    0012f9b0 791da717 [FRAME: GCFrame]

     

    0012fa94 791da717 [FRAME: GCFrame]

     

     

     

    Ngened代码

     

     

     

    如果执行的方法是预编译过(关于细节请参阅关于ngen的文章),它的地址将是固定的,所以只需要找出该地址一次。假设我们想调试Console.WriteLine,可以使用如下的步骤来设置断点:

     

    1      windbg test.exe

     

    2       输入“g”命令。Debugger会停在进程结束(process termination)断点处。

     

    3       载入sos“.loadby sos mscorwks”

     

    4       输入“!name2ee mscorlib.dll System.Console.WriteLine”Debugger会显示Console.WriteLine的所有Overloads。我们感兴趣的是:

     

    MethodDesc: 79bb96b8

     

    Name: [DEFAULT] Void System.Console.WriteLine(String)

     

    5       显示该方法的信息:

     

       !DumpMD 79bb96b8

     

        Method Name : [DEFAULT] Void System.Console.WriteLine(String)

     

        MethodTable 79bb92a0

     

        Module: 79b66000

     

        mdToken: 0600051a (c:"windows.0"microsoft.net"framework"v1.1.4322"mscorlib.dll)

     

        Flags : 8010

     

        Method VA : 799f91b8

     

    6      windbg test.exe

     

    7       mscorlibConsole.WriteLine所在模块)设置模块加载断点。“sxe ld:mscorlib.dll”.

     

    8       输入“g”命令两次。注意对于预编译的AssemblyCLR会先载入IL Assembly,然后在载入Ngened Image。这是为什么要“g”两次的原因。在Debugger中应当有如下的输出:

     

    ModLoad: 79780000 79980000   c:"windows.0"microsoft.net"framework"v1.1.4322"mscorlib.dll

     

    ModLoad: 79980000 79ca6000  

     

    c:"windows"assembly"nativeimages1_v1.1.4322"mscorlib"1.0.5000.0__b77a5c561934e089_a6cf3080"mscorlib.dll

     

    9       Ngened Image被加载后,可以直接在以前得到的地址上设置断点:“bp 799f91b8”

     

    “g”Debugger会停在Console.WriteLine的入口处。输入!clrstack

     

           Thread 0

     

    ESP       EIP    

     

    0012f6a4 799f91b8 [DEFAULT] Void System.Console.WriteLine(String)

     

    0012f6a8 06cb0067 [DEFAULT] Void Test.Main()

     

     at [+0xf] [+0xa] g:"t.cs:8

     

    0012f9b0 791da717 [FRAME: GCFrame]

     

    0012fa94 791da717 [FRAME: GCFrame]

     

     

     

     

     

    WindbgCLR Whidbey的支持更强。K会直接显示托管方法名。Bp可以直接支持托管方法:bp mscorlib_dll!System.ConsoleWriteLine

     

     

     

     

     

     

     

     2004428 9:24 - (阅读:2567;评论:6)

     

    反馈

    # 回复: 在托管代码中设置断点(WINDBG) 2004-4-28 12:30 Flier Lu

    太好了,呵呵,前两天还在琢磨着怎么写个插件实现 bp 命令直接给函数下断点呢 :D

     

    # 回复: 在托管代码中设置断点(WINDBG) 2004-5-1 12:45 chiv_BJ

    问一下,你有Shared source CLI Essential, by Stutz David,

    这本书 电子版吗?

     

    # re: 在托管代码中设置断点(WINDBG) 2004-9-13 15:19 twinsant

    Is mscorlib_dll!System.Console.WriteLine managed code?

     

    I did think it is native code.

     

    # re: 在托管代码中设置断点(WINDBG) 2004-9-14 11:51 Peng Gang

    It is prejitted code for mscorlib.dll (native). Note the format was changed, so you might see something like:

    mscorlib_ni!System.Console.WriteLine

     

    # re: 在托管代码中设置断点(WINDBG) 2005-4-25 2:00 尖锐湿疣

    Thank YOu!

     

    # 使用WindbgSoS扩展调试分析.NET程序 2006-12-23 0:30 自由、创新、研究、探索……

    在博客堂的不是我舍不得-HighCPUinGC(都是 =惹的祸,为啥不用StringBuilder呢?)、不是我舍不得-.NET里面的OutOfMemory看到很多人在问如何分析...

     

     

  • 相关阅读:
    电脑开不开机 且开且珍惜
    IA32系统级架构总览(二)
    IA32系统级架构总览(一) 实模式和保护模式
    Django 步骤
    【Python】使用Supervisor来管理Python的进程
    python json操作
    term2 配置
    被执行人查询
    Linux下redis的安装
    FTP命令
  • 原文地址:https://www.cnblogs.com/holly/p/1433449.html
Copyright © 2011-2022 走看看