crash in release build

B

bjornms

The application i build in C#.net is crashing once a month. I can't
reproduce the crash.

Is there a way to track down where the program crashes, without
putting logging everywhere in the code? Is there a way to get a stack
trace of the crashing program (by the way, i'm new to C#.net, i have
experience in (unmanaged) C++).

Thanks in advance.
 
T

Thomas Tomiczek

Sure it is the application? As in: it could be defective RAM on where the
application is used. I had that :)
 
K

Kevin Spencer

Is there a way to track down where the program crashes, without
putting logging everywhere in the code? Is there a way to get a stack
trace of the crashing program (by the way, i'm new to C#.net, i have
experience in (unmanaged) C++).

If you want information about a crash, you're going to need to implement
some form of logging. If I understand you correctly, you want to limit the
points where you implement logging. So, the most likely point is in the
application run loop. This would be found in your Main method, and is
usually found in the statement

Application.Run(...)

If you put a try/catch block around that, you can implement logging at that
level. Unhandled exceptions will bubble up to the application level. If you
want a stack trace, you can certainly put it into your log at this point,
but the proximity of the exception to the application level may limit the
amount of stack data you receive at that point. This is found in the
StackTrace property of the Exception.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

The shortest distance between 2 points is a curve.
 
J

John Duval

Hi,
If you don't have any idea where it's crashing (like the call stack),
you might want to consider implementing a centralized unhandled
exception handler.

// Add the event handler for handling UI thread exceptions to the
event.
System.Windows.Forms.Application.ThreadException += new
ThreadExceptionEventHandler(Application_ThreadException);
// Set the unhandled exception mode to force all Windows Forms errors
to go through our handler.
System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the
event.
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

Then in the exception handlers, you can get the stack, for example:

private static void Application_ThreadException(object sender,
ThreadExceptionEventArgs e)
{
// e.Exception.StackTrace will contain the call stack where
the exception occurred, write it to a file or something....
...
}

If that's not helping very much, you could try to use a tool like
ADPlus to grab a crash dump of the process and use Windbg with the SOS
extension to look at the state of the program at the time of the
crash. That's more work though.

Hope that helps,
John
 
O

Otis Mukinfus

The application i build in C#.net is crashing once a month. I can't
reproduce the crash.

Is there a way to track down where the program crashes, without
putting logging everywhere in the code? Is there a way to get a stack
trace of the crashing program (by the way, i'm new to C#.net, i have
experience in (unmanaged) C++).

Thanks in advance.

Why do you not want to use logging?

If you mean you don't want to log to the Event Viewer, then log to a file ONLY
WHEN AN EXCEPTION IS THROWN. There's no point in logging successful completion
of a run. When you log the exception log the stack trace by writing the stack
trace to the file by calling TheException.ToString(); or
TheException.StackTrace();

of course you will need to surround your code with try/catch blocks. You are
using try/catch blocks aren't you?

You don't need to put logging everywhere in the code if you make your catch like
this:

catch
{
throw;
}

When you do this you should put another try/catch block in an appropriate
location that is complete like this:

catch(Exception ex)
{
WriteToYourLog(ex.ToString();
}

All exceptions will be bubbled up to the final handler where they are logged.

Good luck with your project,

Otis Mukinfus

http://www.otismukinfus.com
http://www.arltex.com
http://www.tomchilders.com
http://www.n5ge.com
 
D

Dave Sexton

Hi,

Don't underestimate the power of instrumentation! (cheesy, I know)

Seriously, let's say you use everyone's suggestions to get the exception
logged, which is a great idea to begin with. Now, how do you debug it?
Sure, you may have the call stack and the exception but you'll probably have
no idea about the application's *state* at the time of the crash. With
tracing to the Application event log you will.

Just add calls to Trace.WriteLine in places where the state of the
application changes frequently and supply a short message and the values of
some of the local variables and fields. You can do the same in your
exception handling code as well, which should be used sparingly in most
applications.

Before the application starts (a good place is the Main method of your
program, before the call to Application.Run), add a call to:

System.Diagnostics.Trace.Listeners.Add(
new System.Diagnostics.EventLogTraceListener(Application.ProductName));

All of your trace output will be logged to the Application event log with
your app's name as the event source.

If you use a global TraceSwitch in your application then you can easily turn
on/off tracing (and, therefore, the event log output) using the app.config
file. If a user reports crashes or strange behavior you can ask them to
turn on tracing for you and send you the event log if the error occurs
again.

// assuming traceSwitch is an instance of the TraceSwitch class:
if (traceSwitch.TraceVerbose)
Trace.TraceInformation("Updated stock from {0} to {1}", stockOld,
stockNew);

TraceSwitch Class
http://msdn2.microsoft.com/en-us/library/system.diagnostics.traceswitch.aspx

I like to use the Program class created by VS 2005 to encapsulate a global
switch:

public static class Program
{
private static readonly TraceSwitch traceSwitch =
new TraceSwitch("Global",
Application.ProductName + " Trace Switch");

[Conditional("TRACE")]
public static void TraceVerbose(string format, params object[] args)
{
if (traceSwitch.TraceVerbose)
Trace.TraceInformation(format, args);
}

[Conditional("TRACE")]
public static void TraceVerbose(string message)
{
if (traceSwitch.TraceVerbose)
Trace.TraceInformation(message);
}
}

You can then use something like the following throughout your code:

Program.TraceVerbose("Updated stock from {0} to {1}", stockOld, stockNew);
 
C

Chris Mullins [MVP]

There sure is a good way to do it.

The first thing you want to do is make sure you produce a build and keep the
pdb files around. Don't misplace these!

Next up, install the Debugging Tools for Windows - specifically, ADPlus. You
want to now configure AD Plus to generate a Mini-Dump file on a 2nd Chance
Exception of your process. This way you app will run just fine for a month,
and when it does crash, you'll get a dump file.From here, you need to use
WinDbg & Son of Strike to track down the exact cause of the problem.

I go through this in much more detail in a Blog Entry that I did a few
months back:
http://www.coversant.net/Default.aspx?tabid=88&EntryID=28
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top