1 : // Copyright 2016 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/agent/asan/reporters/breakpad_reporter.h"
16 :
17 : #include "base/strings/utf_string_conversions.h"
18 :
19 : namespace agent {
20 : namespace asan {
21 :
22 : // Define required export names.
23 : const char* reporters::BreakpadReporter::CrashForException::name_ =
24 : "CrashForException";
25 : const char* reporters::BreakpadReporter::SetCrashKeyValuePair::name_ =
26 : "SetCrashKeyValuePair";
27 : const char* reporters::BreakpadReporter:: SetCrashKeyValueImpl::name_ =
28 : "SetCrashKeyValueImpl";
29 :
30 : namespace reporters {
31 :
32 : // static
33 E : std::unique_ptr<BreakpadReporter> BreakpadReporter::Create() {
34 : // Initialize the required reporter functions
35 E : BreakpadFunctions breakpad_functions;
36 E : breakpad_functions.crash_for_exception.Lookup();
37 E : breakpad_functions.set_crash_key_value_pair.Lookup();
38 E : breakpad_functions.set_crash_key_value_impl.Lookup();
39 E : if (!AreValid(breakpad_functions))
40 E : return nullptr;
41 :
42 E : return std::unique_ptr<BreakpadReporter>(
43 : new BreakpadReporter(breakpad_functions));
44 E : }
45 :
46 : // static
47 E : bool BreakpadReporter::AreValid(const BreakpadFunctions& breakpad_functions) {
48 : // The crash function and exactly one crash key reporting function must be
49 : // present.
50 E : if (!breakpad_functions.crash_for_exception.IsValid())
51 E : return false;
52 E : if (breakpad_functions.set_crash_key_value_pair.IsValid() ==
53 : breakpad_functions.set_crash_key_value_impl.IsValid()) {
54 E : return false;
55 : }
56 E : return true;
57 E : }
58 :
59 E : const char* BreakpadReporter::GetName() const {
60 E : return "BreakpadReporter";
61 E : }
62 :
63 E : uint32_t BreakpadReporter::GetFeatures() const {
64 E : return FEATURE_CRASH_KEYS;
65 E : }
66 :
67 : bool BreakpadReporter::SetCrashKey(base::StringPiece key,
68 E : base::StringPiece value) {
69 : // Only one of the functions should be set.
70 E : DCHECK_NE(breakpad_functions_.set_crash_key_value_pair.IsValid(),
71 E : breakpad_functions_.set_crash_key_value_impl.IsValid());
72 :
73 : // The 'Impl' variant is the more recent of the two, so check it first.
74 E : if (breakpad_functions_.set_crash_key_value_impl.IsValid()) {
75 E : std::wstring wkey = base::UTF8ToWide(key);
76 E : std::wstring wvalue = base::UTF8ToWide(value);
77 E : breakpad_functions_.set_crash_key_value_impl.Run(
78 : wkey.c_str(), wvalue.c_str());
79 E : } else {
80 E : DCHECK(breakpad_functions_.set_crash_key_value_pair.IsValid());
81 : // StringPiece objects aren't necessarily null terminated, so copy them to
82 : // strings to be sure they'll be terminated properly.
83 E : std::string skey(key.as_string());
84 E : std::string svalue(value.as_string());
85 E : breakpad_functions_.set_crash_key_value_pair.Run(
86 : skey.c_str(), svalue.c_str());
87 E : }
88 E : return true;
89 E : }
90 :
91 E : bool BreakpadReporter::SetMemoryRanges(const MemoryRanges& memory_ranges) {
92 : // Unsupported.
93 E : return false;
94 E : }
95 :
96 : bool BreakpadReporter::SetCustomStream(uint32_t stream_type,
97 : const uint8_t* stream_data,
98 E : size_t stream_length) {
99 : // Unsupported.
100 E : return false;
101 E : }
102 :
103 : // Crashes the running process and sends a crash report.
104 E : void BreakpadReporter::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) {
105 E : DCHECK(breakpad_functions_.crash_for_exception.IsValid());
106 E : breakpad_functions_.crash_for_exception.Run(exception_pointers);
107 :
108 : // The crash function shouldn't return, but putting a NOTREACHED here makes
109 : // this function difficult to test.
110 E : }
111 :
112 E : bool BreakpadReporter::DumpWithoutCrash(const CONTEXT& context) {
113 : // Unsupported.
114 E : return false;
115 E : }
116 :
117 : } // namespace reporters
118 : } // namespace asan
119 : } // namespace agent
|