1 / 32

Crash Handlers Riddhiman Ghosh Debugging Applications for .NET and Windows John Robbins

Crash Handlers Riddhiman Ghosh Debugging Applications for .NET and Windows John Robbins. 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?. Outline. Exceptions

Download Presentation

Crash Handlers Riddhiman Ghosh Debugging Applications for .NET and Windows John Robbins

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CrashHandlersRiddhiman GhoshDebugging Applications for .NET and WindowsJohn 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 • 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 MiniDumpWriteDumpto 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 1997.http://www.microsoft.com/msj/0197/exception/exception.htm • Gershnik, E. “Visual C++ Exception-Handling Instrumentation,” Windows Developer Magazine, December 2002http://www.windevnet.com/documents/s=7697/win0212a/0212a.htm • Microsoft Developer Network

More Related