Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Automatically Create Dump File When Program Hangs

0.00/5 (No votes)
24 Jan 2019 1  
How to automatically create a dump file when the program hangs

Introduction

I would like to know how to create a dump file automatically when my program hangs for unexpected exceptions.

Background

There were a lot of articles about how to create a dump file using the Window Command or the Windbg program.

But my program is already set into a customer's computer, so I can't tell him "You should make a dump file yourself when the program is not responding."

Using the Code

To run this program, you need to use cdb.exe file. You can find in the attachment file. or You can download it as "Windows Software Development Kit" on the internet. While installing it, you should check the item "Debuggin Tools for Windows". Those files are inclued in that. You can also use windbg.exe file instead of cdb.exe. if you use it, windbg window will open and run.

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ProcessHangCheck
{
    public partial class Form1 : Form
    {
        Thread mThread;
        Process mProcess;

        public Form1()
        {
            InitializeComponent();
            mThread = null;
            mProcess = null;
        }

        // start monitoring 
        private void button1_Click(object sender, EventArgs e)
        {
            // process name except for ".exe"
            String strProcName = txtProcName.Text;

            // the execution file which is place in (like cdb or windbg)
            String strDumpExePath = txtDumpExecutionPath.Text;

            // the directory place in which a dump file is created
            String strDumpPath = txtDumpPath.Text;

            try
            {
                strDumpExePath = Path.GetFullPath(strDumpExePath);
                strDumpPath = Path.GetFullPath(strDumpPath);

                if (!Directory.Exists(strDumpExePath))
                    Directory.CreateDirectory(strDumpExePath);

                if (!Directory.Exists(strDumpPath))
                    Directory.CreateDirectory(strDumpPath);
            }
            catch (Exception)
            {
                strDumpExePath = "";
                strDumpPath = "";
            }

            if (String.IsNullOrEmpty(strProcName) ||
                String.IsNullOrEmpty(strDumpExePath) ||
                String.IsNullOrEmpty(strDumpPath))
            {
                MessageBox.Show("Process Name or CDB's location or Dump's directory is empty.");
            }
            else
            {
                Stop();
                mThread = new Thread(() => threadMain(strProcName, strDumpExePath, strDumpPath));
                mThread.Start();
            }
        }

        private void threadMain(String strProcName, String strDumpExePath, String strDumpPath)
        {
            if (String.IsNullOrEmpty(strProcName) || 
                String.IsNullOrEmpty(strDumpExePath) || String.IsNullOrEmpty(strDumpPath)) return;

            bool isAbort = false;
            while (!isAbort)
            {
                try
                {
                    Process[] procs = Process.GetProcessesByName(strProcName);
                    if (procs.Length != 0)
                    {
                        foreach (Process pr in procs)
                        {
                            // if this process is hanging
                            if (!pr.Responding)
                            {
                                Console.WriteLine("Start trying to create a dumpfile");

                                try
                                {
                                    strDumpExePath += "\\";
                                    strDumpExePath = Path.GetFullPath(strDumpExePath);

                                    strDumpPath += "\\";
                                    strDumpPath = Path.GetFullPath(strDumpPath);

                                    String strCmdParam = String.Format(
                                            "-p {0} -c \".dump /o /ma {1}{2}.dmp\"",
                                            pr.Id,
                                            strDumpPath,
                                            DateTime.Now.ToString("yyyyMMddHHmmss"));
                                    Console.WriteLine(strCmdParam);

                                    mProcess = new Process();

                                    mProcess.StartInfo.FileName = "cmd.exe";
                                    mProcess.StartInfo.UseShellExecute = false;
                                    mProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                                    mProcess.StartInfo.CreateNoWindow = true;
                                    mProcess.StartInfo.RedirectStandardOutput = true;
                                    mProcess.StartInfo.RedirectStandardInput = true;
                                    mProcess.StartInfo.RedirectStandardError = true;
                                    mProcess.Start();
                                    mProcess.StandardInput.WriteLine(
                                        String.Format(
                                            "\"{0}cdb.exe\" -p {1} -c \".dump /o /ma {2}{3}.dmp\"{4}",
                                            strDumpExePath,
                                            pr.Id,
                                            strDumpPath,
                                            DateTime.Now.ToString("yyyyMMddHHmmss"),
                                            Environment.NewLine));

                                    mProcess.StandardInput.Close();
                                    String strOutput = mProcess.StandardOutput.ReadToEnd();
                                    Console.WriteLine(strOutput);

                                    mProcess.WaitForExit(10 * 1000);
                                    if (!mProcess.HasExited) mProcess.Kill();

                                    if (!pr.HasExited) pr.Kill();
                                }
                                catch(Exception ex)
                                {
                                    MessageBox.Show(ex.ToString());
                                }
                            }
                            else
                            {
                                Console.WriteLine("Noting to do");
                            }
                        }
                    }
                    else
                        Console.WriteLine("Process isn't running");

                    Thread.Sleep(10 * 1000);
                }
                catch(ThreadAbortException)
                {
                    isAbort = true;
                    Thread.ResetAbort();
                }
                catch (Exception ee)
                {
                    Console.WriteLine(ee.ToString());
                    Thread.Sleep(10 * 1000);
                }
            }
        }

        private void Stop()
        {
            try
            {
                if (mThread != null)
                    mThread.Abort();

                if (mProcess != null && !mProcess.HasExited)
                    mProcess.Kill();
            }
            catch (Exception) { }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Stop();
        }

        // stop monitoring
        private void button2_Click(object sender, EventArgs e)
        {
            Stop();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            String strRoot = Application.StartupPath;
            txtDumpExecutionPath.Text = String.Format("{0}\\USEEXE", strRoot);
        }
    }
}

Points of Interest

There is no program which is perfect. :)

History

  • 24th January, 2019: Initial version
  • 25th January, 2019: zip file attached and add comments

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here