.NET 4:托管代码本身是否会导致堆栈损坏?

13

我的多线程托管程序存在堆破坏问题。做了一些测试后,我发现只有在程序中的后台线程活动时(它们可以切换),才会发生破坏。这些线程使用了一些第三方组件。

通过使用.NET反编译器检查线程和第三方组件的代码,我发现它们都是托管的,即没有“unsafe”、“DllImportAttribute”或“P/Invoke”。似乎纯托管代码会导致堆破坏,这是可能的吗?

更新

除了使用Marshal类外,线程未正确同步是否可能导致堆破坏?如果有示例将会很受欢迎。


2
仅仅因为它们都是被管理的,并不意味着所有东西都是线程安全的。你是否确保代码在需要时以线程安全的方式执行,使用锁等机制? - Chris Dunaway
还有一些Marshal类的方法可以做到这一点。 - Alex F
2
@ChrisDunaway,您是在说不正确的锁定或以非线程安全的方式执行线程即使没有使用Marshal类也会破坏堆吗?我曾经回答过这个问题,认为这是不可能的(这里)。 - net_prog
1个回答

14

使用不安全的代码确实可以破坏堆,但是即使不使用不安全的代码也可能破坏堆。在这种情况下,Marshal类有时会成为你的朋友或敌人。

IntPtr ptr = new IntPtr(50000);  // Random memory
byte[] b = new byte[100];
Marshalp.Copy(b, 0, ptr, 100);

这将在地址50000处的堆中有效地复制100个连续的0。

另一种方法是使用显式结构布局。

[StructLayout(LayoutKind.Explicit)]
struct S1
{
    [FieldOffset(0)]
    internal string str;

    [FieldOffset(0)]
    internal object obj;
}

S1 s = new S1();
s.obj = new Program();
s.str.Trim();  // Hope that works ... :) 

@net_prog 不,需要使用 LayoutKind.Explicit 才能让这个技巧起作用 / 崩溃 :) - JaredPar
1
@net_prog 一般情况下,托管代码不可能破坏堆。这些只是极端情况,可能会导致此问题。但有可能会遇到CLR错误,尽管这种情况不太可能发生。 - JaredPar
你对这里的最后一个回复有什么看法? - net_prog
有没有一种方法可以使用线程而不正确同步呢? - net_prog
@net_prog 我认为没有。 - JaredPar
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接