| 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 |