MinidumpWriteDump из управляемого кода создает исключение AccessViolationException
У меня есть базовый метод взаимодействия MiniDumpWriteDump, скопированный из Интернета в моем проекте C# (3.5).
До сих пор я использовал этот код для регистрации в событии UnhandledException, чтобы получить аварийный дамп до завершения процесса.
В конкретном сценарии, с которым я сейчас сталкиваюсь, я установил эту функцию для использования в каком-то другом случае, чтобы получить дамп диагностической памяти процесса.
Всякий раз, когда вызывается эта функция (не из обработчика UnhandledException), она генерирует AccessViolationException
Вот как выглядит код MiniDump (удалены некоторые лишние части):
using (var fs = new System.IO.FileStream(fileName,
System.IO.FileMode.Create,
System.IO.FileAccess.Write,
System.IO.FileShare.None))
{
MiniDumpExceptionInformation exp;
exp.ThreadId = GetCurrentThreadId();
exp.ClientPointers = false;
exp.ExceptionPointers = Marshal.GetExceptionPointers();
bool bRet = MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
fs.SafeFileHandle.DangerousGetHandle(),
(uint)dumpType,
ref exp,
IntPtr.Zero,
IntPtr.Zero);
return bRet;
}
Нативные типы определены так:
//typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
// DWORD ThreadId;
// PEXCEPTION_POINTERS ExceptionPointers;
// BOOL ClientPointers;
//} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
// Pack=4 is important! So it works also for x64!
[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct MiniDumpExceptionInformation
{
public uint ThreadId;
public IntPtr ExceptionPointers;
[MarshalAs(UnmanagedType.Bool)]
public bool ClientPointers;
}
1 ответ
Marshal.GetExceptionPointers() может вернуть IntPtr.Zero (возможно, когда ОС видит исключение как обработанное). Если это так, вы можете попробовать вызвать вызов MiniDumpWriteDump где-нибудь еще. У меня была та же проблема, и я решил ее, поместив MiniDumpWriteDump в обработчик событий AppDomain.CurrentDomain.FirstChanceException.