blob: 7cfa64c92751ee931cc1f2263dd104a7805e1c84 [file] [log] [blame]
manzagopf2322662016-09-27 11:39:591// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
manzagop6d149912016-12-19 20:17:095#include "components/browser_watcher/stability_debugging.h"
manzagopf2322662016-09-27 11:39:596
manzagope17e32d2017-06-14 20:51:277#include <windows.h>
8
9#include <memory>
10
manzagop6d149912016-12-19 20:17:0911#include "base/debug/activity_tracker.h"
manzagope17e32d2017-06-14 20:51:2712#include "build/build_config.h"
manzagopf2322662016-09-27 11:39:5913
14namespace browser_watcher {
15
manzagope17e32d2017-06-14 20:51:2716namespace {
17
18struct VehUnregisterer {
19 void operator()(void* handle) const {
20 ::RemoveVectoredExceptionHandler(handle);
21 }
22};
23
24using VehHandle = std::unique_ptr<void, VehUnregisterer>;
25
26uintptr_t GetProgramCounter(const CONTEXT& context) {
27#if defined(ARCH_CPU_X86)
28 return context.Eip;
29#elif defined(ARCH_CPU_X86_64)
30 return context.Rip;
Tom Tanab224ff2018-11-13 17:51:4231#elif defined(ARCH_CPU_ARM64)
32 return context.Pc;
manzagope17e32d2017-06-14 20:51:2733#endif
34}
35
36LONG CALLBACK VectoredExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
37 base::debug::GlobalActivityTracker* tracker =
38 base::debug::GlobalActivityTracker::Get();
39 if (tracker) {
40 EXCEPTION_RECORD* record = exception_pointers->ExceptionRecord;
41 uintptr_t pc = GetProgramCounter(*exception_pointers->ContextRecord);
42 tracker->RecordException(reinterpret_cast<void*>(pc),
43 record->ExceptionAddress, record->ExceptionCode);
44 }
45
46 return EXCEPTION_CONTINUE_SEARCH; // Continue to the next handler.
47}
48
49} // namespace
50
manzagopba8991e2017-05-08 21:05:2151void SetStabilityDataBool(base::StringPiece name, bool value) {
52 base::debug::GlobalActivityTracker* global_tracker =
53 base::debug::GlobalActivityTracker::Get();
54 if (!global_tracker)
55 return; // Activity tracking isn't enabled.
56
57 global_tracker->process_data().SetBool(name, value);
58}
59
manzagop6d149912016-12-19 20:17:0960void SetStabilityDataInt(base::StringPiece name, int64_t value) {
61 base::debug::GlobalActivityTracker* global_tracker =
62 base::debug::GlobalActivityTracker::Get();
63 if (!global_tracker)
64 return; // Activity tracking isn't enabled.
65
bcwhite8ffd3902017-04-11 17:10:4966 global_tracker->process_data().SetInt(name, value);
manzagop6d149912016-12-19 20:17:0967}
manzagop14aff5d2016-11-23 17:27:0068
manzagope17e32d2017-06-14 20:51:2769void RegisterStabilityVEH() {
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:5170#if defined(ADDRESS_SANITIZER)
Etienne Bergeron5f4de1c2017-11-21 20:08:5671 // ASAN on windows x64 is dynamically allocating the shadow memory on a
72 // memory access violation by setting up an vector exception handler.
73 // When instrumented with ASAN, this code may trigger an exception by
74 // accessing unallocated shadow memory, which is causing an infinite
75 // recursion (i.e. infinite memory access violation).
76 (void)&VectoredExceptionHandler;
77#else
manzagope17e32d2017-06-14 20:51:2778 // Register a vectored exception handler and request it be first. Note that
79 // subsequent registrations may also request to be first, in which case this
80 // one will be bumped.
81 // TODO(manzagop): Depending on observations, it may be necessary to
82 // consider refreshing the registration, either periodically or at opportune
83 // (e.g. risky) times.
84 static VehHandle veh_handler(
85 ::AddVectoredExceptionHandler(1, &VectoredExceptionHandler));
86 DCHECK(veh_handler);
Etienne Bergeron5f4de1c2017-11-21 20:08:5687#endif // ADDRESS_SANITIZER
manzagope17e32d2017-06-14 20:51:2788}
89
manzagopf2322662016-09-27 11:39:5990} // namespace browser_watcher