Creating minidumps in C # 4.0 projects being developed in VS 2010
To create minidumps in a managed environment, the capabilities of the DbgHelp.dll library are used. Consider the application of its functionality on the example of a finished project on WinForms.
First of all, note that minidumps must be created when an unhandled exception occurs. In order to, for example, generate such an exception, during the execution of the program we will divide by zero when the user presses a certain button:
Now we will consider those mechanisms by which exceptions that are not processed by the developer code are handled in projects. We are interested in two handlers:
A ThreadException typically handles unhandled exceptions related to UI threads (such as those that may occur in WinForms events). All other unhandled exceptions cause the program to stop. However, before the final completion of its work, you can perform some of the necessary actions for us: save the user data, or, as in our case, write a minidump to the hard disk. To do this, use the UnhandledException handler.
In order to simplify the solution of the problem, we will make sure that all exceptions are handled by UnhandledException. To do this, before the Application.Run (new Form1) method in Main (), call the following method:
From this point on, ThreadException does not interest us.
All actions to handle exceptions using DbgHelp are encapsulated in one DumpMaker class, which will have an important method for us with the following signature:
This is the method we will register for handling UnhandledException:
Now the program will call our method before abnormally shutting down.
DumpMaker Class Content
MINIDUMP_TYPE contains all the types of minidumps we can create. Each type is associated with a specific constant. A complete list of constants can be found on the website .
MINIDUMP_EXCEPTION_INFORMATION - a structure that will store information about the exception, due to which the program completed its work.
Returns the ID of the current process.
A library method that directly performs dump creation and recording. It is called from a method
The dump is written to a file with a unique name (FileName), which will be stored in the same directory as the exe file. Before calling MiniDumpWriteDump, initialize a structure of type MINIDUMP_EXCEPTION_INFORMATION.
Consider the list of MiniDumpWriteDump options.
hProcess - descriptor of the process for which information is generated
ProcessID - ID of the process for which information is generated
hFile - file descriptor
DumpType - dump type (we will use MiniDumpNormal)
ExceptionParam - exception information
UserStreamParam - user-defined information. We will not include it in the dump and pass it to the IntPtr.Zero CallbackParam method
- callback information. We will not use it either.
The CreateMiniDump method will be called directly from CurrentDomain_UnhandledException, warning the user before this about what happened:
Let's check the program’s work by running the assembled exe-file and clicking on the button we created:
We got a dump with the extension .dmp. To use it, you just need to open the file, and as a result, VisualStudio will start.
A similar menu will appear on the right side of the window:
In order to be able to work with the real program code, and not with the IL code and stack trace, you must specify symbol paths - directories in which the pdb files of our application are supposedly stored. The pdb file contains debugging data and project status information. By default, the searched files are contained in the same directory as the executable files.
Next, by clicking on Debug with mixed, we will start the debugging process. We will be able to see the state of the program at the time of the collapse, as well as a warning about the exception that has occurred.
1. Stackoverflow
2. Using Crash Minidump
3. Howto: C # Generate dump file on crash
4. Writing Minidumps in C #
A. Fedosin
We write the code creating minidumps
First of all, note that minidumps must be created when an unhandled exception occurs. In order to, for example, generate such an exception, during the execution of the program we will divide by zero when the user presses a certain button:
private void button1_Click_1(object sender, EventArgs e)
{
int a = 3;
int b = 0;
int c = a / b;
}
Now we will consider those mechanisms by which exceptions that are not processed by the developer code are handled in projects. We are interested in two handlers:
AppDomain.CurrentDomain.UnhandledException
Application.ThreadException
A ThreadException typically handles unhandled exceptions related to UI threads (such as those that may occur in WinForms events). All other unhandled exceptions cause the program to stop. However, before the final completion of its work, you can perform some of the necessary actions for us: save the user data, or, as in our case, write a minidump to the hard disk. To do this, use the UnhandledException handler.
In order to simplify the solution of the problem, we will make sure that all exceptions are handled by UnhandledException. To do this, before the Application.Run (new Form1) method in Main (), call the following method:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
From this point on, ThreadException does not interest us.
All actions to handle exceptions using DbgHelp are encapsulated in one DumpMaker class, which will have an important method for us with the following signature:
public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
This is the method we will register for handling UnhandledException:
AppDomain.CurrentDomain.UnhandledException += DumpMaker.CurrentDomain_UnhandledException;
Now the program will call our method before abnormally shutting down.
DumpMaker Class Content
private static class MINIDUMP_TYPE
{
public const int MiniDumpNormal = 0x00000000;
...
public const int MiniDumpWithCodeSegs = 0x00002000;
}
MINIDUMP_TYPE contains all the types of minidumps we can create. Each type is associated with a specific constant. A complete list of constants can be found on the website .
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct MINIDUMP_EXCEPTION_INFORMATION
{
public uint ThreadId;
public IntPtr ExceptionPointers;
public int ClientPointers;
}
MINIDUMP_EXCEPTION_INFORMATION - a structure that will store information about the exception, due to which the program completed its work.
[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();
Returns the ID of the current process.
[DllImport("Dbghelp.dll")]
static extern bool MiniDumpWriteDump(IntPtr hProcess, uint ProcessId, IntPtr hFile, int DumpType, ref MINIDUMP_EXCEPTION_INFORMATION ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam);
A library method that directly performs dump creation and recording. It is called from a method
private static void CreateMiniDump()
{
using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
{
string FileName = string.Format(@"CRASH_DUMP_{0}_{1}.dmp", DateTime.Today.ToShortDateString(), DateTime.Now.Ticks);
MINIDUMP_EXCEPTION_INFORMATION Mdinfo = new MINIDUMP_EXCEPTION_INFORMATION();
Mdinfo.ThreadId = GetCurrentThreadId();
Mdinfo.ExceptionPointers = Marshal.GetExceptionPointers();
Mdinfo.ClientPointers = 1;
using (FileStream fs = new FileStream(FileName, FileMode.Create))
{
{
MiniDumpWriteDump(process.Handle,(uint)process.Id, fs.SafeFileHandle.DangerousGetHandle(), MINIDUMP_TYPE.MiniDumpNormal,
ref Mdinfo,
IntPtr.Zero,
IntPtr.Zero);
}
}
}
}
The dump is written to a file with a unique name (FileName), which will be stored in the same directory as the exe file. Before calling MiniDumpWriteDump, initialize a structure of type MINIDUMP_EXCEPTION_INFORMATION.
Consider the list of MiniDumpWriteDump options.
hProcess - descriptor of the process for which information is generated
ProcessID - ID of the process for which information is generated
hFile - file descriptor
DumpType - dump type (we will use MiniDumpNormal)
ExceptionParam - exception information
UserStreamParam - user-defined information. We will not include it in the dump and pass it to the IntPtr.Zero CallbackParam method
- callback information. We will not use it either.
The CreateMiniDump method will be called directly from CurrentDomain_UnhandledException, warning the user before this about what happened:
public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
System.Windows.Forms.MessageBox.Show("Unhandled exception!");
CreateMiniDump();
}
Run the program
Let's check the program’s work by running the assembled exe-file and clicking on the button we created:
Run the dump
We got a dump with the extension .dmp. To use it, you just need to open the file, and as a result, VisualStudio will start.
A similar menu will appear on the right side of the window:
In order to be able to work with the real program code, and not with the IL code and stack trace, you must specify symbol paths - directories in which the pdb files of our application are supposedly stored. The pdb file contains debugging data and project status information. By default, the searched files are contained in the same directory as the executable files.
Next, by clicking on Debug with mixed, we will start the debugging process. We will be able to see the state of the program at the time of the collapse, as well as a warning about the exception that has occurred.
Used sources
1. Stackoverflow
2. Using Crash Minidump
3. Howto: C # Generate dump file on crash
4. Writing Minidumps in C #
The author of the article
A. Fedosin