[C#]CallbackOnCollectedDelegate MDA
[CODE c++]
// Library.cpp : Defines the unmanaged entry point for the DLL application.
#include "windows.h"
#include "stdio.h"
void (__stdcall *g_pfTarget)();
void __stdcall Initialize(void __stdcall pfTarget())
{
g_pfTarget = pfTarget;
}
void __stdcall Callback()
{
g_pfTarget();
}
[/CODE]
위와 같은 unmanaged code를 C#에서 아래와 같이 쓸 경우
delegate가 unmanaged code의 함수 포인터로 사용되고,
콜백 함수가 가비지 콜렉터에 의해 수집되는 경우 CLR code에서 access violation이 일어날 수 있고,
CallbackOnCollectedDelegate
MDA(Managed Debugging Assistant)가 활성화 됩니다.
[CODE c#]
using System;
using System.Runtime.InteropServices;
public class Entry
{
public delegate void DCallback();
public static void Main()
{
new Entry();
Initialize(Target);
GC.Collect();
GC.WaitForPendingFinalizers();
Callback();
}
public static void Target()
{
}
[DllImport("Library", CallingConvention = CallingConvention.StdCall)]
public static extern void Initialize(DCallback pfDelegate);
[DllImport ("Library", CallingConvention = CallingConvention.StdCall)]
public static extern void Callback();
~Entry()
{
Console.Error.WriteLine("Entry Collected");
}
}
[/CODE]
unmanaged code 환경에서는 함수의 포인터가 상수값으로 할당되어 변하지 않는다는 가정하에서
프로그램에 수행되고 있지만, managed code 환경에서 해당 delegate의 reference count가 더이상 없고
필요하지 않다고 생각되는 경우 가비지 콜렉터가 이를 수집해 버립니다.
이러한 상황을 전혀 알리 없는 unmanaged code가 해당 함수 포인터로 접근을 하려고 할 때 access violation이 나게 되는 것입니다.
개인적으로 Application.Run이 수행되자 마자 계속 이러한 현상이 나타나기도 했었습니다.
CallbackOnCollectedDelegate MDA가 활성화 되지 않으면 바로 가비지 콜렉터가 바로 delegate를 수집해버릴 수도 있습니다. 그러나 이것이 활성화 되어있다면 몇개의 instance 이상이 될 때 수집하기 시작합니다. 이 숫자는 application configuration에서 조정해줄 수 있고, 기본값으로는 1000이 됩니다.
<mdaConfig>
<assistants>
<callbackOnCollectedDelegate listSize="1500" />
</assistants>
</mdaConfig>
위의 상황은 가비지 콜렉터에 의해 일어나는 상황이므로 대체적으로 랜덤하게 일어날 수 있습니다.
잘 돌아가던 프로그램이 갑자기 문제가 생기기도 하니 미리미리 조심을 해야겠습니다.
http://msdn2.microsoft.com/en-us/librar ··· %29.aspx
http://msdn.microsoft.com/msdnmag/issues/06/05/bugbash/
"프로그래밍 / MSDN" 분류의 다른 글
| MSDN 새단장 기념 이벤트 (0) | 2009/01/13 |
| Windows with C++ - Windows Template Library 8.0 (0) | 2007/12/13 |
| WCF Contract Attribute (0) | 2007/07/10 |
| Office 주 Interop 어셈블리 (0) | 2007/07/02 |
| [C#] Form Control에는 Thread-Safe 호출을 사용 (0) | 2007/05/31 |
| System Error Codes (0) | 2007/02/28 |
| Windows SDK .NET Framework 3.0 Samples (0) | 2007/02/24 |
| Visual C++ Libraries as Shared Side-by-Side Assemblies (0) | 2006/11/07 |

댓글을 달아 주세요