获取调用对象的HashCode?

Phi*_*ler 3 c# reflection

这可能是重复的,但我没有看到这个确切的问题或类似的问题/回答的日期比.Net 4的发布更新.

我正在寻找一个临时的hack,它允许我查看调用堆栈并获取堆栈中的所有调用对象(不是方法,但是包含方法的实例).最终我需要他们的哈希码.

这可能吗?

编辑:

无论是否在我的问题中遇到过,都在问是否有一种简单/内置的方法来做到这一点.真的,只是一个止损修复,直到我可以对系统的其他部分进行重大更改.谢谢你的答案.看到它们之后,我想我会等...:)

seh*_*ehe 5

你想在这里实现什么?

看看我在一个月前回答的类似问题:如何在托管代码中获取EIP的当前值?.你可能会从中获得灵感.或者你可能认为它太难看了(后者为+1).

如果您只想在程序会话中组装"唯一"调用路径,请继续:我非常确定使用AOP编织器并线程本地存储.这样做不会太难.

警告1:哈希对通用.NET对象不是很有用

随机对象的哈希码可能会随着它在堆上的位置而变化.供参考:在MONO上,在禁用移动堆分配器的情况下,Object :: GetHash是这个相当庞大的代码(mono/metadata/monitor.c)

#else
/*
 * Wang's address-based hash function:
 *   http://www.concentric.net/~Ttwang/tech/addrhash.htm
 */
    return (GPOINTER_TO_UINT (obj) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
#endif
Run Code Online (Sandbox Code Playgroud)

当然,对于移动分配器,事情稍微复杂一点,以保证在对象的生命周期内保持恒定的哈希值,但是你得到的结论是:每个运行时将生成不同的哈希值,并且完成的分配量将改变未来的默认哈希码相同的物体.

警告2:你的堆栈将包含外来帧

即使您通过提供适当的确定性散列函数来修复该部分,您也需要每个堆栈帧都是"可重新排列"的类型.情况可能并非如此.当然不是你使用类似于LINQ,匿名类型,静态构造函数,委托的东西; 所有类型的东西都可以将堆栈帧与(匿名)辅助类型交织,甚至是JIT编译器发明的性能蹦床,以优化尾递归,大型交换跳转表或多个重载之间的共享代码.

要点:堆栈分析很难:如果要进行堆栈分析,你肯定应该使用正确的API.

结论:

一定要有一个球.但听从了建议

  1. 您的要求是非标准的(由不支持它的运行时库加下划线); 这通常表明:您正在解决一个独特的问题(但重新考虑所选择的工具?)或者您正在以错误的方式解决它
  2. 您可以通过生成带有一些手写模拟代码的流程图而不是尝试挂钩到CLR VM来获取更多信息
  3. 如果您要这样做,请使用适当的API(可能是探查器API,因为采样分析器将完全保存:堆栈'指纹'每个如此多的指令)
  4. 如果您真的必须通过检测代码来实现,请考虑使用AOP