Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: components/browser_watcher/stability_report_extractor_unittest.cc

Issue 2927653003: Stability instrumentation: add a Vectored Exception Handler (Closed)
Patch Set: merge Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/browser_watcher/stability_report_extractor.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/browser_watcher/stability_report_extractor.h" 5 #include "components/browser_watcher/stability_report_extractor.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/debug/activity_tracker.h" 10 #include "base/debug/activity_tracker.h"
11 #include "base/files/file.h" 11 #include "base/files/file.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/files/memory_mapped_file.h" 13 #include "base/files/memory_mapped_file.h"
14 #include "base/files/scoped_temp_dir.h" 14 #include "base/files/scoped_temp_dir.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/metrics/persistent_memory_allocator.h" 16 #include "base/metrics/persistent_memory_allocator.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/time/time.h"
18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/crashpad/crashpad/client/crash_report_database.h" 20 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
20 21
21 namespace browser_watcher { 22 namespace browser_watcher {
22 23
23 using base::debug::ActivityData; 24 using base::debug::ActivityData;
24 using base::debug::ActivityTrackerMemoryAllocator; 25 using base::debug::ActivityTrackerMemoryAllocator;
25 using base::debug::ActivityUserData; 26 using base::debug::ActivityUserData;
26 using base::debug::GlobalActivityTracker; 27 using base::debug::GlobalActivityTracker;
27 using base::debug::ThreadActivityTracker; 28 using base::debug::ThreadActivityTracker;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 PersistentMemoryAllocator::kSizeAny); 113 PersistentMemoryAllocator::kSizeAny);
113 if (mem_base == nullptr) 114 if (mem_base == nullptr)
114 return nullptr; 115 return nullptr;
115 116
116 // Make the allocation iterable so it can be found by other processes. 117 // Make the allocation iterable so it can be found by other processes.
117 allocator->MakeIterable(mem_reference); 118 allocator->MakeIterable(mem_reference);
118 119
119 return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size)); 120 return WrapUnique(new ThreadActivityTracker(mem_base, tracker_mem_size));
120 } 121 }
121 122
123 void PerformBasicReportValidation(const StabilityReport& report) {
124 // One report with one thread that has the expected name and id.
125 ASSERT_EQ(1, report.process_states_size());
126 const ProcessState& process_state = report.process_states(0);
127 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id());
128 ASSERT_EQ(1, process_state.threads_size());
129 const ThreadState& thread_state = process_state.threads(0);
130 EXPECT_EQ(base::PlatformThread::GetName(), thread_state.thread_name());
131 #if defined(OS_WIN)
132 EXPECT_EQ(base::PlatformThread::CurrentId(), thread_state.thread_id());
133 #elif defined(OS_POSIX)
134 EXPECT_EQ(base::PlatformThread::CurrentHandle().platform_handle(),
135 thread_state.thread_id());
136 #endif
137 }
138
122 const FilePath& debug_file_path() const { return debug_file_path_; } 139 const FilePath& debug_file_path() const { return debug_file_path_; }
123 140
124 protected: 141 protected:
125 base::ScopedTempDir temp_dir_; 142 base::ScopedTempDir temp_dir_;
126 FilePath debug_file_path_; 143 FilePath debug_file_path_;
127 144
128 std::unique_ptr<PersistentMemoryAllocator> allocator_; 145 std::unique_ptr<PersistentMemoryAllocator> allocator_;
129 std::unique_ptr<ThreadActivityTracker> tracker_; 146 std::unique_ptr<ThreadActivityTracker> tracker_;
130 }; 147 };
131 148
(...skipping 24 matching lines...) Expand all
156 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false); 173 GlobalActivityTracker::kTypeIdUserDataRecordFree, 1024U, 10U, false);
157 std::unique_ptr<ActivityUserData> user_data = 174 std::unique_ptr<ActivityUserData> user_data =
158 tracker_->GetUserData(activity_id, &user_data_allocator); 175 tracker_->GetUserData(activity_id, &user_data_allocator);
159 user_data->SetInt("some_int", 42); 176 user_data->SetInt("some_int", 42);
160 177
161 // Validate collection returns the expected report. 178 // Validate collection returns the expected report.
162 StabilityReport report; 179 StabilityReport report;
163 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report)); 180 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report));
164 181
165 // Validate the report. 182 // Validate the report.
166 ASSERT_EQ(1, report.process_states_size()); 183 ASSERT_NO_FATAL_FAILURE(PerformBasicReportValidation(report));
167 const ProcessState& process_state = report.process_states(0); 184 const ThreadState& thread_state = report.process_states(0).threads(0);
168 EXPECT_EQ(base::GetCurrentProcId(), process_state.process_id());
169 ASSERT_EQ(1, process_state.threads_size());
170
171 const ThreadState& thread_state = process_state.threads(0);
172 EXPECT_EQ(base::PlatformThread::GetName(), thread_state.thread_name());
173 #if defined(OS_WIN)
174 EXPECT_EQ(base::PlatformThread::CurrentId(), thread_state.thread_id());
175 #elif defined(OS_POSIX)
176 EXPECT_EQ(base::PlatformThread::CurrentHandle().platform_handle(),
177 thread_state.thread_id());
178 #endif
179 185
180 EXPECT_EQ(7, thread_state.activity_count()); 186 EXPECT_EQ(7, thread_state.activity_count());
181 ASSERT_EQ(6, thread_state.activities_size()); 187 ASSERT_EQ(6, thread_state.activities_size());
182 { 188 {
183 const Activity& activity = thread_state.activities(0); 189 const Activity& activity = thread_state.activities(0);
184 EXPECT_EQ(Activity::ACT_TASK_RUN, activity.type()); 190 EXPECT_EQ(Activity::ACT_TASK_RUN, activity.type());
185 EXPECT_EQ(kTaskOrigin, activity.origin_address()); 191 EXPECT_EQ(kTaskOrigin, activity.origin_address());
186 EXPECT_EQ(kTaskSequenceNum, activity.task_sequence_id()); 192 EXPECT_EQ(kTaskSequenceNum, activity.task_sequence_id());
187 EXPECT_EQ(0U, activity.user_data().size()); 193 EXPECT_EQ(0U, activity.user_data().size());
188 } 194 }
(...skipping 27 matching lines...) Expand all
216 } 222 }
217 { 223 {
218 const Activity& activity = thread_state.activities(5); 224 const Activity& activity = thread_state.activities(5);
219 EXPECT_EQ(Activity::ACT_GENERIC, activity.type()); 225 EXPECT_EQ(Activity::ACT_GENERIC, activity.type());
220 EXPECT_EQ(kGenericId, activity.generic_id()); 226 EXPECT_EQ(kGenericId, activity.generic_id());
221 EXPECT_EQ(kGenericData, activity.generic_data()); 227 EXPECT_EQ(kGenericData, activity.generic_data());
222 EXPECT_EQ(0U, activity.user_data().size()); 228 EXPECT_EQ(0U, activity.user_data().size());
223 } 229 }
224 } 230 }
225 231
232 TEST_F(StabilityReportExtractorThreadTrackerTest, CollectException) {
233 const void* expected_pc = reinterpret_cast<void*>(0xCAFE);
234 const void* expected_address = nullptr;
235 const uint32_t expected_code = 42U;
236
237 // Record an exception.
238 const int64_t timestamp = base::Time::Now().ToInternalValue();
239 tracker_->RecordExceptionActivity(expected_pc, expected_address,
240 base::debug::Activity::ACT_EXCEPTION,
241 ActivityData::ForException(expected_code));
242
243 // Collect report and validate.
244 StabilityReport report;
245 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report));
246
247 // Validate the presence of the exception.
248 ASSERT_NO_FATAL_FAILURE(PerformBasicReportValidation(report));
249 const ThreadState& thread_state = report.process_states(0).threads(0);
250 ASSERT_TRUE(thread_state.has_exception());
251 const Exception& exception = thread_state.exception();
252 EXPECT_EQ(expected_code, exception.code());
253 EXPECT_EQ(expected_pc, reinterpret_cast<void*>(exception.program_counter()));
254 EXPECT_EQ(expected_address,
255 reinterpret_cast<void*>(exception.exception_address()));
256 const int64_t tolerance_us = 1000ULL;
257 EXPECT_LE(std::abs(timestamp - exception.time()), tolerance_us);
258 }
259
260 TEST_F(StabilityReportExtractorThreadTrackerTest, CollectNoException) {
261 // Record something.
262 tracker_->PushActivity(reinterpret_cast<void*>(kTaskOrigin),
263 base::debug::Activity::ACT_TASK_RUN,
264 ActivityData::ForTask(kTaskSequenceNum));
265
266 // Collect report and validate there is no exception.
267 StabilityReport report;
268 ASSERT_EQ(SUCCESS, Extract(debug_file_path(), &report));
269 ASSERT_NO_FATAL_FAILURE(PerformBasicReportValidation(report));
270 const ThreadState& thread_state = report.process_states(0).threads(0);
271 ASSERT_FALSE(thread_state.has_exception());
272 }
273
226 // Tests stability report extraction. 274 // Tests stability report extraction.
227 class StabilityReportExtractorTest : public testing::Test { 275 class StabilityReportExtractorTest : public testing::Test {
228 public: 276 public:
229 const int kMemorySize = 1 << 20; // 1MiB 277 const int kMemorySize = 1 << 20; // 1MiB
230 278
231 StabilityReportExtractorTest() {} 279 StabilityReportExtractorTest() {}
232 ~StabilityReportExtractorTest() override { 280 ~StabilityReportExtractorTest() override {
233 GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get(); 281 GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get();
234 if (global_tracker) { 282 if (global_tracker) {
235 global_tracker->ReleaseTrackerForCurrentThreadForTesting(); 283 global_tracker->ReleaseTrackerForCurrentThreadForTesting();
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier()); 448 EXPECT_EQ("CAFECAFE2d000", collected_module.code_identifier());
401 EXPECT_EQ(module_info.debug_file, collected_module.debug_file()); 449 EXPECT_EQ(module_info.debug_file, collected_module.debug_file());
402 EXPECT_EQ("1122334455667788ABCD0123456789AB1", 450 EXPECT_EQ("1122334455667788ABCD0123456789AB1",
403 collected_module.debug_identifier()); 451 collected_module.debug_identifier());
404 EXPECT_EQ("", collected_module.version()); 452 EXPECT_EQ("", collected_module.version());
405 EXPECT_EQ(0LL, collected_module.shrink_down_delta()); 453 EXPECT_EQ(0LL, collected_module.shrink_down_delta());
406 EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded()); 454 EXPECT_EQ(!module_info.is_loaded, collected_module.is_unloaded());
407 } 455 }
408 456
409 } // namespace browser_watcher 457 } // namespace browser_watcher
OLDNEW
« no previous file with comments | « components/browser_watcher/stability_report_extractor.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698