Click here to Skip to main content
15,900,467 members
Articles / Programming Languages / C#
Tip/Trick

Automatically Create Dump File When Program Hangs

Rate me:
Please Sign up or sign in to vote.
4.00/5 (6 votes)
24 Jan 2019CPOL 9.9K   4   15   3
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.

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Wiseneosco
Korea (Republic of) Korea (Republic of)
You know I can't speak English well but I'm learning. If there anything wrong in my article. Understand me. Smile | :) I'm so thankful if you could correct this.
Anyway, I'm a software programmer in Korea. I have been doing development about 10 years.
I majored in Computer Science and Engineering. I'm using c# mainly. Bye!

Comments and Discussions

 
Questioncdb.exe? Pin
dandy7224-Jan-19 5:03
dandy7224-Jan-19 5:03 
PraiseRe: cdb.exe? Pin
Bloody Chicken24-Jan-19 15:41
professionalBloody Chicken24-Jan-19 15:41 
GeneralRe: cdb.exe? Pin
dandy7225-Jan-19 7:53
dandy7225-Jan-19 7:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.