Назовите MiniDumpWriteDump с обратным вызовом

Скопируйте слой, затем используют shift + ctrl + v для создания нового изображения из скопированного слоя.

5
задан anchandra 1 September 2009 в 11:01
поделиться

3 ответа

Используйте этот код для определения структуры с объединением в 32 бита:

[StructLayout(LayoutKind.Explicit)]
internal struct MINIDUMP_CALLBACK_INPUT 
{
  [FieldOffset(0)]
  UInt32 ProcessId;

  [FieldOffset(4)]
  IntPtr ProcessHandle;

  [FieldOffset(8)]
  UInt32 CallbackType;

  [FieldOffset(12)]
  MINIDUMP_THREAD_CALLBACK Thread;
  [FieldOffset(12)]
  MINIDUMP_THREAD_EX_CALLBACK ThreadEx;
  [FieldOffset(12)]
  MINIDUMP_MODULE_CALLBACK Module;
  [FieldOffset(12)]
  MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
  [FieldOffset(12)]
  MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
};

Я думаю, что на 64-битной платформе смещения должны быть соответственно {0, 8, 16, 24} или {0, 4, 12, 16}, является ли ULONG 64 или 32-битным.


Edit

Я думаю, вы можете использовать MarshalAsAttribute для конкретного преобразования полей:

  [StructLayout(LayoutKind.Sequential)]
  struct VS_FIXEDFILEINFO
  {
    UInt32 dwSignature;
    UInt32 dwStrucVersion;
    UInt32 dwFileVersionMS;
    UInt32 dwFileVersionLS;
    UInt32 dwProductVersionMS;
    UInt32 dwProductVersionLS;
    UInt32 dwFileFlagsMask;
    UInt32 dwFileFlags;
    UInt32 dwFileOS;
    UInt32 dwFileType;
    UInt32 dwFileSubtype;
    UInt32 dwFileDateMS;
    UInt32 dwFileDateLS;
  }

  [StructLayout (LayoutKind.Sequential)]
  struct MINIDUMP_MODULE_CALLBACK
  {
    [MarshalAs(UnmanagedType.LPWStr)]
    String                      FullPath;
    UInt64                      BaseOfImage;
    UInt32                      SizeOfImage;
    UInt32                      CheckSum;
    UInt32                      TimeDateStamp;
    VS_FIXEDFILEINFO            VersionInfo;
    IntPtr                      CvRecord;
    UInt32                      SizeOfCvRecord;
    IntPtr                      MiscRecord;
    UInt32                      SizeOfMiscRecord;
  }
1
ответ дан 15 December 2019 в 06:31
поделиться

Это не прямой ответ на ваш вопрос, а обходной путь ...

Знаете ли вы библиотеку ClrDump , которая делает что вам нужно ? Я использовал его для проекта несколько лет назад, и он мне подходит.


Ответ на комментарий автора :

Прочтите на сайте:

ClrDump может создавать небольшие минидампы, содержащие достаточно информации для восстановления стеков вызовов всех потоков в приложении.

Я заключил API в следующий класс:

internal class ClrDump
{
  [return: MarshalAs(UnmanagedType.Bool)]
  [DllImport("clrdump.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  public static extern bool CreateDump(uint ProcessId, string FileName, MINIDUMP_TYPE DumpType, uint ExcThreadId, IntPtr ExtPtrs);

  [return: MarshalAs(UnmanagedType.Bool)]
  [DllImport("clrdump.dll", CharSet=CharSet.Unicode, SetLastError=true)]
  public static extern bool RegisterFilter(string FileName, MINIDUMP_TYPE DumpType);

  [DllImport("clrdump.dll")]
  public static extern FILTER_OPTIONS SetFilterOptions(FILTER_OPTIONS Options);

  [return: MarshalAs(UnmanagedType.Bool)]
  [DllImport("clrdump.dll", SetLastError=true)]
  public static extern bool UnregisterFilter();


  [Flags]
  public enum FILTER_OPTIONS
  {
    CLRDMP_OPT_CALLDEFAULTHANDLER = 1
  }

  [Flags]
  public enum MINIDUMP_TYPE
  {
    MiniDumpFilterMemory = 8,
    MiniDumpFilterModulePaths = 0x80,
    MiniDumpNormal = 0,
    MiniDumpScanMemory = 0x10,
    MiniDumpWithCodeSegs = 0x2000,
    MiniDumpWithDataSegs = 1,
    MiniDumpWithFullMemory = 2,
    MiniDumpWithFullMemoryInfo = 0x800,
    MiniDumpWithHandleData = 4,
    MiniDumpWithIndirectlyReferencedMemory = 0x40,
    MiniDumpWithoutManagedState = 0x4000,
    MiniDumpWithoutOptionalData = 0x400,
    MiniDumpWithPrivateReadWriteMemory = 0x200,
    MiniDumpWithProcessThreadData = 0x100,
    MiniDumpWithThreadInfo = 0x1000,
    MiniDumpWithUnloadedModules = 0x20
  }
}

, а затем где-то в моем коде инициализации я вызвал метод RegisterFilter, который регистрирует внутренний фильтр для необработанных исключений в текущем процессе. Если процесс вылетает из-за необработанного исключения (это может быть собственное или управляемое исключение), фильтр перехватывает его и создает минидамп (с указанным именем файла). Вот пример кода для этого:

StringBuilder sb = new StringBuilder();
sb.Append(Path.GetFileNameWithoutExtension(Application.ExecutablePath));
sb.Append("_");
sb.Append(DateTime.Now.ToString("yyyyMMddHHmmssFF"));
sb.Append(".dmp");
string dmpFilePath = Path.Combine(Path.GetTempPath(), sb.ToString());
ClrDump.RegisterFilter(_dmpFilePath, ClrDump.MINIDUMP_TYPE.MiniDumpNormal);

Вы можете прочитать эту статью , чтобы понять различные параметры MINIDUMP_TYPE, но я думаю, что базовый вариант (MiniDumpNormal) может удовлетворить ваши потребности.

Я вызвал метод RegisterFilter, который регистрирует внутренний фильтр для необработанных исключений в текущем процессе. Если процесс вылетает из-за необработанного исключения (это может быть собственное или управляемое исключение), фильтр перехватывает его и создает минидамп (с указанным именем файла). Вот пример кода для этого:

StringBuilder sb = new StringBuilder();
sb.Append(Path.GetFileNameWithoutExtension(Application.ExecutablePath));
sb.Append("_");
sb.Append(DateTime.Now.ToString("yyyyMMddHHmmssFF"));
sb.Append(".dmp");
string dmpFilePath = Path.Combine(Path.GetTempPath(), sb.ToString());
ClrDump.RegisterFilter(_dmpFilePath, ClrDump.MINIDUMP_TYPE.MiniDumpNormal);

Вы можете прочитать эту статью , чтобы понять различные параметры MINIDUMP_TYPE, но я думаю, что базовый вариант (MiniDumpNormal) может удовлетворить ваши потребности.

Я вызвал метод RegisterFilter, который регистрирует внутренний фильтр для необработанных исключений в текущем процессе. Если процесс вылетает из-за необработанного исключения (это может быть собственное или управляемое исключение), фильтр перехватывает его и создает минидамп (с указанным именем файла). Вот пример кода для этого:

StringBuilder sb = new StringBuilder();
sb.Append(Path.GetFileNameWithoutExtension(Application.ExecutablePath));
sb.Append("_");
sb.Append(DateTime.Now.ToString("yyyyMMddHHmmssFF"));
sb.Append(".dmp");
string dmpFilePath = Path.Combine(Path.GetTempPath(), sb.ToString());
ClrDump.RegisterFilter(_dmpFilePath, ClrDump.MINIDUMP_TYPE.MiniDumpNormal);

Вы можете прочитать эту статью , чтобы понять различные параметры MINIDUMP_TYPE, но я думаю, что базовый вариант (MiniDumpNormal) может удовлетворить ваши потребности.

2
ответ дан 15 December 2019 в 06:31
поделиться

Я так понимаю, что это союз, который доставляет вам проблемы ?

Если CallbackType == KernelMinidumpStatusCallback, то структура CALLBACK_INPUT определяется как:

ULONG ProcessId;
HANDLE ProcessHandle;
ULONG CallbackType;
HRESULT Status;

Если CallbackType == ThreadCallback, то это:

ULONG ProcessId;
HANDLE ProcessHandle;
ULONG CallbackType;
MINIDUMP_THREAD_CALLBACK Thread;

Если CallbackType == ThreadExCallback, то это:

ULONG ProcessId;
HANDLE ProcessHandle;
ULONG CallbackType;
MINIDUMP_THREAD_EX_CALLBACK ThreadEx;

И так далее (это из MSDN ) - похоже, что 4-й член может быть одного из 8 различных типов, в зависимости от того, чему равен CallbackType. Внутри Windows будет использовать один и тот же кусок памяти для всех этих структур (добавляя меньшие к размеру наибольшего). В C ++ легко получить нужный тип

Я не знаю, как это сделать на C #. Я использовал MiniDumpWriteDump в C ++, но никогда не использовал функцию обратного вызова.

0
ответ дан 15 December 2019 в 06:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: