OLD | NEW |
1 // Copyright (c) 2006, Google Inc. | 1 // Copyright (c) 2006, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 | 483 |
484 // Make up an exception record for the current thread and CPU context | 484 // Make up an exception record for the current thread and CPU context |
485 // to make it possible for the crash processor to classify these | 485 // to make it possible for the crash processor to classify these |
486 // as do regular crashes, and to make it humane for developers to | 486 // as do regular crashes, and to make it humane for developers to |
487 // analyze them. | 487 // analyze them. |
488 EXCEPTION_RECORD exception_record = {}; | 488 EXCEPTION_RECORD exception_record = {}; |
489 CONTEXT exception_context = {}; | 489 CONTEXT exception_context = {}; |
490 EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; | 490 EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; |
491 RtlCaptureContext(&exception_context); | 491 RtlCaptureContext(&exception_context); |
492 exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; | 492 exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; |
493 | 493 |
494 // We store pointers to the the expression and function strings, | 494 // We store pointers to the the expression and function strings, |
495 // and the line as exception parameters to make them easy to | 495 // and the line as exception parameters to make them easy to |
496 // access by the developer on the far side. | 496 // access by the developer on the far side. |
497 exception_record.NumberParameters = 3; | 497 exception_record.NumberParameters = 3; |
498 exception_record.ExceptionInformation[0] = | 498 exception_record.ExceptionInformation[0] = |
499 reinterpret_cast<ULONG_PTR>(&assertion.expression); | 499 reinterpret_cast<ULONG_PTR>(&assertion.expression); |
500 exception_record.ExceptionInformation[1] = | 500 exception_record.ExceptionInformation[1] = |
501 reinterpret_cast<ULONG_PTR>(&assertion.file); | 501 reinterpret_cast<ULONG_PTR>(&assertion.file); |
502 exception_record.ExceptionInformation[2] = assertion.line; | 502 exception_record.ExceptionInformation[2] = assertion.line; |
503 | 503 |
504 bool success = false; | 504 bool success = false; |
505 // In case of out-of-process dump generation, directly call | 505 // In case of out-of-process dump generation, directly call |
506 // WriteMinidumpWithException since there is no separate thread running. | 506 // WriteMinidumpWithException since there is no separate thread running. |
507 if (current_handler->IsOutOfProcess()) { | 507 if (current_handler->IsOutOfProcess()) { |
508 success = current_handler->WriteMinidumpWithException( | 508 success = current_handler->WriteMinidumpWithException( |
509 GetCurrentThreadId(), | 509 GetCurrentThreadId(), |
510 &exception_ptrs, | 510 &exception_ptrs, |
511 &assertion); | 511 &assertion); |
512 } else { | 512 } else { |
513 success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, | 513 success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, |
514 &assertion); | 514 &assertion); |
515 } | 515 } |
516 | 516 |
517 if (!success) { | 517 if (!success) { |
518 if (current_handler->previous_iph_) { | 518 if (current_handler->previous_iph_) { |
519 // The handler didn't fully handle the exception. Give it to the | 519 // The handler didn't fully handle the exception. Give it to the |
520 // previous invalid parameter handler. | 520 // previous invalid parameter handler. |
521 current_handler->previous_iph_(expression, | 521 current_handler->previous_iph_(expression, |
522 function, | 522 function, |
523 file, | 523 file, |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 // was called as a result of an exception, returning false will cause | 661 // was called as a result of an exception, returning false will cause |
662 // HandleException to call any previous handler or return | 662 // HandleException to call any previous handler or return |
663 // EXCEPTION_CONTINUE_SEARCH on the exception thread, allowing it to appear | 663 // EXCEPTION_CONTINUE_SEARCH on the exception thread, allowing it to appear |
664 // as though this handler were not present at all. | 664 // as though this handler were not present at all. |
665 if (filter_ && !filter_(callback_context_, exinfo, assertion)) { | 665 if (filter_ && !filter_(callback_context_, exinfo, assertion)) { |
666 return false; | 666 return false; |
667 } | 667 } |
668 | 668 |
669 bool success = false; | 669 bool success = false; |
670 if (IsOutOfProcess()) { | 670 if (IsOutOfProcess()) { |
671 // Use the EXCEPTION_POINTERS overload for RequestDump if | 671 success = crash_generation_client_->RequestDump(exinfo, assertion); |
672 // both exinfo and assertion are NULL. | |
673 if (!assertion) { | |
674 success = crash_generation_client_->RequestDump(exinfo); | |
675 } else { | |
676 success = crash_generation_client_->RequestDump(assertion); | |
677 } | |
678 } else { | 672 } else { |
679 if (minidump_write_dump_) { | 673 if (minidump_write_dump_) { |
680 HANDLE dump_file = CreateFile(next_minidump_path_c_, | 674 HANDLE dump_file = CreateFile(next_minidump_path_c_, |
681 GENERIC_WRITE, | 675 GENERIC_WRITE, |
682 0, // no sharing | 676 0, // no sharing |
683 NULL, | 677 NULL, |
684 CREATE_NEW, // fail if exists | 678 CREATE_NEW, // fail if exists |
685 FILE_ATTRIBUTE_NORMAL, | 679 FILE_ATTRIBUTE_NORMAL, |
686 NULL); | 680 NULL); |
687 if (dump_file != INVALID_HANDLE_VALUE) { | 681 if (dump_file != INVALID_HANDLE_VALUE) { |
688 MINIDUMP_EXCEPTION_INFORMATION except_info; | 682 MINIDUMP_EXCEPTION_INFORMATION except_info; |
689 except_info.ThreadId = requesting_thread_id; | 683 except_info.ThreadId = requesting_thread_id; |
690 except_info.ExceptionPointers = exinfo; | 684 except_info.ExceptionPointers = exinfo; |
691 except_info.ClientPointers = FALSE; | 685 except_info.ClientPointers = FALSE; |
692 | 686 |
693 // Add an MDRawBreakpadInfo stream to the minidump, to provide additiona
l | 687 // Add an MDRawBreakpadInfo stream to the minidump, to provide |
694 // information about the exception handler to the Breakpad processor. T
he | 688 // additional information about the exception handler to the Breakpad |
695 // information will help the processor determine which threads are | 689 // processor. The information will help the processor determine which |
696 // relevant. The Breakpad processor does not require this information b
ut | 690 // threads are relevant. The Breakpad processor does not require this |
697 // can function better with Breakpad-generated dumps when it is present. | 691 // information but can function better with Breakpad-generated dumps |
698 // The native debugger is not harmed by the presence of this information
. | 692 // when it is present. The native debugger is not harmed by the |
| 693 // presence of this information. |
699 MDRawBreakpadInfo breakpad_info; | 694 MDRawBreakpadInfo breakpad_info; |
700 breakpad_info.validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID | | 695 breakpad_info.validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID | |
701 MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID; | 696 MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID; |
702 breakpad_info.dump_thread_id = GetCurrentThreadId(); | 697 breakpad_info.dump_thread_id = GetCurrentThreadId(); |
703 breakpad_info.requesting_thread_id = requesting_thread_id; | 698 breakpad_info.requesting_thread_id = requesting_thread_id; |
704 | 699 |
705 // Leave room in user_stream_array for a possible assertion info stream. | 700 // Leave room in user_stream_array for a possible assertion info stream. |
706 MINIDUMP_USER_STREAM user_stream_array[2]; | 701 MINIDUMP_USER_STREAM user_stream_array[2]; |
707 user_stream_array[0].Type = MD_BREAKPAD_INFO_STREAM; | 702 user_stream_array[0].Type = MD_BREAKPAD_INFO_STREAM; |
708 user_stream_array[0].BufferSize = sizeof(breakpad_info); | 703 user_stream_array[0].BufferSize = sizeof(breakpad_info); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 dump_path_c_, next_minidump_id_c_); | 754 dump_path_c_, next_minidump_id_c_); |
760 | 755 |
761 // remove when VC++7.1 is no longer supported | 756 // remove when VC++7.1 is no longer supported |
762 minidump_path[MAX_PATH - 1] = L'\0'; | 757 minidump_path[MAX_PATH - 1] = L'\0'; |
763 | 758 |
764 next_minidump_path_ = minidump_path; | 759 next_minidump_path_ = minidump_path; |
765 next_minidump_path_c_ = next_minidump_path_.c_str(); | 760 next_minidump_path_c_ = next_minidump_path_.c_str(); |
766 } | 761 } |
767 | 762 |
768 } // namespace google_breakpad | 763 } // namespace google_breakpad |
OLD | NEW |