Download presentation
Presentation is loading. Please wait.
Published byNicoletta Arcuri Modified over 5 years ago
1
Crash Handlers Riddhiman Ghosh Debugging Applications for
Crash Handlers Riddhiman Ghosh Debugging Applications for .NET and Windows John Robbins
2
Goal From “prevention” to “cure”. How to deal with a program that has crashed? How to pinpoint sources of errors in programs that are running outside the debugger and on-site?
3
Outline Exceptions Crashes Code Samples C++ Exceptions
Structured Exception Handling Crashes Custom Crash Handlers Bugslayer Crash Utils Minidumps Code Samples
4
Types of Exception Handling
C++ Exception Handling Structured Exception Handling (SEH) The two have different approaches to exception handling.
5
C++ Exceptions try, catch, throw void someFunc() { try
//exception block throw 100; } catch(int& exc) //exception handler cout<<"Caught Exception "<<exc;
6
Structured Exception Handling
Is provided by the Operating System and is independent of programming language. Deals directly with crashes such as access violations, stack overflows, invalid handles, no memory, etc. We can use SEH through C/C++ using the __try/__except/__finally keywords.
7
Structured Exception Handling
void someFunc() { __try //exception block } __except(EXCEPTION_EXECUTE_HANDLER) //exception handler cout<<"Caught Exception "<<exc; __finally //termination block //release resources
8
Structured Exception Handling
The parameter of __except is called an “exception filter” that specifies how the exception is supposed to be handled. 3 possible values: EXCEPTION_EXECUTION_HANDLER EXCEPTION_CONTINUE_EXECUTION EXCEPTION_CONTINUE_SEARCH
9
Structured Exception Handling
EXCEPTION_EXECUTION_HANDLER Indicates that the code in the __except block should be used to handle the exception. EXCEPTION_CONTINUE_EXECUTION Allows the exception to be ignored. EXCEPTION_CONTINUE_SEARCH Passes the exception up the call chain to the next __except block. The OS will continue looking for a suitable exception handler.
10
Structured Exception Handling
The exception filter can be a complex expression. __try { //exception block throw 100; } __except( EXCEPTION_INT_DIVIDE_BY_ZER0 == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ) //exception handler ...
11
Structured Exception Handling
GetExceptionCode can only be called in exception filters, else compiler error. GetExceptionInformation – returns a pointer to an EXCEPTION_POINTERS structure that completely describes the reason for the crash and the state of the CPU at the time of the crash. typedef struct _EXCEPTION_POINTERS { PEXCEPTION_RECORD ExceptionRecord; PCONTEXT ContextRecord; } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
12
Structured Exception Handling
RaiseException SEH is not limited to crashes – you can create your own exceptions with RaiseException. Custom error codes are limited to a single unsigned integer
13
Structured Exception Handling
Vectored Exception Handling An advanced feature of SEH that first appeared in Windows XP and Windows Server 2003. Allows global notification for every exception that occurs, making it possible to log and monitor all exceptions being generated by your application, even from third-party library code. If your application crashed in front of a customer due to an unhandled exception, you’d like to know where it came from.
14
… and never the twain shall meet!
A serious limitation of SEH is the fact that SEH and C++ exception handling don’t mix very well. C++ exceptions are implemented internally using SEH. The compiler complains if you use the two indiscriminately together . Unlike C++, SEH does not call destructors for objects created on the stack.
15
SEH vs. C++ Exceptions Robbins: “Avoid C++ exception handling”
C++ exception handling is not a “clean feature” of the language, and has not been architected well. E.g. there is no ANSI standard class that contains information about an exception for consisting handling of generic errors. Unlike SEH, C++ exception handling does not handle hard crashes automatically. Translation functions between SEH and C++, such as _set_se_translator don’t really work.
16
SEH vs. C++ Exceptions Robbins: “Avoid C++ exception handling”
C++ exception handling comes with a much larger overhead, and should not be used in performance-sensitive applications. C++ uses SEH internally to implement exceptions.
17
SEH vs. C++ Exceptions Robbins:
“Absolutely, positively, never, ever use catch(…)” catch(…)block can catch any type of exception, but since there is no parameter to this function, you have no way of knowing what was thrown, how you got there and why. Without this information the only logical and safe thing to do is to terminate.
18
SEH vs. C++ Exceptions Robbins:
“Absolutely, positively, never, ever use catch(…)” More seriously, catch(…)eats not only C++ exceptions but also SEH exceptions, since C++ uses SEH internally. Not only do you not know how you’ve reached the catch block, you’ve probably silently eaten up a hard error such as an access violation, and you know nothing about how to handle it. Your program may crash later, obscuring any causal relationship to the real cause of the crash from you.
19
When your program crashes…
When an exception is raised, “exception unwinding” takes place, in search of a suitable handler. If “no one” is ready to handle the exception the program crashes.
20
When your program crashes…
Actually there is always an exception handler. If none is explicitly provided, the OS always sneaks in a default exception handler. It is this handler generates the “Application Error” dialog box as shown and allows you to terminate/debug the program on a “crash”.
21
When your program crashes…
The default “Application Error” dialog box is hardly useful. To get to the bottom of a crash we need more information. We can create our own dialog boxes and handlers to obtain the information we want, at the same time presenting a friendlier interface to the user – “Crash Handlers”
22
Crash Handlers “Crash Handlers” = “Proactive Debugging”
With a crash handler its possible to get control right as the application dies, and log vital information about the crash: the processor context the memory the state of all objects live at the time of the crash This may look like too much information to log, but helps replicate conditions that led to a crash.
23
Crash Handlers SetUnhandledExceptionFilter
This API function allows you to specify an exception filter function (the crash handler) that will be called whenever an unhandled exception occurs in the process. This API call takes in a pointer to a function that will be called in case of an unhandled exception.
24
Crash Handlers SetUnhandledExceptionFilter
The exception filter function receives a pointer to EXCEPTION_POINTERS that gives information about the exception. Any exception handling code can be placed in this callback function. Check the reason of the exception – the stack is damaged do not make function calls or calls to libraries like CRT or MFC.
25
Crash Handlers SetUnhandledExceptionFilter
Avoid memory allocations on the heap in the handler There is only one global crash handler per process. This handler will be called irrespective of which module of the process caused the crash.
26
Bugslayer Utilities Robbins’ bugslayerutil.dll includes the easy-to-use CrashHandler API SetCrashHandlerFilter: simply call this function to set your own exception filter function GetRegisterString – a that function reads an EXCEPTION_POINTERS structure to return formatted register string GetFaultReason – returns a complete description of the crash. Shows the process, the reason for the exception, the module that caused the exception, the address of the exception and if symbol information is available, the function, the source file and the line number where the crash occurred
27
Bugslayer Utilities GetFirstStackTraceString and GetNextStackTraceString functions let you walk the stack. You first call the GetFirstStackTraceString function and keep calling GetNextStackTraceString till it returns false, to walk the entire stack.
28
Minidumps An alternative to extracting crash information from an EXCEPTION_POINTERS structure is to use minidumps, also called crash dumps. A minidump contains the entire state of the application at the time of the crash. The Windows API provides: BOOL MiniDumpWriteDump( HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, /*dump type*/ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, /*pointer to EXCEPTION_POINTERS*/ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, /*usually NULL*/ PMINIDUMP_CALLBACK_INFORMATION CallbackParam /*usually NULL*/ );
29
Minidumps Dump (.DMP) files can be loaded into a debugger such as Visual Studio. The source and symbols, if available, for the dump file are automatically loaded. Its like being there when the crash occurred; debugging a dump is almost like live debugging. In bugslayerutil Robbins uses MiniDumpWriteDump to give us a function that we can use to snap out a dump at any time during program execution.
30
Summary SEH provides a powerful, language independent means of exception handling. Avoid using C++ exceptions. Never use the catch(…) construct. Crash Handlers are very effective debugging tools – provide detailed information on the crash, and help replicate crash conditions for troubleshooting.
31
Summary Crash Handlers can obtain exception information using GetExceptionInformation, or use crash dumps which contain detailed application state at the time of the crash. BugslayerUtil provides an easy to use interface to add crash handler and dumping functionality to our applications.
32
References Robbins, J. Debugging Applications for .NET and Windows, Microsoft Press, 2003 Pietrek, M. "A Crash Course on the Depths of Win32 Structured Exception Handling," Microsoft Systems Journal, January Gershnik, E. “Visual C++ Exception-Handling Instrumentation,” Windows Developer Magazine, December Microsoft Developer Network
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.