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 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 | 543 |
544 // The handler either took care of the invalid parameter problem itself, | 544 // The handler either took care of the invalid parameter problem itself, |
545 // or passed it on to another handler. "Swallow" it by exiting, paralleling | 545 // or passed it on to another handler. "Swallow" it by exiting, paralleling |
546 // the behavior of "swallowing" exceptions. | 546 // the behavior of "swallowing" exceptions. |
547 exit(0); | 547 exit(0); |
548 } | 548 } |
549 #endif // _MSC_VER >= 1400 | 549 #endif // _MSC_VER >= 1400 |
550 | 550 |
551 // static | 551 // static |
552 void ExceptionHandler::HandlePureVirtualCall() { | 552 void ExceptionHandler::HandlePureVirtualCall() { |
| 553 // This is an pure virtual funciton call, not an exception. It's safe to |
| 554 // play with sprintf here. |
553 AutoExceptionHandler auto_exception_handler; | 555 AutoExceptionHandler auto_exception_handler; |
554 ExceptionHandler* current_handler = auto_exception_handler.get_handler(); | 556 ExceptionHandler* current_handler = auto_exception_handler.get_handler(); |
555 | 557 |
556 MDRawAssertionInfo assertion; | 558 MDRawAssertionInfo assertion; |
557 memset(&assertion, 0, sizeof(assertion)); | 559 memset(&assertion, 0, sizeof(assertion)); |
558 assertion.type = MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL; | 560 assertion.type = MD_ASSERTION_INFO_TYPE_PURE_VIRTUAL_CALL; |
559 | 561 |
| 562 // Make up an exception record for the current thread and CPU context |
| 563 // to make it possible for the crash processor to classify these |
| 564 // as do regular crashes, and to make it humane for developers to |
| 565 // analyze them. |
| 566 EXCEPTION_RECORD exception_record = {}; |
| 567 CONTEXT exception_context = {}; |
| 568 EXCEPTION_POINTERS exception_ptrs = { &exception_record, &exception_context }; |
| 569 RtlCaptureContext(&exception_context); |
| 570 exception_record.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; |
| 571 |
| 572 // We store pointers to the the expression and function strings, |
| 573 // and the line as exception parameters to make them easy to |
| 574 // access by the developer on the far side. |
| 575 exception_record.NumberParameters = 3; |
| 576 exception_record.ExceptionInformation[0] = |
| 577 reinterpret_cast<ULONG_PTR>(&assertion.expression); |
| 578 exception_record.ExceptionInformation[1] = |
| 579 reinterpret_cast<ULONG_PTR>(&assertion.file); |
| 580 exception_record.ExceptionInformation[2] = assertion.line; |
| 581 |
560 bool success = false; | 582 bool success = false; |
561 // In case of out-of-process dump generation, directly call | 583 // In case of out-of-process dump generation, directly call |
562 // WriteMinidumpWithException since there is no separate thread running. | 584 // WriteMinidumpWithException since there is no separate thread running. |
563 | 585 |
564 if (current_handler->IsOutOfProcess()) { | 586 if (current_handler->IsOutOfProcess()) { |
565 success = current_handler->WriteMinidumpWithException( | 587 success = current_handler->WriteMinidumpWithException( |
566 GetCurrentThreadId(), | 588 GetCurrentThreadId(), |
567 NULL, | 589 &exception_ptrs, |
568 &assertion); | 590 &assertion); |
569 } else { | 591 } else { |
570 success = current_handler->WriteMinidumpOnHandlerThread(NULL, &assertion); | 592 success = current_handler->WriteMinidumpOnHandlerThread(&exception_ptrs, |
| 593 &assertion); |
571 } | 594 } |
572 | 595 |
573 if (!success) { | 596 if (!success) { |
574 if (current_handler->previous_pch_) { | 597 if (current_handler->previous_pch_) { |
575 // The handler didn't fully handle the exception. Give it to the | 598 // The handler didn't fully handle the exception. Give it to the |
576 // previous purecall handler. | 599 // previous purecall handler. |
577 current_handler->previous_pch_(); | 600 current_handler->previous_pch_(); |
578 } else { | 601 } else { |
579 // If there's no previous handler, return and let _purecall handle it. | 602 // If there's no previous handler, return and let _purecall handle it. |
580 // This will just put up an assertion dialog. | 603 // This will just put up an assertion dialog. |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 dump_path_c_, next_minidump_id_c_); | 777 dump_path_c_, next_minidump_id_c_); |
755 | 778 |
756 // remove when VC++7.1 is no longer supported | 779 // remove when VC++7.1 is no longer supported |
757 minidump_path[MAX_PATH - 1] = L'\0'; | 780 minidump_path[MAX_PATH - 1] = L'\0'; |
758 | 781 |
759 next_minidump_path_ = minidump_path; | 782 next_minidump_path_ = minidump_path; |
760 next_minidump_path_c_ = next_minidump_path_.c_str(); | 783 next_minidump_path_c_ = next_minidump_path_.c_str(); |
761 } | 784 } |
762 | 785 |
763 } // namespace google_breakpad | 786 } // namespace google_breakpad |
OLD | NEW |