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

Side by Side Diff: components/crash/content/app/fallback_crash_handler_launcher_win_unittest.cc

Issue 2596463002: A simple, practically zero cost fallback crash handler for Crashpad handler process. (Closed)
Patch Set: Tweak comments for moar better confusion-less reading. Created 3 years, 11 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
scottmg 2017/01/06 18:29:04 2017
Sigurður Ásgeirsson 2017/01/06 20:59:11 Done.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/crash/content/app/fallback_crash_handler_launcher_win.h"
6
7 #include <dbghelp.h>
8
9 #include "base/command_line.h"
10 #include "base/files/file.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/macros.h"
15 #include "base/process/process.h"
16 #include "base/process/process_handle.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/test/multiprocess_test.h"
19 #include "base/win/win_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "testing/multiprocess_func_list.h"
22
23 namespace crash_reporter {
24
25 namespace {
26
27 const wchar_t kFileName[] = L"crash.dmp";
28
29 MULTIPROCESS_TEST_MAIN(FallbackCrashHandlerLauncherMain) {
30 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
31
32 // Check for presence of the "process" argument.
33 CHECK(cmd_line->HasSwitch("process"));
scottmg 2017/01/06 18:29:04 I've never used MULTIPROCESS_TEST_MAIN... can thes
Sigurður Ásgeirsson 2017/01/06 20:59:11 Sadly no, there's no GTest on the other side.
34
35 // Retrieve and check the handle to verify that it was inherited in.
36 unsigned uint_process = 0;
scottmg 2017/01/06 18:29:04 unsigned int, and below for thread_id.
Sigurður Ásgeirsson 2017/01/06 20:59:11 Done.
37 CHECK(base::StringToUint(cmd_line->GetSwitchValueASCII("process"),
38 &uint_process));
39 base::Process process(base::win::Uint32ToHandle(uint_process));
40
41 // Verify that the process handle points to our parent.
42 CHECK_EQ(base::GetParentProcessId(base::GetCurrentProcessHandle()),
43 process.Pid());
44
45 // Check the "thread" argument.
46 CHECK(cmd_line->HasSwitch("thread"));
47
48 // Retrieve the thread id.
49 unsigned thread_id = 0;
50 CHECK(
51 base::StringToUint(cmd_line->GetSwitchValueASCII("thread"), &thread_id));
52
53 // Check the "exception-pointers" argument.
54 CHECK(cmd_line->HasSwitch("exception-pointers"));
55 uint64_t uint_exc_ptrs = 0;
56 CHECK(base::StringToUint64(
57 cmd_line->GetSwitchValueASCII("exception-pointers"), &uint_exc_ptrs));
58
59 EXCEPTION_POINTERS* exc_ptrs = reinterpret_cast<EXCEPTION_POINTERS*>(
60 static_cast<uintptr_t>(uint_exc_ptrs));
61
62 // Check the "database" argument.
63 CHECK(cmd_line->HasSwitch("database"));
64 base::FilePath database_dir = cmd_line->GetSwitchValuePath("database");
65
66 base::FilePath dump_path = database_dir.Append(kFileName);
67
68 // Create a dump file in the directory.
69 base::File dump(dump_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
70
71 CHECK(dump.IsValid());
72
73 MINIDUMP_TYPE minidump_type = static_cast<MINIDUMP_TYPE>(
scottmg 2017/01/06 18:29:04 const makes sense here.
Sigurður Ásgeirsson 2017/01/06 20:59:11 Done.
74 MiniDumpWithHandleData | MiniDumpWithUnloadedModules |
75 MiniDumpWithProcessThreadData | MiniDumpWithThreadInfo |
76 MiniDumpWithTokenInformation);
77
78 MINIDUMP_EXCEPTION_INFORMATION exc_info = {};
79 exc_info.ThreadId = thread_id;
80 exc_info.ExceptionPointers = exc_ptrs;
81 exc_info.ClientPointers = TRUE; // ExceptionPointers in client.
82
83 // Write the minidump as a direct test of the validity and permissions on the
84 // parent handle.
85 if (!MiniDumpWriteDump(process.Handle(), // Process handle.
86 process.Pid(), // Process Id.
87 dump.GetPlatformFile(), // File handle.
88 minidump_type, // Minidump type.
89 &exc_info, // Exception Param
90 nullptr, // UserStreamParam,
91 nullptr)) { // CallbackParam
92 DWORD error = GetLastError();
93
94 dump.Close();
95 CHECK(base::DeleteFile(dump_path, false));
96 CHECK(false) << "Unable to write dump, error " << error;
97 }
98
99 return 0;
100 }
101
102 class FallbackCrashHandlerLauncherTest : public base::MultiProcessTest {
103 public:
104 void SetUp() override { ASSERT_TRUE(database_dir_.CreateUniqueTempDir()); }
105
106 protected:
107 base::ScopedTempDir database_dir_;
108 };
109
110 } // namespace
111
112 TEST_F(FallbackCrashHandlerLauncherTest, LaunchAndWaitForHandler) {
113 base::CommandLine base_cmdline(
114 MakeCmdLine("FallbackCrashHandlerLauncherMain"));
115
116 FallbackCrashHandlerLauncher launcher;
117 ASSERT_TRUE(launcher.Initialize(base_cmdline, database_dir_.GetPath()));
118
119 // Make like an access violation at the current place.
120 EXCEPTION_RECORD exc_record = {};
121 exc_record.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
122 CONTEXT ctx = {};
123 RtlCaptureContext(&ctx);
124
125 EXCEPTION_POINTERS exc_ptrs = {&exc_record, &ctx};
126
127 ASSERT_EQ(ERROR_SUCCESS, launcher.LaunchAndWaitForHandler(&exc_ptrs));
scottmg 2017/01/06 18:29:04 It's a bit weird that in the test we don't test th
Sigurður Ásgeirsson 2017/01/06 20:59:11 Yeah, I suppose, though this is a function of the
128
129 // Check that the dump was written, e.g. it's an existing file with non-zero
130 // size.
131 base::File dump(database_dir_.GetPath().Append(kFileName),
132 base::File::FLAG_OPEN | base::File::FLAG_READ);
133 ASSERT_TRUE(dump.IsValid());
134 ASSERT_NE(0, dump.GetLength());
135 }
136
137 } // namespace crash_reporter
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698