evo*_*obe 7 c# mono garbage-collection
我试图追踪单声道运行时中的一个错误,其中一个变量似乎被分配给一个有效对象,然后被重新分配给一个虚假对象,特别是
//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.
Run Code Online (Sandbox Code Playgroud)
我想知道何时对"o"的引用变得无意义,并且这样做是为了找到一种方法来确定C#代码中各个时间点的"o"的地址.我知道类似于其他问题的答案"不要做有GC",但GC不起作用所以我需要一个解决方法.
有谁知道如何在C#中确定单声道对象的地址?很好地链接在非托管代码或其他任何东西.(关于诊断主要问题的方法的任何其他线索).
s.b*_*rns 12
您应该能够使用GCHandle构造来实现此目的.
GCHandle objHandle = GCHandle.Alloc(obj,GCHandleType.WeakTrackResurrection);
int address = GCHandle.ToIntPtr(objHandle).ToInt32();
Run Code Online (Sandbox Code Playgroud)
'obj'是你想要得到的地址的对象.
事实证明这在.NET中是不可能的,但可以通过改变单声道运行时代码来实现.要创建可以读取内存地址的C#方法,请对单声道源代码进行以下更改:
更改gc-internal.h
gpointer ves_icall_System_GCHandle_GetAddrOfObject (MonoObject *obj) MONO_INTERNAL;
Run Code Online (Sandbox Code Playgroud)
改变gc.c添加:
gpointer ves_icall_System_GCHandle_GetAddrOfObject (MonoObject *obj) {
return (char*)obj;
}
Run Code Online (Sandbox Code Playgroud)
改变GCHandle.cs添加:
MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static IntPtr GetAddrOfObject(object obj);
public static IntPtr AddrOfObject(object o)
{
IntPtr res = GetAddrOfObject(o);
return res;
}
Run Code Online (Sandbox Code Playgroud)
改为添加icall-def.h
ICALL(GCH_6, "GetAddrOfObject", ves_icall_System_GCHandle_GetAddrOfObject)
Run Code Online (Sandbox Code Playgroud)
请注意,这些必须按顺序排列,因此请将其添加到GetAddrOfPinnedObject行重建之上
最后,从C#调用它
for (int i = 0; i < 100; i++) {
object o = new object ();
var ptr = GCHandle.AddrOfObject (o);
Console.WriteLine ("Address: " + ptr.ToInt64().ToString ("x"));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11234 次 |
| 最近记录: |