ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

托管调试中的对象标识

2020-12-01 10:35:46  阅读:177  来源: 互联网

标签:对象 句柄 代码 托管 标识 Foo 调试 调试器


问题是:
也许您在调试时浏览了全局、局部或参数,然后通过一些丑陋的对象引用(如哈希表)来查找对象引用。你希望能在那个物体上获得一些身份,这样你就可以很容易地再次找到它。以后重新查找它可能不实际,特别是如果程序状态自上次以来已更改,以致原始步骤不再生成相同的对象。如果一个数据结构被更改,一个变量被重新分配,或者一个函数返回并使其所有的局部变量无效,那么很容易发生这种情况。事实上,在这种情况下,回溯原始步骤甚至可能产生完全不同的对象。
解决方案是提供独立于其发现方式的“对象标识”。然后,不管程序状态发生了什么变化,都可以在以后根据其标识检索对象

本机代码中的对象标识

在本机代码中,通过“this”指针,每个对象都有一个内部标识。由于本机代码中没有GC移动对象,所以对象的地址是常量,只要对象还活着,就可以用来引用对象。


例如,如果我知道地址0x0012eeff有一个Foo类型的对象,我可以通过检查“((Foo*)0x0012eeff)”随时查看它。地址提供了一个非常方便的固有对象标识。

托管代码中的问题

由于托管代码有一个GC来移动对象,所以转换地址不一定是安全的。地址可以是0x0012eeff,然后GC可以将其移动到0x44556677。托管代码的任何对象标识解决方案都需要与垃圾回收器协作。

托管代码中的对象标识示例
class Program

{

    static void Main()

    {

        string s = "A test";

        Foo();

    }

    static void Foo()

    {

        object x = null;

        System.Console.WriteLine("In Foo:" + x); // <-- set Breakpoint here

    }

}

在Visual Studio 中试用:
1) 运行到断点。
2) 在断点处,将当前堆栈帧切换到Main()。
3) 打开“Local”窗口。你应该看看当地的“s”。它的价值是“a test”。
4) 右键单击“局部变量”窗口中的“s”,然后单击上下文窗口上的“生成对象ID”。该值现在显示“A test”{1}。VS创建了一个伪变量“1”,并将其别名为“s”。
5) 现在切换回Foo()。
6) 在locals窗口中,您将看到值为null的“x”。
7) 将“x”的值设置为“1”。
8) x的值现在是“A test”{1}!
9) 跨过writeline,看看它实际上使用了这个新的x值。

ICorDebug的工作原理:

interface ICorDebugHeapValue2 : IUnknown

{

    /*

      * Creates a handle of the given type for this heap value.

      *

      */

    HRESULT CreateHandle([in] CorDebugHandleType type, [out] ICorDebugHandleValue ** ppHandle);

};

这将返回从ICorDebugReferenceValue派生的ICorDebugHandleValue。HandleValue跟踪正在检查的对象的GC句柄。(回想起来,我认为我们应该将此ICorDebugStrongReferenceValue而不是HandleValue。HandleValue表示它对应于System.Runtime.InteropServices.GCHandle结构,但它不是)。
调试器可以保留伪变量(如“1”)到ICorDebugHandleValue对象的映射。
“type”指定句柄是“strong”还是“weak”。“Strong”(又名“normal”)句柄使对象保持活动状态,而“弱”句柄则无法保持对象的活动状态。这样做的一个副作用是,调试器现在可以创建强句柄来更改对象的寿命,从而允许调试器更改程序行为。(因此,只在调试器下重新编写bug的问题更加严重)。由于GCs和寿命已经是不确定的,这种扰动类似于调试器改变时间和暴露竞争条件的情况。
V1.1试图在ICorDebug级别解决这个问题(通过ICorDebugReferenceValue::DereferenceStrong),但这是一个失败的设计。我们不赞成取消引用strong,而倾向于使用ICorDebugHandleValue。

 

标签:对象,句柄,代码,托管,标识,Foo,调试,调试器
来源: https://www.cnblogs.com/yilang/p/13906124.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有