처리되지 않은 예외가 발생하면 (AppDomain.CurrentDomain.UnhandledException 및 TaskScheduler.UnobservedTaskException을 사용하여) 미니 덤프를 생성하는 프로세스가 있습니다. 덤프는 처리되지 않은 예외 처리기에서 제대로 작동하지만 관찰되지 않은 작업 예외 처리기에서 호출 될 때 AccessViolationException을 생성합니다 (아래 예제 코드 참조).UnBservedTaskException 내부에 미니 덤프를 생성하면 AccessViolationException이 발생합니다.
MSDN 및 StackOverflow에서 읽은 바로는 두 코드 경로의 주요 차이점은 후자가 finalizer 스레드에서 발생하고 스레드 상태 또는 아마도 보안으로 인해이 작업이 성공하지 못하는 것으로 추측됩니다. .
관찰되지 않은 스레드 예외 상황에서 미니 덤프 작업이 실패하는 이유를 설명하는 정보 나 링크가 있습니까? 나는 단순히 노력하고있는 것이 불가능하다는 것을 받아 들여서 기쁩니다. 그러나 그 사실을 확인하고 이유를 알고 싶습니다.
아래의 코드는 내에서 처리되지 않은 예외를 트리거하여 내 문제를 보여줍니다. 관찰되지 않은 스레드 예외를 트리거하도록 가비지 콜렉션을 강요합니다. MiniDumpWriteDump 호출은 AccessViolationException을 생성합니다.
using System;
using System.IO;
using System.Runtime.ConstrainedExecution;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
namespace ExceptionTest
{
public class ClassThatThrows
{
public void Throw()
{
var t = new Task(() =>
{
Console.WriteLine("Throwing...");
throw new NullReferenceException();
});
t.Start();
}
}
public class Program
{
public static void Main(string[] args)
{
TaskScheduler.UnobservedTaskException += HandleUnobservedTaskException;
var test = new ClassThatThrows();
test.Throw();
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
Console.ReadLine();
}
[HandleProcessCorruptedStateExceptions]
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[SecurityCritical]
private static void HandleUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
WriteMiniDump();
}
private static void WriteMiniDump()
{
var miniDumpFilePath = GetMiniDumpFilePath();
using (var fileStream = new FileStream(miniDumpFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
MiniDumpExceptionInformation exceptionInfo;
exceptionInfo.ThreadId = GetCurrentWin32ThreadId();
exceptionInfo.ClientPointers = false;
exceptionInfo.ExceptionPointers = Marshal.GetExceptionPointers();
var currentProcess = GetCurrentProcess();
var currentProcessId = GetCurrentProcessId();
var safeFileHandle = fileStream.SafeFileHandle;
MiniDumpWriteDump(currentProcess, currentProcessId, safeFileHandle.DangerousGetHandle(), 0x00000000, ref exceptionInfo, IntPtr.Zero, IntPtr.Zero);
}
}
protected static string GetMiniDumpFilePath()
{
var timestamp = DateTime.Now.ToString("yyyyMMddTHHmmss");
var fileName = string.Format("MiniDump.{0}.mdmp", timestamp);
return Path.Combine(Path.GetTempPath(), fileName);
}
[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
public static extern uint GetCurrentWin32ThreadId();
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
public static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, IntPtr hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam);
[DllImport("kernel32.dll", EntryPoint = "GetCurrentProcess", ExactSpelling = true)]
public static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", EntryPoint = "GetCurrentProcessId", ExactSpelling = true)]
public static extern uint GetCurrentProcessId();
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct MiniDumpExceptionInformation
{
public uint ThreadId;
public IntPtr ExceptionPointers;
[MarshalAs(UnmanagedType.Bool)]
public bool ClientPointers;
}
}
}
감사
'IntPtr'이 전달되는 것을 고정하려고 했습니까? –
재현이 없으며 명백한 오류가 없습니다. Windows, dbghelp.dll 및 .NET 버전은 질문에 문서화되어야합니다. 내가 권장 할 수있는 것은 GC.KeepAlive (e.Exception);를 이벤트 핸들러에 장거리로 추가하는 것이다. 환경 문제를 찾으십시오. 또한 관리되지 않는 디버깅 인 Microsoft Symbol 서버를 활성화하고 폭탄이 나타날 때 표시되는 스택 추적을 게시하십시오. –