0

I have a rather simple program that operates as an inventory tracking program. It is a single thread, .net 4.0, and is entirely event driven(nothing happens without a button click). The program crashes without a button being clicked. Here are the measures I have taken to attempt to get any information about this error:

FIRST: LOOK FOR UNHANDELED EXCEPTIONS OR THREAD EXCEPTIONS. CREATE A MESSAGE BOX POP-UP AND A DATABASE ENTRY FOR THIS ERROR:

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Application.Run(new archiveInventory_b());
    }
    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
        ErrorLogEntry(e.Exception.Message + " INNER EXCEPTION: " + e.Exception.InnerException.Message, "ThreadException");
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
        ErrorLogEntry((e.ExceptionObject as Exception).Message + " INNER EXCEPTION: " + (e.ExceptionObject as Exception).InnerException.Message, "UnhandledException");
    }

The program closes and no message box or database entry.

SECOND: CATCH THE CULPRIT IN THE ACT WHEN THE PROGRAM CLOSES:

private static void form_Closing(object sender, CancelEventArgs e)
    {
        const string message =
    "Are you sure that you would like to close the program?";
        const string caption = "Form Closing";
        var result = MessageBox.Show(message, caption,
                                     MessageBoxButtons.YesNo,
                                     MessageBoxIcon.Question);

        // If the no button was pressed ... 
        if (result == DialogResult.No)
        {
            // cancel the closure of the form.
            e.Cancel = true;
        }
    }

Yet no message ever appears. What else can be done to track this one down?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Yoda Bytes
  • 117
  • 2
  • I too am finding it hard to decipher in your question which code snippet you provided is erroneous (unclear). Have you tried stepping through, debugging? it should halt your program when it crashes at which point you should have a call stack and a handy halted program. – Sayse Sep 11 '14 at 14:02
  • 1
    The question is poetic yet hard to read. I'd recommend you to use logging throughtout your app, it's a nice way to catch that kind of errors. – AndreySarafanov Sep 11 '14 at 14:04
  • The error occurs at any random point. I cannot recreate the error because I do not have the time to use my program for the necessary amount of time for it to randomly occur. I was going to get the error message from an error message that the user would receive – Yoda Bytes Sep 11 '14 at 14:05
  • 1
    that form_closing event was taken straight from msdn?http://msdn.microsoft.com/en-us/library/system.windows.forms.messagebox(v=vs.110).aspx – jbutler483 Sep 11 '14 at 14:06
  • jbutler483: yup, taken verbatim from the evil empire. I see you're good rebel material yourself – Yoda Bytes Sep 11 '14 at 14:08
  • 1
    Are you breaking on all thrown exceptions? ("debug" menu->exceptions) – James Sep 11 '14 at 14:09
  • what do you mean by *'the program crashes'*? What's telling you it's the program if it happens randomly? – jbutler483 Sep 11 '14 at 14:11
  • jbutler483: My users tell me that it crashes. And they claim that they could be turned around doing something else and it will still occur – Yoda Bytes Sep 11 '14 at 14:15
  • I am deeply impressed by the moderation here. Within 45 minutes all the irrelevant information has been taken out. – Yoda Bytes Sep 11 '14 at 14:49
  • Oops. I read "depressed". – Larry Sep 11 '14 at 15:07

2 Answers2

2

There are three basic reasons why a .NET program can crash to the desktop without firing the event handlers you wrote. I'll assume it is not something obvious like Environment.Exit() in your code:

  • A StackOverflowException. There is not enough stack space left to do anything safely, including firing those events. You'll always know about it when you have a debugger attached but no notification at all when you run your program without one.

  • An ExecutionEngineException. Raised by the CLR when it detects that its internal data structures are corrupted. By far the most common reason is corruption of the GC heap, in turn caused by a bad pinvoke declaration or misbehaving unmanaged code. Exceedingly difficult to diagnose, the damage is always done long before the crash occurs.

  • A /GS violation. /GS is the name of a C++ compiler option that adds extra checks to code to verify that the processor stack was not corrupted. A very common malware attack vector, a way to get a processor to execute arbitrary code with just data. /GS checks are present in the CLR as well as code generated by the jitter. Such mishaps are very rare, the original .NET 4.0 release had some bugs in the CLR that triggered this check incorrectly but I haven't heard about it for quite a while. They can be diagnosed with the debugger, you however have to turn on unmanaged code debugging.

Which one of those three is crashing your program is something you'll have to find out the hard way. The most basic way to discover which way you need to go hunting next is paying attention to the process exit code. Its value will be non-zero to indicate failure, it is set to the matching underlying SEH exception code. When you have trouble reproducing the crash then you may have to write a little helper program that does nothing but use the Process class to start your main program. When it stops, the Process.ExitCode gives you the value.

Needless to say perhaps, this is going to take a while to get fixed so allocate the resources you need to hone down on the problem. Extensive testing to get a repro is required. Keep your fingers crossed for a simple SOE, by far the most common reason, those other two are awfully ugly and you're liable to need Microsoft Support.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

There is a known issue about swallowed Exceptions in the Load() event in Windows x64.

To eliminate this reason (or check it...), could you please add an try/catch in your load event (if applicable), so you can verify if any exception occurs here ?

Community
  • 1
  • 1
Larry
  • 17,605
  • 9
  • 77
  • 106
  • 1
    Another good way to catch this type of exception is to go to Debug > Exceptions, and check "Thrown" on the "Common Language Runtime Exceptions". Don't leave this setting on all the time or it will drive you nuts. – Bradley Uffner Sep 11 '14 at 14:25
  • Would I be correct in assuming that I should put a try/catch in each form's load? – Yoda Bytes Sep 11 '14 at 16:18
  • Yes, in general, in every events that is fired from an external source. – Larry Sep 11 '14 at 16:54