| Index: components/browser_watcher/stability_debugging.cc
|
| diff --git a/components/browser_watcher/stability_debugging.cc b/components/browser_watcher/stability_debugging.cc
|
| index 3c8cc6492928043dbe0de2306bef4581e992e044..aee484c8506d9497e4819ba2da20f05f5199914a 100644
|
| --- a/components/browser_watcher/stability_debugging.cc
|
| +++ b/components/browser_watcher/stability_debugging.cc
|
| @@ -4,10 +4,48 @@
|
|
|
| #include "components/browser_watcher/stability_debugging.h"
|
|
|
| +#include <windows.h>
|
| +
|
| +#include <memory>
|
| +
|
| #include "base/debug/activity_tracker.h"
|
| +#include "build/build_config.h"
|
|
|
| namespace browser_watcher {
|
|
|
| +namespace {
|
| +
|
| +struct VehUnregisterer {
|
| + void operator()(void* handle) const {
|
| + ::RemoveVectoredExceptionHandler(handle);
|
| + }
|
| +};
|
| +
|
| +using VehHandle = std::unique_ptr<void, VehUnregisterer>;
|
| +
|
| +uintptr_t GetProgramCounter(const CONTEXT& context) {
|
| +#if defined(ARCH_CPU_X86)
|
| + return context.Eip;
|
| +#elif defined(ARCH_CPU_X86_64)
|
| + return context.Rip;
|
| +#endif
|
| +}
|
| +
|
| +LONG CALLBACK VectoredExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
|
| + base::debug::GlobalActivityTracker* tracker =
|
| + base::debug::GlobalActivityTracker::Get();
|
| + if (tracker) {
|
| + EXCEPTION_RECORD* record = exception_pointers->ExceptionRecord;
|
| + uintptr_t pc = GetProgramCounter(*exception_pointers->ContextRecord);
|
| + tracker->RecordException(reinterpret_cast<void*>(pc),
|
| + record->ExceptionAddress, record->ExceptionCode);
|
| + }
|
| +
|
| + return EXCEPTION_CONTINUE_SEARCH; // Continue to the next handler.
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| void SetStabilityDataBool(base::StringPiece name, bool value) {
|
| base::debug::GlobalActivityTracker* global_tracker =
|
| base::debug::GlobalActivityTracker::Get();
|
| @@ -26,4 +64,16 @@ void SetStabilityDataInt(base::StringPiece name, int64_t value) {
|
| global_tracker->process_data().SetInt(name, value);
|
| }
|
|
|
| +void RegisterStabilityVEH() {
|
| + // Register a vectored exception handler and request it be first. Note that
|
| + // subsequent registrations may also request to be first, in which case this
|
| + // one will be bumped.
|
| + // TODO(manzagop): Depending on observations, it may be necessary to
|
| + // consider refreshing the registration, either periodically or at opportune
|
| + // (e.g. risky) times.
|
| + static VehHandle veh_handler(
|
| + ::AddVectoredExceptionHandler(1, &VectoredExceptionHandler));
|
| + DCHECK(veh_handler);
|
| +}
|
| +
|
| } // namespace browser_watcher
|
|
|