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

Side by Side Diff: components/crash/content/app/fallback_crash_handler_launcher_win.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:10 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 "base/logging.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/win/win_util.h"
10
11 namespace crash_reporter {
12
13 FallbackCrashHandlerLauncher::FallbackCrashHandlerLauncher() {
14 memset(&exception_pointers_, 0, sizeof(exception_pointers_));
15 }
16
17 FallbackCrashHandlerLauncher::~FallbackCrashHandlerLauncher() {}
18
19 bool FallbackCrashHandlerLauncher::Initialize(
20 const base::CommandLine& program,
21 const base::FilePath& crashpad_database) {
22 // Open an inheritable handle to self. This will be inherited to the handler.
23 DWORD kAccessMask =
scottmg 2017/01/06 18:29:04 const DWORD if using k..., otherwise access_mask.
Sigurður Ásgeirsson 2017/01/06 20:59:10 Done.
24 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_DUP_HANDLE;
25 self_process_handle_.Set(
26 OpenProcess(kAccessMask, TRUE, ::GetCurrentProcessId()));
27 if (!self_process_handle_.IsValid())
28 return false;
29
30 // Setup the startup info for inheriting the self process handle into the
31 // fallback crash handler.
32 if (!startup_info_.InitializeProcThreadAttributeList(1))
33 return false;
34
35 HANDLE raw_self_process_handle = self_process_handle_.Get();
36 if (!startup_info_.UpdateProcThreadAttribute(
37 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &raw_self_process_handle,
38 sizeof(raw_self_process_handle))) {
39 return false;
40 }
41
42 // Build the command line from a copy of the command line passed in.
43 base::CommandLine cmd_line(program);
44 cmd_line.AppendSwitchPath("database", crashpad_database);
45 cmd_line.AppendSwitchASCII(
46 "exception-pointers",
47 base::UintToString(reinterpret_cast<uintptr_t>(&exception_pointers_)));
48 cmd_line.AppendSwitchASCII(
49 "process", base::UintToString(
50 base::win::HandleToUint32(self_process_handle_.Get())));
51
52 std::wstring str_cmd_line = cmd_line.GetCommandLineString();
53
54 // Append the for now abortive thread argument manually.
55 str_cmd_line.append(L" --thread=");
56
57 // Store the command line string for easy use later.
58 cmd_line_.assign(str_cmd_line.begin(), str_cmd_line.end());
59
60 // Reserve space for appending the thread id later at crash time, without
61 // requiring an allocation to happen.
62 cmd_line_.reserve(cmd_line_.size() + 32);
63
64 return true;
65 }
66
67 DWORD FallbackCrashHandlerLauncher::LaunchAndWaitForHandler(
68 EXCEPTION_POINTERS* exception_pointers) {
69 DCHECK(!cmd_line_.empty());
70 DCHECK_EQ('=', cmd_line_.back());
71 // This program has crashed. Try and not use anything but the stack.
72
73 // Append the current thread's ID to the command line, without incurring
74 // an allocation.
75 wchar_t buf[32];
76 int len = wsprintf(buf, L"%d", GetCurrentThreadId());
scottmg 2017/01/06 18:29:04 How about doing a resize() in Initialize() and the
Sigurður Ásgeirsson 2017/01/06 20:59:10 Good idea, done!
77 // Append the thread ID and the terminating zero to the command line string.
78 cmd_line_.insert(cmd_line_.end(), buf, buf + len + 1);
79
80 // Copy the exception pointers to our member variable, whose address is
81 // already baked into the command line.
82 exception_pointers_ = *exception_pointers;
83
84 // Launch the pre-cooked command line.
85 DWORD error = ERROR_SUCCESS;
86 PROCESS_INFORMATION process_info = {};
87 if (!CreateProcess(nullptr, // Application name.
88 &cmd_line_[0], // Command line.
89 nullptr, // Process attributes.
90 nullptr, // Thread attributes.
91 true, // Inherit handles.
92 0, // Creation flags.
93 nullptr, // Environment.
94 nullptr, // Current directory.
95 startup_info_.startup_info(), // Startup info.
96 &process_info)) {
97 error = GetLastError();
scottmg 2017/01/06 18:29:04 return GetLastError() seems simpler here, and move
Sigurður Ásgeirsson 2017/01/06 20:59:10 Done.
98 return error;
99 }
100
101 // Wait on the fallback crash handler process. The expectation is that this
102 // will never return, as the fallback crash handler will terminate this
103 // process. For testing, and full-on belt and suspenders, cover for this
104 // returning.
105 error = WaitForSingleObject(process_info.hProcess, INFINITE);
106 if (error != WAIT_OBJECT_0) {
scottmg 2017/01/06 18:29:04 Please add (or add a note to add) UMA that tracks
Sigurður Ásgeirsson 2017/01/06 20:59:10 Added a TODO - maybe it'll be saner to do this fro
107 // This should never happen, barring handle abuse.
108 NOTREACHED();
109 error = GetLastError();
110 } else {
111 // On successful wait, return the exit code of the fallback crash handler
112 // process.
113 if (!GetExitCodeProcess(process_info.hProcess, &error)) {
114 // This should never happen, barring handle abuse.
115 NOTREACHED();
116 error = GetLastError();
117 }
118 }
119
120 // Close the handles returned from CreateProcess.
121 CloseHandle(process_info.hProcess);
122 CloseHandle(process_info.hThread);
123
124 return error;
125 }
126
127 } // namespace crash_reporter
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698