The ultimate solution to let the program exit in a decent way when it crashes (seh + dump + unhandled exception filter)

Source: Internet
Author: User
Tags exit in

Http://blog.csdn.net/starlee/article/details/6655779

--------------------------------------------------

In my previous articleArticleSeh + dump file for decent exit in case of program crash I introduced how to avoid using seh + dump fileProgramAnd create a dump file when the program crashes to help locate exceptionsCodeLine. However, only the code in the try/try t block has an exception can be captured. The code outside the try block has an exception and the program will crash.
The following uses the code in seh + dump file, which causes the program to exit in a decent way when it crashes, as an example.

View plainprint?
  1. // Create a dump file
  2. //
  3. VoidCreatedumpfile (LpcwstrLpstrdumpfilepathname, exception_pointers * pexception)
  4. {
  5. // Create a dump file
  6. //
  7. HandleHdumpfile = createfile (lpstrdumpfilepathname, generic_write, 0, null, create_always, file_attribute_normal, null );
  8. // Dump Information
  9. //
  10. Minidump_exception_information dumpinfo;
  11. Dumpinfo. exceptionpointers = pexception;
  12. Dumpinfo. threadid = getcurrentthreadid ();
  13. Dumpinfo. clientpointers = true;
  14. // Write the dump file content
  15. //
  16. Minidumpwritedump (getcurrentprocess (), getcurrentprocessid (), hdumpfile, minidumpnormal, & dumpinfo, null, null );
  17. Closehandle (hdumpfile );
  18. }
  19. // Function used as an expression in blocks t
  20. //
  21. LongCrashhandler (exception_pointers * pexception)
  22. {
  23. // Add the code for handling program crashes here
  24. //
  25. // Here is an example of a pop-up dialog box.
  26. //
  27. MessageBox (null, _ T ("Message from catch handler"), _ T ("Test"), Mb_ OK );
  28. // Create a dump file
  29. //
  30. Createdumpfile (_ T ("C: \ test. dmp"), Pexception );
  31. ReturnPrediction_execute_handler;
  32. }
  33. Int_ Tmain (IntArgc, _ tchar * argv [])
  34. {
  35. _ Try
  36. {
  37. MessageBox (null, _ T ("Message from '_ try' section"), _ T ("Test"), Mb_ OK );
  38. // In addition to zero, the program crashes manually
  39. //
  40. IntI = 13;
  41. IntJ = 0;
  42. IntM = I/J;
  43. }
  44. // Create a dump file when an exception that causes the program to crash
  45. //
  46. _ Random t (crashhandler (getexceptioninformation ()))
  47. {
  48. // Here is an example of a pop-up dialog box.
  49. //
  50. MessageBox (null, _ T ("Message from '_ partition t' section"), _ T ("Test"), Mb_ OK );
  51. }
  52. MessageBox (null, _ T ("Funcation completed"), _ T ("Test"), Mb_ OK );
  53. Return0;
  54. }

// Create a dump file <br/> // <br/> void createdumpfile (lpcwstr lpstrdumpfilepathname, exception_pointers * pexception) <br/>{< br/> // create a dump file <br/> // <br/> handle hdumpfile = createfile (lpstrdumpfilepathname, generic_write, 0, null, create_always, file_attribute_normal, null); </P> <p> // dump Information <br/> // <br/> minidump_exception_information dumpinfo; <br/> dumpinfo. exceptionpointers = pexception; <br/> dumpinfo. threadid = getcurrentthreadid (); <br/> dumpinfo. clientpointers = true; </P> <p> // write the dump file content <br/> // <br/> minidumpwritedump (getcurrentprocess (), getcurrentprocessid (), hdumpfile, minidumpnormal, & dumpinfo, null, null); </P> <p> closehandle (hdumpfile ); <br/>}</P> <p> // function used as an expression in blocks of blocks <br/> // <br/> long crashhandler (exception_pointers * pexception) <br/>{< br/> // Add the code for handling program crashes here <br/> // </P> <p> // a dialog box is displayed. for example <br/> // <br/> MessageBox (null, _ T ("Message from catch handler"), _ T ("test"), mb_ OK ); </P> <p> // create a dump file <br/> // <br/> createdumpfile (_ T ("C: \ test. DMP "), pexception); </P> <p> return exception_execute_handler; <br/>}</P> <p> int _ tmain (INT argc, _ tchar * argv []) <br/>{< br/>__ try <br/>{< br/> MessageBox (null, _ T ("Message from '_ try' section"), _ T ("test"), mb_ OK); </P> <p> // division by zero, manual program crash <br/> // <br/> int I = 13; <br/> Int J = 0; <br/> int M = I/J; <br/>}< br/> // capture the dump file created when an exception that causes the program to crash <br/> // <br/>__ handler T (crashhandler (getexceptioninformation () )) <br/>{< br/> // here, a dialog box is displayed as an example <br/> // <br/> MessageBox (null, _ T ("Message from '_ partition t' section"), _ T ("test"), mb_ OK ); <br/>}</P> <p> MessageBox (null, _ T ("funcation completed"), _ T ("test"), mb_ OK ); </P> <p> return 0; <br/>}

Compile and run the above Code. The following dialog box is displayed in sequence, and a dump file test. DMP is created on drive C.

If you change the main () function in the above Code to the following, the compiled program will crash.

View plainprint?
  1. Int_ Tmain (IntArgc, _ tchar * argv [])
  2. {
  3. _ Try
  4. {
  5. MessageBox (null, _ T ("Message from '_ try' section"), _ T ("Test"), Mb_ OK );
  6. // In addition to zero, the program crashes manually
  7. //
  8. IntI = 13;
  9. IntJ = 0;
  10. IntM = I/J;
  11. }
  12. // Create a dump file when an exception that causes the program to crash
  13. //
  14. _ Random t (crashhandler (getexceptioninformation ()))
  15. {
  16. // Here is an example of a pop-up dialog box.
  17. //
  18. MessageBox (null, _ T ("Message from '_ partition t' section"), _ T ("Test"), Mb_ OK );
  19. }
  20. // In addition to zero, the program crashes manually
  21. //
  22. IntI = 13;
  23. IntJ = 0;
  24. IntM = I/J;
  25. MessageBox (null, _ T ("Funcation completed"), _ T ("Test"), Mb_ OK );
  26. Return0;
  27. }

int _ tmain (INT argc, _ tchar * argv []) <br/>{< br/>__ try <br/>{< br/> MessageBox (null, _ T ("Message from '_ try' section "), _ T ("test"), mb_ OK); </P> <p> // division by zero, manual program crash <br/> // <br/> int I = 13; <br/> Int J = 0; <br/> int M = I/J; <br/>}< br/> // capture the dump file created when an exception that causes the program to crash <br/> // <br/>__ handler T (crashhandler (getexceptioninformation () )) <br/>{< br/> // here, a dialog box is displayed as an example <br/> // <br/> MessageBox (null, _ T ("Message from '_ partition t' section"), _ T ("test"), mb_ OK ); <br/>}</P> <p> // The program crashes manually after division by zero. <br/> // <br/> int I = 13; <br/> Int J = 0; <br/> int M = I/J; </P> <p> MessageBox (null, _ T ("funcation completed "), _ T ("test"), mb_ OK); </P> <p> return 0; <br/>}

This situation is very likely to occur in actual programming. After all, we cannot predict all possible causes of program crash in advance and put the code into try/retry t blocks. So what should we do with these unpredictable exceptions? This will use the method in my unhandled exception that causes a program to exit in a decent way when it crashes: Use setunhandledexceptionfilter in the Windows API to set a callback function to handle these unexpected exceptions. The following is the modified Code in the above example code. The createdumpfile function does not change.

View plainprint?
  1. // Obtain the current time
  2. //
  3. Wstring getpresenttime ()
  4. {
  5. Systemtime time;
  6. Getlocaltime (& time );
  7. Wchar_tWsztime [128];
  8. Swprintf_s (wsztime, _ T ("% 04d-% 02d-% 02d % 02d-% 02d-% 02d-% 03d"), Time. wyear, time. wmonth, time. wday, time. whour, time. wminute, time. wsecond, time. wmilliseconds );
  9. ReturnWstring (wsztime );
  10. }
  11. // Callback function for Exception Handling
  12. //
  13. LongCrashhandler (exception_pointers * pexception)
  14. {
  15. // Add the code for handling program crashes here
  16. //
  17. // Here is an example of a pop-up dialog box.
  18. //
  19. MessageBox (null, _ T ("Message from catch handler"), _ T ("Test"), Mb_ OK );
  20. // Use the current time as the file name
  21. //
  22. Wstring strdumpfilename = _ T ("C: \") + getpresenttime () + _ T (". Dmp ");
  23. // Create a dump file
  24. //
  25. Createdumpfile (strdumpfilename. Data (), pexception );
  26. ReturnPrediction_execute_handler;
  27. }
  28. Int_ Tmain (IntArgc, _ tchar * argv [])
  29. {
  30. // Set the callback function for processing unhandled exception
  31. //
  32. Setunhandledexceptionfilter (lptop_level_exception_filter) crashhandler );
  33. _ Try
  34. {
  35. MessageBox (null, _ T ("Message from '_ try' section"), _ T ("Test"), Mb_ OK );
  36. // In addition to zero, the program crashes manually
  37. //
  38. IntI = 13;
  39. IntJ = 0;
  40. IntM = I/J;
  41. }
  42. _ Random t (crashhandler (getexceptioninformation ()))
  43. {
  44. // Add the code for handling program crashes here
  45. //
  46. // Here is an example of a pop-up dialog box.
  47. //
  48. MessageBox (null, _ T ("Message from '_ partition t' section"), _ T ("Test"), Mb_ OK );
  49. }
  50. // In addition to zero, the program crashes manually
  51. //
  52. IntI = 13;
  53. IntJ = 0;
  54. IntM = I/J;
  55. MessageBox (null, _ T ("Funcation completed"), _ T ("Test"), Mb_ OK );
  56. Return0;
  57. }

// <Br/> obtain the current time <br/> // <br/> wstring getpresenttime () <br/>{< br/> systemtime time; <br/> getlocaltime (& time); </P> <p> wchar_t wsztime [128]; <br/> swprintf_s (wsztime, _ T ("% 04d-% 02d-% 02d % 02d-% 02d-% 02d-% 03d"), <br/> time. wyear, time. wmonth, time. wday, time. whour, time. wminute, <br/> time. wsecond, time. wmilliseconds); </P> <p> return wstring (wsztime ); <br/>}</P> <p> // callback function for exception handling <br/> // <br/> long crashhandler (exception_pointers * pexception) <br/>{< br/> // Add the code for handling program crashes here <br/> // </P> <p> // a dialog box is displayed. for example <br/> // <br/> MessageBox (null, _ T ("Message from catch handler"), _ T ("test"), mb_ OK ); </P> <p> // use the current time as the file name <br/> // <br/> wstring strdumpfilename = _ T ("C :\\") + getpresenttime () + _ T (". DMP "); </P> <p> // create a dump file <br/> // <br/> createdumpfile (strdumpfilename. data (), pexception); </P> <p> return exception_execute_handler; <br/>}</P> <p> int _ tmain (INT argc, _ tchar * argv []) <br/>{< br/> // set the callback function for processing unhandled exception <br/> // </P> <p> setunhandledexceptionfilter (lptop_level_exception_filter) crashhandler ); </P> <p >__ try <br/> {<br/> MessageBox (null, _ T ("Message from '_ try' section "), _ T ("test"), <br/> mb_ OK); </P> <p> // division by zero, manual program crash <br/> // <br/> int I = 13; <br/> Int J = 0; <br/> int M = I/J; <br/>}< br/>__ handle T (crashhandler (getexceptioninformation ())) <br/>{< br/> // Add the code for handling program crashes here <br/> // </P> <p> // a dialog box is displayed. for example <br/> // <br/> MessageBox (null, _ T ("Message from '_ partition t' section"), _ T ("test"), <br/> mb_ OK ); <br/>}</P> <p> // The program crashes manually after division by zero. <br/> // <br/> int I = 13; <br/> Int J = 0; <br/> int M = I/J; </P> <p> MessageBox (null, _ T ("funcation completed "), _ T ("test"), mb_ OK); </P> <p> return 0; <br/>}

Compile the above Code and run the generated EXE file. You can see that the program Exits normally after the series of dialogs mentioned above are popped up. At the same time, two dump files are generated under drive C, and the file name indicates the time when an exception occurs.


The above code is only to illustrate how to use seh and setunhandledexceptionfilter together, so the expressions after the limit T and
The callback function set in setunhandledexceptionfilter uses the same function crashhandler. In actual applications
Use different functions as required. The parameter of this function must be a pointer to prediction_pointers, and the returned value must be one of the three
Nodes: prediction_continue_search, prediction_continue_execution, and prediction_execute_handler.
For the specific meanings of these three values, refer to msdn or my article "seh for decent exit when a program crashes".

In practice, the same callback function should not be used. Because the function in the limit t expression is used to handle code exceptions in the try block.
The callback function set by setunhandledexceptionfilter is used to handle exceptions that are not captured in the code. For exceptions that are not captured, this callback function is not
If you know where an exception occurs, you can know the exception type through the Exception Code, but you cannot handle the exception because you do not know what the exception is. Generally, this callback function
Number is the last line of defense before the application crashes. After the code in this function is executed, the application will be terminated. Therefore, in most applications, an error report is displayed in this function.
Dialog Box to tell the user that the program has an exception and needs to be terminated. You can send the error report (usually including the dump file and some necessary text information) to a specified place to help developers modify code defects
Improve software quality.

the application compiled using the preceding method will not crash and a dump file will be generated when an exception occurs. Program users will have a very good user experience. If you add log information to the application and use the dump file together, you can easily locate exceptions in the application and help developers quickly fix errors in the code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.