MinidumpWriteDump из управляемого кода вызывает исключение AccessViolationException.

У меня есть базовый метод взаимодействия MiniDumpWriteDump, скопированный из Интернета в моем проекте С# (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;
        }

person lysergic-acid    schedule 22.10.2012    source источник
comment
Я не вижу ничего плохого. Много чего не хватает.   -  person Hans Passant    schedule 22.10.2012
comment
Чего не хватает? Этот же код отлично работает в контексте обработчика необработанных исключений, однако в другом случае происходит сбой при исключении. Что еще я могу добавить к своему первоначальному вопросу, чтобы сделать его более понятным?   -  person lysergic-acid    schedule 22.10.2012
comment
Ну, само исключение нарушения доступа, похоже, отсутствует в действии для начала. Не могли бы вы включить трассировку стека?   -  person Maarten Bodewes    schedule 25.10.2012


Ответы (1)


Marshal.GetExceptionPointers() может вернуть IntPtr.Zero (возможно, когда ОС увидит, что исключение обработано). Если это так, вы можете попытаться поместить вызов MiniDumpWriteDump в другое место. У меня была такая же проблема, и я решил ее, поместив «MiniDumpWriteDump» в обработчик событий «AppDomain.CurrentDomain.FirstChanceException».

person user1027167    schedule 26.03.2014