• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git chrome/chrome_elf/BUILD.gn chrome/chrome_elf/BUILD.gn
2index 3fe0b9b74ae0a..38987ce169308 100644
3--- chrome/chrome_elf/BUILD.gn
4+++ chrome/chrome_elf/BUILD.gn
5@@ -7,6 +7,7 @@
6
7 import("//build/config/compiler/compiler.gni")
8 import("//build/config/win/manifest.gni")
9+import("//cef/libcef/features/features.gni")
10 import("//chrome/process_version_rc_template.gni")
11 import("//testing/test.gni")
12
13@@ -104,9 +105,6 @@ source_set("constants") {
14
15 static_library("crash") {
16   sources = [
17-    "../app/chrome_crash_reporter_client_win.cc",
18-    "../app/chrome_crash_reporter_client_win.h",
19-    "../common/chrome_result_codes.h",
20     "crash/crash_helper.cc",
21     "crash/crash_helper.h",
22   ]
23@@ -114,6 +112,7 @@ static_library("crash") {
24     ":hook_util",
25     "//base",  # This needs to go.  DEP of app, crash_keys, client.
26     "//base:base_static",  # pe_image
27+    "//cef/libcef/features",
28     "//chrome/install_static:install_static_util",
29     "//components/crash/core/app",
30     "//components/crash/core/common",  # crash_keys
31@@ -121,6 +120,17 @@ static_library("crash") {
32     "//content/public/common:result_codes",
33     "//third_party/crashpad/crashpad/client",  # DumpWithoutCrash
34   ]
35+
36+  if (enable_cef) {
37+    deps += [ "//cef:chrome_elf_set" ]
38+    include_dirs = [ "//cef" ]
39+  } else {
40+    sources += [
41+      "//chrome/app/chrome_crash_reporter_client_win.cc",
42+      "//chrome/app/chrome_crash_reporter_client_win.h",
43+      "//chrome/common/chrome_result_codes.h",
44+    ]
45+  }
46 }
47
48 source_set("dll_hash") {
49diff --git chrome/chrome_elf/crash/crash_helper.cc chrome/chrome_elf/crash/crash_helper.cc
50index 886372e114899..ad3bc2242883b 100644
51--- chrome/chrome_elf/crash/crash_helper.cc
52+++ chrome/chrome_elf/crash/crash_helper.cc
53@@ -11,12 +11,17 @@
54 #include <string>
55 #include <vector>
56
57+#include "cef/libcef/features/features.h"
58 #include "chrome/app/chrome_crash_reporter_client_win.h"
59 #include "chrome/chrome_elf/hook_util/hook_util.h"
60 #include "components/crash/core/app/crashpad.h"
61 #include "components/crash/core/common/crash_keys.h"
62 #include "third_party/crashpad/crashpad/client/crashpad_client.h"
63
64+#if BUILDFLAG(ENABLE_CEF)
65+#include "cef/libcef/common/crash_reporter_client.h"
66+#endif
67+
68 namespace {
69
70 // Crash handling from elf is only enabled for the chrome.exe process.
71@@ -77,7 +82,11 @@ bool InitializeCrashReporting() {
72   g_crash_reports = new std::vector<crash_reporter::Report>;
73   g_set_unhandled_exception_filter = new elf_hook::IATHook();
74
75+#if BUILDFLAG(ENABLE_CEF)
76+  CefCrashReporterClient::InitializeCrashReportingForProcess();
77+#else
78   ChromeCrashReporterClient::InitializeCrashReportingForProcess();
79+#endif
80
81   g_crash_helper_enabled = true;
82   return true;
83diff --git chrome/common/crash_keys.cc chrome/common/crash_keys.cc
84index f6850e85411ab..4f5500d8fa1ea 100644
85--- chrome/common/crash_keys.cc
86+++ chrome/common/crash_keys.cc
87@@ -4,6 +4,8 @@
88
89 #include "chrome/common/crash_keys.h"
90
91+#include <iterator>
92+
93 #include "base/base_switches.h"
94 #include "base/command_line.h"
95 #include "base/cxx17_backports.h"
96@@ -46,8 +48,10 @@ void HandleEnableDisableFeatures(const base::CommandLine& command_line) {
97 }
98 #endif
99
100+}  // namespace
101+
102 // Return true if we DON'T want to upload this flag to the crash server.
103-bool IsBoringSwitch(const std::string& flag) {
104+bool IsBoringChromeSwitch(const std::string& flag) {
105   static const char* const kIgnoreSwitches[] = {
106     switches::kEnableLogging,
107     switches::kFlagSwitchesBegin,
108@@ -107,13 +111,11 @@ bool IsBoringSwitch(const std::string& flag) {
109   return false;
110 }
111
112-}  // namespace
113-
114 void SetCrashKeysFromCommandLine(const base::CommandLine& command_line) {
115 #if BUILDFLAG(IS_CHROMEOS)
116   HandleEnableDisableFeatures(command_line);
117 #endif
118-  SetSwitchesFromCommandLine(command_line, &IsBoringSwitch);
119+  SetSwitchesFromCommandLine(command_line, &IsBoringChromeSwitch);
120 }
121
122 void SetActiveExtensions(const std::set<std::string>& extensions) {
123diff --git chrome/common/crash_keys.h chrome/common/crash_keys.h
124index e2d53ac83dde0..6ac76e407a748 100644
125--- chrome/common/crash_keys.h
126+++ chrome/common/crash_keys.h
127@@ -16,6 +16,10 @@ class CommandLine;
128
129 namespace crash_keys {
130
131+// Returns true if the specified command-line flag should be excluded from
132+// crash reporting.
133+bool IsBoringChromeSwitch(const std::string& flag);
134+
135 // Sets the kNumSwitches key and the set of keys named using kSwitchFormat based
136 // on the given |command_line|.
137 void SetCrashKeysFromCommandLine(const base::CommandLine& command_line);
138diff --git components/crash/core/app/breakpad_linux.cc components/crash/core/app/breakpad_linux.cc
139index 823e49a234e3d..3f0f95a330bf4 100644
140--- components/crash/core/app/breakpad_linux.cc
141+++ components/crash/core/app/breakpad_linux.cc
142@@ -29,6 +29,7 @@
143 #include "base/base_switches.h"
144 #include "base/command_line.h"
145 #include "base/debug/dump_without_crashing.h"
146+#include "base/debug/leak_annotations.h"
147 #include "base/files/file_path.h"
148 #include "base/lazy_instance.h"
149 #include "base/linux_util.h"
150@@ -721,7 +722,7 @@ bool CrashDone(const MinidumpDescriptor& minidump,
151   info.process_type_length = 7;
152   info.distro = base::g_linux_distro;
153   info.distro_length = my_strlen(base::g_linux_distro);
154-  info.upload = upload;
155+  info.upload = upload && g_upload_url;
156   info.process_start_time = g_process_start_time;
157   info.oom_size = base::g_oom_size;
158   info.pid = g_pid;
159@@ -1735,10 +1736,27 @@ void HandleCrashDump(const BreakpadInfo& info) {
160     GetCrashReporterClient()->GetProductNameAndVersion(&product_name, &version);
161
162     writer.AddBoundary();
163-    writer.AddPairString("prod", product_name);
164+    writer.AddPairString("product", product_name);
165+    writer.AddBoundary();
166+    writer.AddPairString("version", version);
167     writer.AddBoundary();
168-    writer.AddPairString("ver", version);
169+
170+#if defined(ARCH_CPU_ARM_FAMILY)
171+#if defined(ARCH_CPU_32_BITS)
172+    const char* platform = "linuxarm";
173+#elif defined(ARCH_CPU_64_BITS)
174+    const char* platform = "linuxarm64";
175+#endif
176+#else
177+#if defined(ARCH_CPU_32_BITS)
178+    const char* platform = "linux32";
179+#elif defined(ARCH_CPU_64_BITS)
180+    const char* platform = "linux64";
181+#endif
182+#endif  // defined(ARCH_CPU_ARM_FAMILY)
183+    writer.AddPairString("platform", platform);
184     writer.AddBoundary();
185+
186     if (info.pid > 0) {
187       char pid_value_buf[kUint64StringSize];
188       uint64_t pid_value_len = my_uint64_len(info.pid);
189@@ -1855,6 +1873,9 @@ void HandleCrashDump(const BreakpadInfo& info) {
190         crash_reporter::internal::TransitionalCrashKeyStorage;
191     CrashKeyStorage::Iterator crash_key_iterator(*info.crash_keys);
192     const CrashKeyStorage::Entry* entry;
193+
194+    crash_reporter::CrashReporterClient::ParameterMap parameters;
195+
196     while ((entry = crash_key_iterator.Next())) {
197       size_t key_size, value_size;
198       // Check for malformed messages.
199@@ -1865,7 +1886,13 @@ void HandleCrashDump(const BreakpadInfo& info) {
200                        ? CrashKeyStorage::value_size - 1
201                        : my_strlen(entry->value);
202
203-      writer.AddPairData(entry->key, key_size, entry->value, value_size);
204+      parameters.insert(std::make_pair(std::string{entry->key, key_size}, std::string{entry->value, value_size}));
205+    }
206+    if (!parameters.empty())
207+      parameters = GetCrashReporterClient()->FilterParameters(parameters);
208+
209+    for (const auto& param : parameters) {
210+      writer.AddPairData(param.first.data(), param.first.size(), param.second.data(), param.second.size());
211       writer.AddBoundary();
212       writer.Flush();
213     }
214diff --git components/crash/core/app/breakpad_linux.h components/crash/core/app/breakpad_linux.h
215index 2f0d4c555506a..c537846b21568 100644
216--- components/crash/core/app/breakpad_linux.h
217+++ components/crash/core/app/breakpad_linux.h
218@@ -20,6 +20,9 @@ extern void InitCrashReporter(const std::string& process_type);
219 // Sets the product/distribution channel crash key.
220 void SetChannelCrashKey(const std::string& channel);
221
222+// Set the crash server URL.
223+void SetCrashServerURL(const std::string& url);
224+
225 #if BUILDFLAG(IS_ANDROID)
226 extern void InitCrashKeysForTesting();
227
228diff --git components/crash/core/app/crash_reporter_client.cc components/crash/core/app/crash_reporter_client.cc
229index 82b7f241e2618..d3cd5524bb253 100644
230--- components/crash/core/app/crash_reporter_client.cc
231+++ components/crash/core/app/crash_reporter_client.cc
232@@ -89,7 +89,7 @@ bool CrashReporterClient::GetShouldDumpLargerDumps() {
233 }
234 #endif
235
236-#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
237+#if BUILDFLAG(IS_POSIX)
238 void CrashReporterClient::GetProductNameAndVersion(const char** product_name,
239                                                    const char** version) {
240 }
241@@ -98,6 +98,7 @@ void CrashReporterClient::GetProductNameAndVersion(std::string* product_name,
242                                                    std::string* version,
243                                                    std::string* channel) {}
244
245+#if !BUILDFLAG(IS_MAC)
246 base::FilePath CrashReporterClient::GetReporterLogFilename() {
247   return base::FilePath();
248 }
249@@ -107,6 +108,7 @@ bool CrashReporterClient::HandleCrashDump(const char* crashdump_filename,
250   return false;
251 }
252 #endif
253+#endif
254
255 #if BUILDFLAG(IS_WIN)
256 bool CrashReporterClient::GetCrashDumpLocation(std::wstring* crash_dir) {
257@@ -141,6 +143,28 @@ bool CrashReporterClient::ReportingIsEnforcedByPolicy(bool* breakpad_enabled) {
258   return false;
259 }
260
261+bool CrashReporterClient::EnableBreakpadForProcess(
262+    const std::string& process_type) {
263+  return false;
264+}
265+
266+void CrashReporterClient::GetCrashOptionalArguments(
267+    std::vector<std::string>* arguments) {
268+}
269+
270+#if BUILDFLAG(IS_WIN)
271+std::wstring CrashReporterClient::GetCrashExternalHandler(
272+    const std::wstring& exe_dir) {
273+  return exe_dir + L"\\crashpad_handler.exe";
274+}
275+#endif
276+
277+#if BUILDFLAG(IS_MAC)
278+bool CrashReporterClient::EnableBrowserCrashForwarding() {
279+  return true;
280+}
281+#endif
282+
283 #if BUILDFLAG(IS_ANDROID)
284 unsigned int CrashReporterClient::GetCrashDumpPercentage() {
285   return 100;
286@@ -203,9 +227,11 @@ bool CrashReporterClient::ShouldMonitorCrashHandlerExpensively() {
287   return false;
288 }
289
290-bool CrashReporterClient::EnableBreakpadForProcess(
291-    const std::string& process_type) {
292-  return false;
293+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
294+CrashReporterClient::ParameterMap
295+CrashReporterClient::FilterParameters(const ParameterMap& parameters) {
296+  return parameters;
297 }
298+#endif
299
300 }  // namespace crash_reporter
301diff --git components/crash/core/app/crash_reporter_client.h components/crash/core/app/crash_reporter_client.h
302index 24e53fa62c2c4..68011566b5723 100644
303--- components/crash/core/app/crash_reporter_client.h
304+++ components/crash/core/app/crash_reporter_client.h
305@@ -5,7 +5,9 @@
306 #ifndef COMPONENTS_CRASH_CORE_APP_CRASH_REPORTER_CLIENT_H_
307 #define COMPONENTS_CRASH_CORE_APP_CRASH_REPORTER_CLIENT_H_
308
309+#include <map>
310 #include <string>
311+#include <vector>
312
313 #include "build/build_config.h"
314
315@@ -89,7 +91,7 @@ class CrashReporterClient {
316   virtual bool GetShouldDumpLargerDumps();
317 #endif
318
319-#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
320+#if BUILDFLAG(IS_POSIX)
321   // Returns a textual description of the product type and version to include
322   // in the crash report. Neither out parameter should be set to NULL.
323   // TODO(jperaza): Remove the 2-parameter overload of this method once all
324@@ -100,6 +102,7 @@ class CrashReporterClient {
325                                         std::string* version,
326                                         std::string* channel);
327
328+#if !BUILDFLAG(IS_MAC)
329   virtual base::FilePath GetReporterLogFilename();
330
331   // Custom crash minidump handler after the minidump is generated.
332@@ -109,6 +112,7 @@ class CrashReporterClient {
333   // libc nor allocate memory normally.
334   virtual bool HandleCrashDump(const char* crashdump_filename,
335                                uint64_t crash_pid);
336+#endif
337 #endif
338
339   // The location where minidump files should be written. Returns true if
340@@ -206,6 +210,27 @@ class CrashReporterClient {
341
342   // Returns true if breakpad should run in the given process type.
343   virtual bool EnableBreakpadForProcess(const std::string& process_type);
344+
345+  // Populate |arguments| with additional optional arguments.
346+  virtual void GetCrashOptionalArguments(std::vector<std::string>* arguments);
347+
348+#if BUILDFLAG(IS_WIN)
349+  // Returns the absolute path to the external crash handler exe.
350+  virtual std::wstring GetCrashExternalHandler(const std::wstring& exe_dir);
351+#endif
352+
353+#if BUILDFLAG(IS_MAC)
354+  // Returns true if forwarding of crashes to the system crash reporter is
355+  // enabled for the browser process.
356+  virtual bool EnableBrowserCrashForwarding();
357+#endif
358+
359+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
360+  // Provides an oportunity to modify the parameters that will be sent with a
361+  // crash upload.
362+  using ParameterMap = std::map<std::string, std::string>;
363+  virtual ParameterMap FilterParameters(const ParameterMap& parameters);
364+#endif
365 };
366
367 }  // namespace crash_reporter
368diff --git components/crash/core/app/crashpad.cc components/crash/core/app/crashpad.cc
369index 6da6be46cee4a..5e3067c081867 100644
370--- components/crash/core/app/crashpad.cc
371+++ components/crash/core/app/crashpad.cc
372@@ -154,7 +154,8 @@ bool InitializeCrashpadImpl(bool initial_client,
373   // fallback. Forwarding is turned off for debug-mode builds even for the
374   // browser process, because the system's crash reporter can take a very long
375   // time to chew on symbols.
376-  if (!browser_process || is_debug_build) {
377+  if (!browser_process || is_debug_build ||
378+      !GetCrashReporterClient()->EnableBrowserCrashForwarding()) {
379     crashpad::CrashpadInfo::GetCrashpadInfo()
380         ->set_system_crash_reporter_forwarding(crashpad::TriState::kDisabled);
381   }
382diff --git components/crash/core/app/crashpad_mac.mm components/crash/core/app/crashpad_mac.mm
383index dc041c43371fd..1d060ae55c586 100644
384--- components/crash/core/app/crashpad_mac.mm
385+++ components/crash/core/app/crashpad_mac.mm
386@@ -16,11 +16,14 @@
387 #include "base/files/file_path.h"
388 #include "base/mac/bundle_locations.h"
389 #include "base/mac/foundation_util.h"
390+#include "base/path_service.h"
391 #include "base/strings/string_number_conversions.h"
392 #include "base/strings/string_piece.h"
393 #include "base/strings/sys_string_conversions.h"
394 #include "build/branding_buildflags.h"
395 #include "components/crash/core/app/crash_reporter_client.h"
396+#include "components/crash/core/app/crash_switches.h"
397+#include "content/public/common/content_paths.h"
398 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
399 #include "third_party/crashpad/crashpad/client/crashpad_client.h"
400 #include "third_party/crashpad/crashpad/client/crashpad_info.h"
401@@ -38,14 +41,24 @@ std::map<std::string, std::string> GetProcessSimpleAnnotations() {
402     std::map<std::string, std::string> process_annotations;
403     @autoreleasepool {
404       NSBundle* outer_bundle = base::mac::OuterBundle();
405+      CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
406+      const char* product_name = "";
407+      const char* product_version = "";
408+      crash_reporter_client->GetProductNameAndVersion(&product_name,
409+                                                      &product_version);
410+
411+      if (strlen(product_name) == 0) {
412 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
413-      process_annotations["prod"] = "Chrome_Mac";
414+        process_annotations["product"] = "Chrome_Mac";
415 #else
416-      NSString* product = base::mac::ObjCCast<NSString>([outer_bundle
417-          objectForInfoDictionaryKey:base::mac::CFToNSCast(kCFBundleNameKey)]);
418-      process_annotations["prod"] =
419-          base::SysNSStringToUTF8(product).append("_Mac");
420+        NSString* product = base::mac::ObjCCast<NSString>([outer_bundle
421+            objectForInfoDictionaryKey:base::mac::CFToNSCast(kCFBundleNameKey)]);
422+        process_annotations["product"] =
423+            base::SysNSStringToUTF8(product).append("_Mac");
424 #endif
425+      } else {
426+        process_annotations["product"] = product_name;
427+      }
428
429 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
430       // Empty means stable.
431@@ -76,12 +89,20 @@ std::map<std::string, std::string> GetProcessSimpleAnnotations() {
432         }
433       }
434
435-      NSString* version =
436-          base::mac::ObjCCast<NSString>([base::mac::FrameworkBundle()
437-              objectForInfoDictionaryKey:@"CFBundleShortVersionString"]);
438-      process_annotations["ver"] = base::SysNSStringToUTF8(version);
439+      if (strlen(product_version) == 0) {
440+        NSString* version =
441+            base::mac::ObjCCast<NSString>([base::mac::FrameworkBundle()
442+                objectForInfoDictionaryKey:@"CFBundleShortVersionString"]);
443+        process_annotations["version"] = base::SysNSStringToUTF8(version);
444+      } else {
445+        process_annotations["version"] = product_version;
446+      }
447
448-      process_annotations["plat"] = std::string("OS X");
449+#if defined(ARCH_CPU_ARM64)
450+      process_annotations["platform"] = std::string("macosarm64");
451+#else
452+      process_annotations["platform"] = std::string("macos");
453+#endif
454     }  // @autoreleasepool
455     return process_annotations;
456   }();
457@@ -141,10 +162,10 @@ bool PlatformCrashpadInitialization(
458
459   if (initial_client) {
460     @autoreleasepool {
461-      base::FilePath framework_bundle_path = base::mac::FrameworkBundlePath();
462-      base::FilePath handler_path =
463-          framework_bundle_path.Append("Helpers").Append(
464-              "chrome_crashpad_handler");
465+      // Use the same subprocess helper exe.
466+      base::FilePath handler_path;
467+      base::PathService::Get(content::CHILD_PROCESS_EXE, &handler_path);
468+      DCHECK(!handler_path.empty());
469
470       // Is there a way to recover if this fails?
471       CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
472@@ -173,6 +194,12 @@ bool PlatformCrashpadInitialization(
473             "--reset-own-crash-exception-port-to-system-default");
474       }
475
476+      // Since we're using the same subprocess helper exe we must specify the
477+      // process type.
478+      arguments.push_back(std::string("--type=") + switches::kCrashpadHandler);
479+
480+      crash_reporter_client->GetCrashOptionalArguments(&arguments);
481+
482       bool result = GetCrashpadClient().StartHandler(
483           handler_path, *database_path, metrics_path, url,
484           GetProcessSimpleAnnotations(), arguments, true, false);
485diff --git components/crash/core/app/crashpad_win.cc components/crash/core/app/crashpad_win.cc
486index 1a8f42cb4e2ea..fbdeab5d54584 100644
487--- components/crash/core/app/crashpad_win.cc
488+++ components/crash/core/app/crashpad_win.cc
489@@ -36,8 +36,8 @@ void GetPlatformCrashpadAnnotations(
490   std::wstring product_name, version, special_build, channel_name;
491   crash_reporter_client->GetProductNameAndVersion(
492       exe_file, &product_name, &version, &special_build, &channel_name);
493-  (*annotations)["prod"] = base::WideToUTF8(product_name);
494-  (*annotations)["ver"] = base::WideToUTF8(version);
495+  (*annotations)["product"] = base::WideToUTF8(product_name);
496+  (*annotations)["version"] = base::WideToUTF8(version);
497 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
498   // Empty means stable.
499   const bool allow_empty_channel = true;
500@@ -54,9 +54,11 @@ void GetPlatformCrashpadAnnotations(
501   if (!special_build.empty())
502     (*annotations)["special"] = base::WideToUTF8(special_build);
503 #if defined(ARCH_CPU_X86)
504-  (*annotations)["plat"] = std::string("Win32");
505+  (*annotations)["platform"] = std::string("win32");
506 #elif defined(ARCH_CPU_X86_64)
507-  (*annotations)["plat"] = std::string("Win64");
508+  (*annotations)["platform"] = std::string("win64");
509+#elif defined(ARCH_CPU_ARM64)
510+  (*annotations)["platform"] = std::string("winarm64");
511 #endif
512 }
513
514@@ -71,7 +73,9 @@ bool PlatformCrashpadInitialization(
515   base::FilePath metrics_path;  // Only valid in the browser process.
516
517   const char kPipeNameVar[] = "CHROME_CRASHPAD_PIPE_NAME";
518+#if defined(GOOGLE_CHROME_BUILD)
519   const char kServerUrlVar[] = "CHROME_CRASHPAD_SERVER_URL";
520+#endif
521   std::unique_ptr<base::Environment> env(base::Environment::Create());
522
523   CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
524@@ -92,9 +96,11 @@ bool PlatformCrashpadInitialization(
525
526     std::string url = crash_reporter_client->GetUploadUrl();
527
528+#if defined(GOOGLE_CHROME_BUILD)
529     // Allow the crash server to be overridden for testing. If the variable
530     // isn't present in the environment then the default URL will remain.
531     env->GetVar(kServerUrlVar, &url);
532+#endif
533
534     base::FilePath exe_file(exe_path);
535     if (exe_file.empty()) {
536@@ -105,13 +111,14 @@ bool PlatformCrashpadInitialization(
537       exe_file = base::FilePath(exe_file_path);
538     }
539
540-    // If the handler is embedded in the binary (e.g. chrome, setup), we
541-    // reinvoke it with --type=crashpad-handler. Otherwise, we use the
542-    // standalone crashpad_handler.exe (for tests, etc.).
543     std::vector<std::string> start_arguments(initial_arguments);
544+
545+    // Always add --type=crashpad-handler because the value is expected by
546+    // CefExecuteProcess.
547+    start_arguments.push_back(
548+        std::string("--type=") + switches::kCrashpadHandler);
549+
550     if (embedded_handler) {
551-      start_arguments.push_back(std::string("--type=") +
552-                                switches::kCrashpadHandler);
553       if (!user_data_dir.empty()) {
554         start_arguments.push_back(std::string("--user-data-dir=") +
555                                   user_data_dir);
556@@ -122,9 +129,12 @@ bool PlatformCrashpadInitialization(
557       start_arguments.push_back("/prefetch:7");
558     } else {
559       base::FilePath exe_dir = exe_file.DirName();
560-      exe_file = exe_dir.Append(FILE_PATH_LITERAL("crashpad_handler.exe"));
561+      exe_file = base::FilePath(
562+          crash_reporter_client->GetCrashExternalHandler(exe_dir.value()));
563     }
564
565+    crash_reporter_client->GetCrashOptionalArguments(&start_arguments);
566+
567     std::vector<std::string> arguments(start_arguments);
568
569     if (crash_reporter_client->ShouldMonitorCrashHandlerExpensively()) {
570