65.9K
CodeProject is changing. Read more.
Home

Automatically Create Dump File When Program Hangs

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (6 votes)

Jan 24, 2019

CPOL
viewsIcon

10440

downloadIcon

4

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