获取 .NET 对象的内存地址 (C#)

Get Memory Address of .NET Object (C#)(获取 .NET 对象的内存地址 (C#))
本文介绍了获取 .NET 对象的内存地址 (C#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试追踪单声道运行时中的一个错误,其中一个变量似乎被分配给一个有效对象,然后被重新分配给一个虚假对象,特别是

I am trying to track down a bug in the mono runtime where a variable appears to be allocated to one valid object, and then is reassigned later to a bogus object, specifically

//early in code I allocate, fine
var o = new object(); // valid allocation
// later in code this is called, not fine
lock(o) // <- is triggering bug due to "o" now referencing a nonsense memory location.

我想知道对o"的引用何时变得无意义,为此我正在寻找一种方法来确定 C# 代码中各个时间点的o"地址.我知道与其他问题类似,答案是不要这样做,有 GC",但 GC 不起作用,所以我需要一个解决方法.

I would like to know when the reference to "o" becomes nonsense, and to do this am looking for a way to determine the address of "o" at various timepoints within the C# code. I know is similar to other questions with answers "don't do that there is a GC", but the GC doesn't work so I need a workaround.

有谁知道如何确定 C# 中单声道对象的地址?可以链接非托管代码或其他任何内容.(任何其他线索来诊断主要问题的方法都值得赞赏).

Does anyone know how I can determine the address of a mono object in C#? Am fine to link in unmanaged code or whatever. (Any other clues to ways to diagnose the main issue appreciated to).

推荐答案

原来这在 .NET 中无法直接实现,但可以通过更改 mono 运行时代码来实现.要创建可以读取内存地址的 C# 方法,请对 mono 源代码进行以下更改:

Turns out this is not possible in .NET directly, but can be accomplished by altering the mono runtime code. To create a C# method that can read the memory address, make the following changes to the mono source code:

修改 gc-internal.h 以添加

Alter gc-internal.h to add

gpointer    ves_icall_System_GCHandle_GetAddrOfObject (MonoObject *obj) MONO_INTERNAL;

更改 gc.c 以添加:

Alter gc.c to add:

gpointer    ves_icall_System_GCHandle_GetAddrOfObject (MonoObject *obj) {
    return (char*)obj;
}

更改 GCHandle.cs 以添加:

Alter GCHandle.cs to add:

MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static IntPtr GetAddrOfObject(object obj);

public static IntPtr AddrOfObject(object o)
{
    IntPtr res = GetAddrOfObject(o);
    return res;
}

修改 icall-def.h 以添加

Alter icall-def.h to add

ICALL(GCH_6, "GetAddrOfObject", ves_icall_System_GCHandle_GetAddrOfObject)

请注意,这些必须按顺序排列,因此将其添加到 GetAddrOfPinnedObject 行上方重建

Note that these must be in order, so add it above the GetAddrOfPinnedObject line Rebuild

最后,从 C# 调用它

Finally, call it from C#

for (int i = 0; i < 100; i++) {
    object o = new object ();
    var ptr = GCHandle.AddrOfObject (o);
    Console.WriteLine ("Address: " + ptr.ToInt64().ToString ("x"));
}

这篇关于获取 .NET 对象的内存地址 (C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)