2011-09-27 67 views
11

我的多线程托管程序中存在堆损坏。做了一些测试后,我发现只有当程序中的后台线程处于活动状态(它们是可切换的)时才会发生损坏。线程使用一些第三方组件。.NET 4:托管代码是否会导致堆损坏?

检查线程和第三方组件的代码(使用.NET反射)后,我发现他们都得到管理,即没有“不安全”或“DllImportAttribute”或“P/Invoke的”。看起来纯粹的托管代码会导致堆损坏,这可能吗?

UPDATE

除了使用Marshal类,是有可能损坏具有螺纹堆不被正确地同步?一个例子将非常感激。

+2

只是因为他们是全部管理,并不意味着一切都是线程安全的。你是否确保代码以线程安全的方式执行,在需要的地方使用锁等? –

+0

也有元帅类方法可以做到这一点。 –

+2

@ChrisDunaway,你是说不正确的锁定或以非线程安全的方式执行线程可以破坏堆,即使不使用Marshal类?我有一个答案,这是不可能的([这里](http://stackoverflow.com/questions/7471288/what-tools-are-available-to-detect-heap-corruption-in-net-c-program/ 7471468#7471468))。 –

回答

12

绝对有可能在不使用任何不安全代码的情况下破坏堆。 Marshal类的地址为你的朋友/敌人在这里

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

这有效地复制100个连续的0到堆中50000

另一种方式是明确的结构布局

[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 ... :) 
+0

Re。结构体,普通'[StructLayout(LayoutKind.Sequential)]'不会导致堆腐败,对吧? –

+0

@net_prog不,''LayoutKind.Explicit'需要这个技巧才能工作/崩溃:) – JaredPar

+0

@net_prog in * general *托管代码无法破坏堆。这些只是一些......可能导致它的极端情况。这是*可能*但是你碰到CLR错误的可能性不大。 – JaredPar