ГЛАВНАЯ     АРХИВ     НАПИСАТЬ АДМИНУ     ПОДПИСАТЬСЯ НА RSS     ВОЙТИ      

Поиск

Категории

Облако тегов

  << Предыдущий пост       Следующий пост >>  
От: inbruk
19. августа 2013 16:43

исключения

Продолжаю цикл переводов понравившейся мне статьи автора James Dingle про исключения. Первый пост посвященный этой статье находится здесь.

9. Сохраняйте дампы

Функция Win32 API MiniDumpWriteDump() позволяет вам сохранить дамп и продолжить выполнение приложения. Это очень удобный шаблон для улучшения разрешения проблем, в дополнение к логам. Это очевидно довольно дорогой процесс. Так что использовать его нужно, довольно редко. Но обычно результаты оказываются очень ценными.

Здесь написано как сделать это на Си: http://blogs.msdn.com/b/joshpoley/archive/2008/05/19/prolific-usage-of-minidumpwritedump-automating-crash-dump-analysis-part-0.aspx .

Дальше будет пример на C#. Вы также можете найти много примеров в интернете. Как только дамп сгенерирован и сохранен. Вы просто открываете его в Visual Studio. И имеете доступные исходные коды (возможно имелось ввиду, что для разбора они нужны).

Важно чтобы вы вызывали этот метод внутри вашего блока catch. Сделав так вы получите исключение встроенное (сохраненное) в дампе. И указатель текущей инструкции будет установлен на строке с ошибкой. А не на строке, в которой дамп был создан.

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;


namespace Sample
{
  /// /// Creates a mini dump of the current process ///
  internal static class MiniDump
  {
    public static void CreateDump(string path, MiniDumpType miniDumpType)
    {
      var exceptionInfo = new MiniDumpExceptionInfo
        {
        ThreadId = GetCurrentThreadId(),
        ExceptionPointers = Marshal.GetExceptionPointers(),
        ClientPointers = false // false because own process
        };
      Process process = Process.GetCurrentProcess();

      using (var stream = new FileStream(path, FileMode.Create))
      {
        Debug.Assert(stream.SafeFileHandle != null);

        // The problem Marshal.GetExceptionPointers can return null on x86 machines due to differences
        // in low-level exception handling.
        // Then passing a MiniDumpExceptionInfo structure with a NULL ExceptionPointers members causes an
        // access violation. So we only pass this structure if we got a valid ExceptionPointers member.
        // It will probably result that x86 machines will see the instruction pointer to the MiniDumpWriteDump
        // line and not the exception itself.
        IntPtr exceptionInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(exceptionInfo));
        Marshal.StructureToPtr(exceptionInfo, exceptionInfoPtr, false);

        try
        {
          MiniDumpWriteDump(
          process.Handle,
          process.Id,
          stream.SafeFileHandle.DangerousGetHandle(),
          miniDumpType,
          exceptionInfo.ExceptionPointers == IntPtr.Zero ? IntPtr.Zero : exceptionInfoPtr,
          IntPtr.Zero,
          IntPtr.Zero);
        }
        catch (Exception exception)
        {
          Trace("Cannot generate the mini-dump because of exception " + exception);
        }

        Marshal.FreeHGlobal(exceptionInfoPtr);
      }
    }

    [DllImport("kernel32.dll")]
    private static extern int GetCurrentThreadId();

    [DllImport("DbgHelp.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    private static extern Boolean MiniDumpWriteDump(
      IntPtr hProcess,
      Int32 processId,
      IntPtr fileHandle,
      MiniDumpType dumpType,
      IntPtr excepInfo,
      IntPtr userInfo,
      IntPtr extInfo);

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct MiniDumpExceptionInfo
    {
      public Int32 ThreadId;
      public IntPtr ExceptionPointers;

      [MarshalAs(UnmanagedType.Bool)]
      public bool ClientPointers;
    }
  }

  [Flags]
  internal enum MiniDumpType
  {
    Normal = 0x00000000,
    WithDataSegs = 0x00000001,
    WithFullMemory = 0x00000002,
    WithHandleData = 0x00000004,
    FilterMemory = 0x00000008,
    ScanMemory = 0x00000010,
    WithUnloadedModules = 0x00000020,
    WithIndirectlyReferencedMemory = 0x00000040,
    FilterModulePaths = 0x00000080,
    WithProcessThreadData = 0x00000100,
    WithPrivateReadWriteMemory = 0x00000200,
    WithoutOptionalData = 0x00000400,
    WithFullMemoryInfo = 0x00000800,
    WithThreadInfo = 0x00001000,
    WithCodeSegs = 0x00002000,
    WithoutAuxiliaryState = 0x00004000,
    WithFullAuxiliaryState = 0x00008000
  }
}



Все, на этом статья заканчивается.

Похожие записи


Обработка и логирование исключений под Windows и в веб сервисах (часть 10)
Продолжаю цикл переводов понравившейся мне статьи автора James Dingle про исключения. Первый пост посвященный этой статье находится здесь. 8. Обрушивайтесь правильно В соответствии с правилом " 5 - Не проглатывать исключений ", некоторые разработчики предполагают, что их приложение должно быть всегда работающим. Таким образом они дум...

Обработка и логирование исключений под Windows и в веб сервисах (часть 6)
Продолжаю цикл переводов понравившейся мне статьи автора James Dingle про исключения. Первый пост посвященный этой статье находится здесь. 4. Обрабатывать исключение нужно на правильном уровне стека Давайте вернемся к нашей компании по доставке пиццы. Вы могли бы ожидать от каждого из сотрудников, что они не будут сообщять о каждой из проблем их...

Обработка и логирование исключений под Windows и в веб сервисах (часть 2)
Продолжаю цикл переводов понравившейся мне статьи автора James Dingle про исключения. Первый пост посвященный этой статье находится здесь. Почему я должен писать эффективные журналы исключений ? Написание эффективной системы перехвата и логирования исключений это не самая сексуальная (приятная, красивая) часть вашего приложения или службы. Хорошее и...

Добавить комментарий




biuquote
  • Комментарий
  • Предпросмотр
Loading


  Сохранить комментарий