blob: f6ac8713d7808f43daad505e9db46c31cc6bced8 [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;
31#endif
32}
33
34LONG CALLBACK VectoredExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
35 base::debug::GlobalActivityTracker* tracker =
36 base::debug::GlobalActivityTracker::Get();
37 if (tracker) {
38 EXCEPTION_RECORD* record = exception_pointers->ExceptionRecord;
39 uintptr_t pc = GetProgramCounter(*exception_pointers->ContextRecord);
40 tracker->RecordException(reinterpret_cast<void*>(pc),
41 record->ExceptionAddress, record->ExceptionCode);
42 }
43
44 return EXCEPTION_CONTINUE_SEARCH; // Continue to the next handler.
45}
46
47} // namespace
48
manzagopba8991e2017-05-08 21:05:2149void SetStabilityDataBool(base::StringPiece name, bool value) {
50 base::debug::GlobalActivityTracker* global_tracker =
51 base::debug::GlobalActivityTracker::Get();
52 if (!global_tracker)
53 return; // Activity tracking isn't enabled.
54
55 global_tracker->process_data().SetBool(name, value);
56}
57
manzagop6d149912016-12-19 20:17:0958void SetStabilityDataInt(base::StringPiece name, int64_t value) {
59 base::debug::GlobalActivityTracker* global_tracker =
60 base::debug::GlobalActivityTracker::Get();
61 if (!global_tracker)
62 return; // Activity tracking isn't enabled.
63
bcwhite8ffd3902017-04-11 17:10:4964 global_tracker->process_data().SetInt(name, value);
manzagop6d149912016-12-19 20:17:0965}
manzagop14aff5d2016-11-23 17:27:0066
manzagope17e32d2017-06-14 20:51:2767void RegisterStabilityVEH() {
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:5168#if defined(ADDRESS_SANITIZER)
Etienne Bergeron5f4de1c2017-11-21 20:08:5669 // ASAN on windows x64 is dynamically allocating the shadow memory on a
70 // memory access violation by setting up an vector exception handler.
71 // When instrumented with ASAN, this code may trigger an exception by
72 // accessing unallocated shadow memory, which is causing an infinite
73 // recursion (i.e. infinite memory access violation).
74 (void)&VectoredExceptionHandler;
75#else
manzagope17e32d2017-06-14 20:51:2776 // Register a vectored exception handler and request it be first. Note that
77 // subsequent registrations may also request to be first, in which case this
78 // one will be bumped.
79 // TODO(manzagop): Depending on observations, it may be necessary to
80 // consider refreshing the registration, either periodically or at opportune
81 // (e.g. risky) times.
82 static VehHandle veh_handler(
83 ::AddVectoredExceptionHandler(1, &VectoredExceptionHandler));
84 DCHECK(veh_handler);
Etienne Bergeron5f4de1c2017-11-21 20:08:5685#endif // ADDRESS_SANITIZER
manzagope17e32d2017-06-14 20:51:2786}
87
manzagopf2322662016-09-27 11:39:5988} // namespace browser_watcher