Enable Crashpad for Android
Overview:
This CL disables Breakpad for Chrome, Content Shell, WebView, and
Chromecast on Android and replaces it with Crashpad. When a crash
signal is received, the browser forks+execs a Crashpad handler process
either for itself or on behalf of a crashing child to create a crash
dump.
components/crash/
- Remove CrashDumpManager. Minidump creation is handled entirely by
Crashpad.
- Remove OnChildStart from ChildExitObserver as it is no longer
necessary.
- ChildExitObserver observers CrashHandlerHost to be notified when
child processes receive crash signals.
- De-duplicate calls to ChildExitObserver::Client::OnChildExit when
NOTIFICATION_RENDER_PROCESS_{CLOSED, TERMINATED} are both sent.
components/minidump_uploader/
- Uploaders expect crash reports to already be MIME encoded since
Breakpad was doing that in a signal handler call-back.
CrashFileManager now automatically calls into native code to do
the encoding and write to a directory of crash reports whenever it
checks for reports without logcats.
chrome/app/*.{cc,h}
chrome/browser/*.cc
content/shell/app/*.{cc,h}
content/shell/browser/*.cc
- Initialize Crashpad instead of Breakpad, with minor cleanup and
adjustment for changes to CrashDumpObserver.
chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc
- Simulate crashes/exits with NOTIFICATION_RENDER_PROCESS_{CREATED,
CLOSED} and signals sent to ChildExitObserver instead of a crash
dump.
android_webview/
- AwBrowserTerminator now observes child process crashes via
ChildExitObserver rather than its own pipe.
- Crashpad always produces minidumps, and not microdumps.
- Disabling Crashpad is not yet supported.
chromecast/
- There are now two directories that crash report uploaders should
be aware of: "Crashpad" contains a database of raw minidumps
produced by Crashpad, and "Crash Reports" contains MIME encoded
minidumps. MIME encoding is performed by a CrashReportMimeWriter
in CastCrashUploader.java:checkForCrashDumps().
TBR=yfriedman@chromium.org,peter@chromium.org,isherman@chromium.org,jam@chromium.org,wnwen@chromium.org,torne@chromium.org,halliwell@chromium.org,tobiasjs@chromium.org,rsesek@chromium.org,sanfin@chromium.org,jperaza@chromium.org,mark@chromium.org
Bug: crashpad:30
Change-Id: Ib1b0fe085272a7e1e4a91462add50e41eecad746
Cq-Include-Trybots: master.tryserver.chromium.android:android_compile_x64_dbg;master.tryserver.chromium.android:android_compile_x86_dbg
Reviewed-on: https://chromium-review.googlesource.com/c/1388654
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
Reviewed-by: Luke Halliwell <halliwell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#619711}diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 10a060a..3eb5dee0 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -736,6 +736,7 @@
"//components/crash/android:crashpad_main",
"//components/crash/content/app",
"//components/crash/content/browser",
+ "//components/crash/core/common",
"//components/download/public/common:public",
"//components/embedder_support/android:web_contents_delegate",
"//components/google/core/browser",
@@ -801,6 +802,7 @@
"//storage/browser",
"//storage/common",
"//third_party/blink/public:blink",
+ "//third_party/crashpad/crashpad/client",
"//ui/base",
"//ui/events:gesture_detection",
"//ui/gfx",
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index cbcd232..ca1bb07f 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -16,6 +16,7 @@
"+components/crash/core",
"+components/download/public/common",
"+components/heap_profiling",
+ "+components/minidump_uploader",
"+components/navigation_interception",
"+components/policy/core/browser",
"+components/policy/core/common",
@@ -61,6 +62,9 @@
"+storage/browser/quota",
"+storage/common/quota",
+ "+third_party/crashpad/crashpad/client",
+ "+third_party/crashpad/crashpad/util",
+
"+ui/gfx",
"+ui/gl",
"+ui/touch_selection/touch_handle.h",
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc
index 42e713d..9db729b4 100644
--- a/android_webview/browser/aw_browser_main_parts.cc
+++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -30,7 +30,6 @@
#include "base/message_loop/message_loop_current.h"
#include "base/path_service.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
#include "components/heap_profiling/supervisor.h"
#include "components/services/heap_profiling/public/cpp/settings.h"
#include "components/user_prefs/user_prefs.h"
@@ -95,10 +94,9 @@
}
base::FilePath crash_dir;
- if (crash_reporter::IsCrashReporterEnabled()) {
- if (base::PathService::Get(android_webview::DIR_CRASH_DUMPS, &crash_dir)) {
- if (!base::PathExists(crash_dir))
- base::CreateDirectory(crash_dir);
+ if (base::PathService::Get(android_webview::DIR_CRASH_DUMPS, &crash_dir)) {
+ if (!base::PathExists(crash_dir)) {
+ base::CreateDirectory(crash_dir);
}
}
@@ -106,7 +104,7 @@
switches::kWebViewSandboxedRenderer)) {
// Create the renderers crash manager on the UI thread.
::crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
- std::make_unique<AwBrowserTerminator>(crash_dir));
+ std::make_unique<AwBrowserTerminator>());
}
variations::InitCrashKeys();
diff --git a/android_webview/browser/aw_browser_terminator.cc b/android_webview/browser/aw_browser_terminator.cc
index 8347981..ef87bc6 100644
--- a/android_webview/browser/aw_browser_terminator.cc
+++ b/android_webview/browser/aw_browser_terminator.cc
@@ -9,14 +9,11 @@
#include "android_webview/browser/aw_render_process_gone_delegate.h"
#include "android_webview/common/aw_descriptors.h"
-#include "android_webview/common/crash_reporter/aw_crash_reporter_client.h"
-#include "base/bind.h"
#include "base/logging.h"
#include "base/stl_util.h"
-#include "base/sync_socket.h"
-#include "base/task/post_task.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
-#include "content/public/browser/browser_task_traits.h"
+#include "base/strings/stringprintf.h"
+#include "components/crash/content/app/crashpad.h"
+#include "components/crash/content/browser/crash_metrics_reporter_android.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/child_process_launcher_utils.h"
@@ -36,13 +33,8 @@
namespace {
void GetAwRenderProcessGoneDelegatesForRenderProcess(
- int render_process_id,
+ content::RenderProcessHost* rph,
std::vector<AwRenderProcessGoneDelegate*>* delegates) {
- content::RenderProcessHost* rph =
- content::RenderProcessHost::FromID(render_process_id);
- if (!rph)
- return;
-
std::unique_ptr<content::RenderWidgetHostIterator> widgets(
content::RenderWidgetHost::GetRenderWidgetHosts());
while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
@@ -59,28 +51,29 @@
}
}
-void OnRenderProcessGone(int process_host_id) {
+void OnRenderProcessGone(content::RenderProcessHost* host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<AwRenderProcessGoneDelegate*> delegates;
- GetAwRenderProcessGoneDelegatesForRenderProcess(process_host_id, &delegates);
+ GetAwRenderProcessGoneDelegatesForRenderProcess(host, &delegates);
for (auto* delegate : delegates)
- delegate->OnRenderProcessGone(process_host_id);
+ delegate->OnRenderProcessGone(host->GetID());
}
-void OnRenderProcessGoneDetail(int process_host_id,
- base::ProcessHandle child_process_pid,
+void OnRenderProcessGoneDetail(content::RenderProcessHost* host,
+ base::ProcessId child_process_pid,
bool crashed) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<AwRenderProcessGoneDelegate*> delegates;
- GetAwRenderProcessGoneDelegatesForRenderProcess(process_host_id, &delegates);
+ GetAwRenderProcessGoneDelegatesForRenderProcess(host, &delegates);
for (auto* delegate : delegates) {
if (!delegate->OnRenderProcessGoneDetail(child_process_pid, crashed)) {
if (crashed) {
- crash_reporter::SuppressDumpGeneration();
// Keeps this log unchanged, CTS test uses it to detect crash.
- LOG(FATAL) << "Render process (" << child_process_pid << ")'s crash"
- << " wasn't handled by all associated webviews, triggering"
- << " application crash.";
+ std::string message = base::StringPrintf(
+ "Render process (%d)'s crash wasn't handled by all associated "
+ "webviews, triggering application crash.",
+ child_process_pid);
+ crash_reporter::CrashWithoutDumping(message);
} else {
// The render process was most likely killed for OOM or switching
// WebView provider, to make WebView backward compatible, kills the
@@ -101,91 +94,26 @@
} // namespace
-AwBrowserTerminator::AwBrowserTerminator(base::FilePath crash_dump_dir)
- : crash_dump_dir_(crash_dump_dir) {}
+AwBrowserTerminator::AwBrowserTerminator() = default;
-AwBrowserTerminator::~AwBrowserTerminator() {}
-
-void AwBrowserTerminator::OnChildStart(
- int process_host_id,
- content::PosixFileDescriptorInfo* mappings) {
- DCHECK(content::CurrentlyOnProcessLauncherTaskRunner());
-
- base::AutoLock auto_lock(process_host_id_to_pipe_lock_);
- DCHECK(!ContainsKey(process_host_id_to_pipe_, process_host_id));
-
- auto local_pipe = std::make_unique<base::SyncSocket>();
- auto child_pipe = std::make_unique<base::SyncSocket>();
- if (base::SyncSocket::CreatePair(local_pipe.get(), child_pipe.get())) {
- process_host_id_to_pipe_[process_host_id] = std::move(local_pipe);
- mappings->Transfer(kAndroidWebViewCrashSignalDescriptor,
- base::ScopedFD(dup(child_pipe->handle())));
- }
- if (crash_reporter::IsCrashReporterEnabled()) {
- base::ScopedFD file(
- breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
- process_host_id));
- if (file != base::kInvalidPlatformFile)
- mappings->Transfer(kAndroidMinidumpDescriptor, std::move(file));
- }
-}
-
-void AwBrowserTerminator::OnChildExitAsync(
- const ::crash_reporter::ChildExitObserver::TerminationInfo& info,
- base::FilePath crash_dump_dir,
- std::unique_ptr<base::SyncSocket> pipe) {
- if (crash_reporter::IsCrashReporterEnabled()) {
- breakpad::CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild(
- crash_dump_dir, info);
- }
-
- if (!pipe.get() || info.normal_termination)
- return;
-
- bool crashed = false;
-
- // If the child process hasn't written anything into the pipe. This implies
- // that it was terminated via SIGKILL by the low memory killer.
- if (pipe->Peek() >= sizeof(int)) {
- int exit_code;
- pipe->Receive(&exit_code, sizeof(exit_code));
- LOG(ERROR) << "Renderer process (" << info.pid << ") crash detected (code "
- << exit_code << ").";
- crashed = true;
- }
-
- base::PostTaskWithTraits(
- FROM_HERE, {BrowserThread::UI},
- base::BindOnce(&OnRenderProcessGoneDetail, info.process_host_id, info.pid,
- crashed));
-}
+AwBrowserTerminator::~AwBrowserTerminator() = default;
void AwBrowserTerminator::OnChildExit(
- const ::crash_reporter::ChildExitObserver::TerminationInfo& info) {
- std::unique_ptr<base::SyncSocket> pipe;
+ const crash_reporter::ChildExitObserver::TerminationInfo& info) {
+ content::RenderProcessHost* rph =
+ content::RenderProcessHost::FromID(info.process_host_id);
+ OnRenderProcessGone(rph);
- {
- base::AutoLock auto_lock(process_host_id_to_pipe_lock_);
- // We might get a NOTIFICATION_RENDERER_PROCESS_TERMINATED and a
- // NOTIFICATION_RENDERER_PROCESS_CLOSED. In that case we only want
- // to process the first notification.
- const auto& iter = process_host_id_to_pipe_.find(info.process_host_id);
- if (iter != process_host_id_to_pipe_.end()) {
- pipe = std::move(iter->second);
- DCHECK(pipe->handle() != base::SyncSocket::kInvalidHandle);
- process_host_id_to_pipe_.erase(iter);
- }
- }
- if (pipe.get()) {
- OnRenderProcessGone(info.process_host_id);
+ crash_reporter::CrashMetricsReporter::GetInstance()->ChildProcessExited(info);
+
+ if (info.normal_termination) {
+ return;
}
- base::PostTaskWithTraits(
- FROM_HERE,
- {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
- base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
- base::BindOnce(&AwBrowserTerminator::OnChildExitAsync, info,
- crash_dump_dir_, std::move(pipe)));
+ LOG(ERROR) << "Renderer process (" << info.pid << ") crash detected (code "
+ << info.crash_signo << ").";
+
+ OnRenderProcessGoneDetail(rph, info.pid, info.is_crashed());
}
} // namespace android_webview
diff --git a/android_webview/browser/aw_browser_terminator.h b/android_webview/browser/aw_browser_terminator.h
index e3f7e9d58..e75bf76 100644
--- a/android_webview/browser/aw_browser_terminator.h
+++ b/android_webview/browser/aw_browser_terminator.h
@@ -7,47 +7,24 @@
#include <map>
-#include "base/synchronization/lock.h"
+#include "base/macros.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
-namespace base {
-class SyncSocket;
-}
-
namespace android_webview {
-// This class manages behavior of the browser on renderer crashes when
-// microdumps are used for capturing the crash stack. Normally, in this case
-// the browser doesn't need to do much, because a microdump is written into
-// Android log by the renderer process itself. However, the browser may need to
-// crash itself on a renderer crash. Since on Android renderers are not child
-// processes of the browser, it can't access the exit code. Instead, the browser
-// uses a dedicated pipe in order to receive the information about the renderer
-// crash status.
+// This class manages the browser's behavior in response to renderer exits. If
+// the application does not successfully handle a renderer crash/kill, the
+// browser needs to crash itself.
class AwBrowserTerminator : public crash_reporter::ChildExitObserver::Client {
public:
- AwBrowserTerminator(base::FilePath crash_dump_dir);
+ AwBrowserTerminator();
~AwBrowserTerminator() override;
- // crash_reporter::ChildExitObserver::Client implementation.
- void OnChildStart(int process_host_id,
- content::PosixFileDescriptorInfo* mappings) override;
+ // crash_reporter::ChildExitObserver::Client
void OnChildExit(
const crash_reporter::ChildExitObserver::TerminationInfo& info) override;
private:
- static void OnChildExitAsync(
- const crash_reporter::ChildExitObserver::TerminationInfo& info,
- base::FilePath crash_dump_dir,
- std::unique_ptr<base::SyncSocket> pipe);
-
- base::FilePath crash_dump_dir_;
-
- // This map should only be accessed with its lock aquired as it is accessed
- // from the PROCESS_LAUNCHER, FILE, and UI threads.
- base::Lock process_host_id_to_pipe_lock_;
- std::map<int, std::unique_ptr<base::SyncSocket>> process_host_id_to_pipe_;
-
DISALLOW_COPY_AND_ASSIGN(AwBrowserTerminator);
};
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index ae5cc33..d8004476 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -31,7 +31,6 @@
#include "android_webview/common/aw_content_client.h"
#include "android_webview/common/aw_descriptors.h"
#include "android_webview/common/aw_switches.h"
-#include "android_webview/common/crash_reporter/aw_crash_reporter_client.h"
#include "android_webview/common/render_view_messages.h"
#include "android_webview/common/url_constants.h"
#include "android_webview/grit/aw_resources.h"
@@ -50,7 +49,7 @@
#include "base/task/post_task.h"
#include "components/autofill/content/browser/content_autofill_driver_factory.h"
#include "components/cdm/browser/cdm_message_filter_android.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
+#include "components/crash/content/browser/crash_handler_host_linux.h"
#include "components/navigation_interception/intercept_navigation_delegate.h"
#include "components/policy/content/policy_blacklist_navigation_throttle.h"
#include "components/policy/core/browser/browser_policy_connector_base.h"
@@ -73,6 +72,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/url_constants.h"
@@ -391,7 +391,8 @@
process_type == switches::kUtilityProcess)
<< process_type;
// Pass crash reporter enabled state to renderer processes.
- if (crash_reporter::IsCrashReporterEnabled()) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ ::switches::kEnableCrashReporter)) {
command_line->AppendSwitch(::switches::kEnableCrashReporter);
}
}
@@ -611,8 +612,11 @@
fd = ui::GetLocalePackFd(®ion);
mappings->ShareWithRegion(kAndroidWebViewLocalePakDescriptor, fd, region);
- ::crash_reporter::ChildExitObserver::GetInstance()
- ->BrowserChildProcessStarted(child_process_id, mappings);
+ int crash_signal_fd =
+ crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
+ if (crash_signal_fd >= 0) {
+ mappings->Share(service_manager::kCrashDumpSignal, crash_signal_fd);
+ }
}
void AwContentBrowserClient::OverrideWebkitPrefs(
diff --git a/android_webview/browser/aw_debug.cc b/android_webview/browser/aw_debug.cc
index d8afd23..0ebdd8a 100644
--- a/android_webview/browser/aw_debug.cc
+++ b/android_webview/browser/aw_debug.cc
@@ -11,12 +11,20 @@
#include "base/debug/dump_without_crashing.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/threading/thread_restrictions.h"
#include "components/crash/content/app/crash_reporter_client.h"
+#include "components/crash/content/app/crashpad.h"
#include "components/crash/core/common/crash_key.h"
+#include "components/minidump_uploader/rewrite_minidumps_as_mimes.h"
#include "components/version_info/version_info.h"
#include "components/version_info/version_info_values.h"
#include "jni/AwDebug_jni.h"
+#include "third_party/crashpad/crashpad/client/crash_report_database.h"
+#include "third_party/crashpad/crashpad/util/net/http_body.h"
+#include "third_party/crashpad/crashpad/util/net/http_multipart_builder.h"
+
+#include <memory>
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF8ToJavaString;
@@ -62,6 +70,59 @@
DISALLOW_COPY_AND_ASSIGN(AwDebugCrashReporterClient);
};
+// Writes the most recent report in the database as a MIME to fd. Finishes by
+// deleting all reports from the database. Returns `true` if a report was
+// successfully found and written the file descriptor.
+bool WriteLastReportToFd(crashpad::CrashReportDatabase* db, int fd) {
+ std::vector<crashpad::CrashReportDatabase::Report> reports;
+ if (db->GetPendingReports(&reports) !=
+ crashpad::CrashReportDatabase::kNoError ||
+ !reports.size()) {
+ LOG(ERROR) << "no reports";
+ return false;
+ }
+
+ size_t most_recent_index = 0;
+ time_t most_recent_time = reports[0].creation_time;
+ for (size_t index = 1; index < reports.size(); ++index) {
+ if (reports[index].creation_time > most_recent_time) {
+ most_recent_index = index;
+ most_recent_time = reports[index].creation_time;
+ }
+ }
+
+ {
+ std::unique_ptr<const crashpad::CrashReportDatabase::UploadReport>
+ upload_report;
+ if (db->GetReportForUploading(reports[most_recent_index].uuid,
+ &upload_report,
+ /* report_metrics= */ false) !=
+ crashpad::CrashReportDatabase::kNoError) {
+ return false;
+ }
+
+ crashpad::HTTPMultipartBuilder builder;
+ pid_t pid;
+ if (!minidump_uploader::MimeifyReport(*upload_report.get(), &builder,
+ &pid)) {
+ return false;
+ }
+
+ crashpad::WeakFileHandleFileWriter writer(fd);
+ if (!minidump_uploader::WriteBodyToFile(builder.GetBodyStream().get(),
+ &writer)) {
+ return false;
+ }
+ }
+
+ for (size_t index = 0; index < reports.size(); ++index) {
+ db->DeleteReport(reports[index].uuid);
+ }
+ db->CleanDatabase(0);
+
+ return true;
+}
+
} // namespace
static jboolean JNI_AwDebug_DumpWithoutCrashing(
@@ -76,8 +137,28 @@
base::File::FLAG_WRITE);
if (!target.IsValid())
return false;
- // breakpad_linux::HandleCrashDump will close this fd once it is done.
- return crash_reporter::DumpWithoutCrashingToFd(target.TakePlatformFile());
+
+ AwDebugCrashReporterClient client;
+ base::FilePath database_path;
+ if (!client.GetCrashDumpLocation(&database_path)) {
+ return false;
+ }
+
+ if (!base::CreateDirectory(database_path)) {
+ return false;
+ }
+
+ std::unique_ptr<crashpad::CrashReportDatabase> database =
+ crashpad::CrashReportDatabase::Initialize(database_path);
+ if (!database) {
+ return false;
+ }
+
+ if (!::crash_reporter::DumpWithoutCrashingForClient(&client)) {
+ return false;
+ }
+
+ return WriteLastReportToFd(database.get(), target.GetPlatformFile());
}
static void JNI_AwDebug_InitCrashKeysForWebViewTesting(JNIEnv* env) {
diff --git a/android_webview/common/aw_paths.cc b/android_webview/common/aw_paths.cc
index 99887b2..6b1bc92d 100644
--- a/android_webview/common/aw_paths.cc
+++ b/android_webview/common/aw_paths.cc
@@ -19,7 +19,7 @@
if (!base::android::GetCacheDirectory(&cur))
return false;
cur = cur.Append(FILE_PATH_LITERAL("WebView"))
- .Append(FILE_PATH_LITERAL("Crash Reports"));
+ .Append(FILE_PATH_LITERAL("Crashpad"));
break;
case DIR_SAFE_BROWSING:
if (!base::android::GetCacheDirectory(&cur))
diff --git a/android_webview/common/crash_reporter/aw_crash_reporter_client.cc b/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
index 3298bd1..84f83e9 100644
--- a/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
+++ b/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
@@ -4,70 +4,47 @@
#include "android_webview/common/crash_reporter/aw_crash_reporter_client.h"
-#include <random>
+#include <stdint.h>
#include "android_webview/common/aw_channel.h"
#include "android_webview/common/aw_descriptors.h"
#include "android_webview/common/aw_paths.h"
+#include "android_webview/common/aw_switches.h"
#include "android_webview/common/crash_reporter/crash_keys.h"
#include "base/android/build_info.h"
#include "base/base_paths_android.h"
-#include "base/debug/crash_logging.h"
-#include "base/debug/dump_without_crashing.h"
-#include "base/files/file_path.h"
+#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "base/logging.h"
#include "base/path_service.h"
#include "base/scoped_native_library.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
#include "build/build_config.h"
-#include "components/crash/content/app/breakpad_linux.h"
#include "components/crash/content/app/crash_reporter_client.h"
+#include "components/crash/content/app/crashpad.h"
#include "components/version_info/version_info.h"
#include "components/version_info/version_info_values.h"
-#include "content/public/common/content_switches.h"
namespace android_webview {
namespace crash_reporter {
namespace {
-// TODO(gsennton) lower the following value before pushing to stable:
-const double minidump_generation_user_fraction = 1.0;
-
-// Returns whether the current process should be reporting crashes through
-// minidumps. This function should only be called once per process - the return
-// value might differ between different calls to this function.
-bool is_process_in_crash_reporting_sample() {
- // TODO(gsennton): update this method to depend on finch when that is
- // implemented for WebView.
- base::Time cur_time = base::Time::Now();
- std::minstd_rand generator(cur_time.ToInternalValue() /* seed */);
- std::uniform_real_distribution<double> distribution(0.0, 1.0);
- return minidump_generation_user_fraction > distribution(generator);
-}
-
class AwCrashReporterClient : public ::crash_reporter::CrashReporterClient {
public:
- AwCrashReporterClient()
- : dump_fd_(kAndroidMinidumpDescriptor),
- crash_signal_fd_(-1),
- in_crash_reporting_sample_(is_process_in_crash_reporting_sample()) {}
-
- // Does not use lock, can only be called immediately after creation.
- void set_crash_signal_fd(int fd) { crash_signal_fd_ = fd; }
+ AwCrashReporterClient() {}
// crash_reporter::CrashReporterClient implementation.
- bool UseCrashKeysWhiteList() override { return true; }
- const char* const* GetCrashKeyWhiteList() override;
-
bool IsRunningUnattended() override { return false; }
- bool GetCollectStatsConsent() override;
- void GetProductNameAndVersion(const char** product_name,
- const char** version) override {
- *product_name = "AndroidWebView";
- *version = PRODUCT_VERSION;
+ bool GetCollectStatsConsent() override {
+ // TODO(jperaza): Crashpad uses GetCollectStatsConsent() to enable or
+ // disable upload of crash reports. However, Crashpad does not yet support
+ // upload on Android, so this return value currently has no effect and
+ // WebView's own uploader will determine consent before uploading. If and
+ // when Crashpad supports upload on Android, consent can be determined here,
+ // or WebView can continue uploading reports itself.
+ return false;
}
+
void GetProductNameAndVersion(std::string* product_name,
std::string* version,
std::string* channel) override {
@@ -76,20 +53,6 @@
*channel =
version_info::GetChannelString(android_webview::GetChannelOrStable());
}
- // Microdumps are always enabled in WebView builds, conversely to what happens
- // in the case of the other Chrome for Android builds (where they are enabled
- // only when NO_UNWIND_TABLES == 1).
- bool ShouldEnableBreakpadMicrodumps() override { return true; }
-
- int GetAndroidMinidumpDescriptor() override { return dump_fd_; }
- int GetAndroidCrashSignalFD() override { return crash_signal_fd_; }
-
- bool DumpWithoutCrashingToFd(int fd) {
- // TODO(tobiasjs): figure out what to do with on demand minidump on the
- // renderer process of webview.
- breakpad::GenerateMinidumpOnDemandForAndroid(fd);
- return true;
- }
bool GetCrashDumpLocation(base::FilePath* crash_dir) override {
return base::PathService::Get(android_webview::DIR_CRASH_DUMPS, crash_dir);
@@ -109,36 +72,21 @@
unsigned int GetCrashDumpPercentageForWebView() override { return 100; }
+ bool GetBrowserProcessType(std::string* ptype) override {
+ *ptype = base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kWebViewSandboxedRenderer)
+ ? "browser"
+ : "webview";
+ return true;
+ }
+
private:
- int dump_fd_;
- int crash_signal_fd_;
- bool in_crash_reporting_sample_;
DISALLOW_COPY_AND_ASSIGN(AwCrashReporterClient);
};
-const char* const* AwCrashReporterClient::GetCrashKeyWhiteList() {
- return crash_keys::kWebViewCrashKeyWhiteList;
-}
-
-bool AwCrashReporterClient::GetCollectStatsConsent() {
-#if defined(GOOGLE_CHROME_BUILD)
- // TODO(gsennton): Enabling minidump-generation unconditionally means we
- // will generate minidumps even if the user doesn't consent to minidump
- // uploads. However, we will check user-consent before uploading any
- // minidumps, if we do not have user consent we will delete the minidumps.
- // We should investigate whether we can avoid generating minidumps
- // altogether if we don't have user consent, see crbug.com/692485
- return in_crash_reporting_sample_;
-#else
- return false;
-#endif // !defined(GOOGLE_CHROME_BUILD)
-}
-
base::LazyInstance<AwCrashReporterClient>::Leaky g_crash_reporter_client =
LAZY_INSTANCE_INITIALIZER;
-bool g_enabled = false;
-
#if defined(ARCH_CPU_X86_FAMILY)
bool SafeToUseSignalHandler() {
// N+ shared library namespacing means that we are unable to dlopen
@@ -198,11 +146,13 @@
} // namespace
-void EnableCrashReporter(const std::string& process_type, int crash_signal_fd) {
- if (g_enabled) {
+void EnableCrashReporter(const std::string& process_type) {
+ static bool enabled;
+ if (enabled) {
NOTREACHED() << "EnableCrashReporter called more than once";
return;
}
+ enabled = true;
#if defined(ARCH_CPU_X86_FAMILY)
if (!SafeToUseSignalHandler()) {
@@ -212,52 +162,13 @@
#endif
AwCrashReporterClient* client = g_crash_reporter_client.Pointer();
- if (process_type == switches::kRendererProcess && crash_signal_fd != -1) {
- client->set_crash_signal_fd(crash_signal_fd);
- }
::crash_reporter::SetCrashReporterClient(client);
- breakpad::SanitizationInfo sanitization_info;
- sanitization_info.should_sanitize_dumps = true;
-#if !defined(COMPONENT_BUILD)
- sanitization_info.skip_dump_if_principal_mapping_not_referenced = true;
- sanitization_info.address_within_principal_mapping =
- reinterpret_cast<uintptr_t>(&EnableCrashReporter);
-#endif // defined(COMPONENT_BUILD)
-
- bool is_browser_process =
- process_type.empty() ||
- process_type == breakpad::kWebViewSingleProcessType ||
- process_type == breakpad::kBrowserProcessType;
- if (is_browser_process) {
- breakpad::InitCrashReporter(process_type, sanitization_info);
- } else {
- breakpad::InitNonBrowserCrashReporterForAndroid(process_type,
- sanitization_info);
- }
- g_enabled = true;
+ ::crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
}
bool GetCrashDumpLocation(base::FilePath* crash_dir) {
return g_crash_reporter_client.Get().GetCrashDumpLocation(crash_dir);
}
-void AddGpuFingerprintToMicrodumpCrashHandler(
- const std::string& gpu_fingerprint) {
- breakpad::AddGpuFingerprintToMicrodumpCrashHandler(gpu_fingerprint);
-}
-
-bool DumpWithoutCrashingToFd(int fd) {
- ::crash_reporter::SetCrashReporterClient(g_crash_reporter_client.Pointer());
- return g_crash_reporter_client.Pointer()->DumpWithoutCrashingToFd(fd);
-}
-
-bool IsCrashReporterEnabled() {
- return breakpad::IsCrashReporterEnabled();
-}
-
-void SuppressDumpGeneration() {
- breakpad::SuppressDumpGeneration();
-}
-
} // namespace crash_reporter
} // namespace android_webview
diff --git a/android_webview/common/crash_reporter/aw_crash_reporter_client.h b/android_webview/common/crash_reporter/aw_crash_reporter_client.h
index 63ceef37..05356d9 100644
--- a/android_webview/common/crash_reporter/aw_crash_reporter_client.h
+++ b/android_webview/common/crash_reporter/aw_crash_reporter_client.h
@@ -14,13 +14,9 @@
namespace android_webview {
namespace crash_reporter {
-void EnableCrashReporter(const std::string& process_type, int crash_signal_fd);
+void EnableCrashReporter(const std::string& process_type);
bool GetCrashDumpLocation(base::FilePath* crash_dir);
-void AddGpuFingerprintToMicrodumpCrashHandler(
- const std::string& gpu_fingerprint);
-bool DumpWithoutCrashingToFd(int fd);
-bool IsCrashReporterEnabled();
-void SuppressDumpGeneration();
+
} // namespace crash_reporter
} // namespace android_webview
diff --git a/android_webview/common/crash_reporter/crash_keys.cc b/android_webview/common/crash_reporter/crash_keys.cc
index e300c40..37d7f59a 100644
--- a/android_webview/common/crash_reporter/crash_keys.cc
+++ b/android_webview/common/crash_reporter/crash_keys.cc
@@ -4,7 +4,7 @@
#include "android_webview/common/crash_reporter/crash_keys.h"
-#include "components/crash/content/app/breakpad_linux.h"
+#include "components/crash/core/common/crash_key.h"
namespace android_webview {
namespace crash_keys {
@@ -55,7 +55,7 @@
// clang-format on
void InitCrashKeysForWebViewTesting() {
- breakpad::InitCrashKeysForTesting();
+ crash_reporter::InitializeCrashKeys();
}
} // namespace crash_keys
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc
index ff7ebf08..0addc54 100644
--- a/android_webview/lib/aw_main_delegate.cc
+++ b/android_webview/lib/aw_main_delegate.cc
@@ -34,7 +34,6 @@
#include "base/threading/thread_restrictions.h"
#include "cc/base/switches.h"
#include "components/autofill/core/common/autofill_features.h"
-#include "components/crash/content/app/breakpad_linux.h"
#include "components/crash/core/common/crash_key.h"
#include "components/safe_browsing/android/safe_browsing_api_handler_bridge.h"
#include "components/services/heap_profiling/public/cpp/allocator_shim.h"
@@ -241,7 +240,6 @@
command_line.GetSwitchValueASCII(switches::kLang));
}
- int crash_signal_fd = -1;
if (process_type == switches::kRendererProcess) {
auto* global_descriptors = base::GlobalDescriptors::GetInstance();
int pak_fd = global_descriptors->Get(kAndroidWebViewLocalePakDescriptor);
@@ -260,19 +258,9 @@
ui::ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion(
base::File(pak_fd), pak_region, pak_info.second);
}
-
- crash_signal_fd =
- global_descriptors->Get(kAndroidWebViewCrashSignalDescriptor);
- }
- if (is_browser_process) {
- if (command_line.HasSwitch(switches::kWebViewSandboxedRenderer)) {
- process_type = breakpad::kBrowserProcessType;
- } else {
- process_type = breakpad::kWebViewSingleProcessType;
- }
}
- crash_reporter::EnableCrashReporter(process_type, crash_signal_fd);
+ crash_reporter::EnableCrashReporter(process_type);
base::android::BuildInfo* android_build_info =
base::android::BuildInfo::GetInstance();
@@ -298,12 +286,6 @@
int exit_code = browser_runner_->Initialize(main_function_params);
DCHECK_LT(exit_code, 0);
- // At this point the content client has received the GPU info required
- // to create a GPU fingerpring, and we can pass it to the microdump
- // crash handler on the same thread as the crash handler was initialized.
- crash_reporter::AddGpuFingerprintToMicrodumpCrashHandler(
- content_client_.gpu_fingerprint());
-
// Return 0 so that we do NOT trigger the default behavior. On Android, the
// UI message loop is managed by the Java application.
return 0;
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 75d238e..62b79d31 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -663,7 +663,6 @@
"//components/background_task_scheduler:background_task_scheduler_task_ids_java",
"//components/bookmarks/common/android:bookmarks_java",
"//components/crash/android:java",
- "//components/crash/android:javatests",
"//components/dom_distiller/core/android:dom_distiller_core_java",
"//components/download/internal/background_service:internal_java",
"//components/download/network:network_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
index 49b4d536..17602b22 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -37,7 +37,8 @@
import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelImpl;
import org.chromium.chrome.browser.webapps.ActivityAssigner;
import org.chromium.chrome.browser.webapps.ChromeWebApkHost;
-import org.chromium.components.crash.browser.CrashDumpManager;
+import org.chromium.components.crash.browser.ChildProcessCrashObserver;
+import org.chromium.components.minidump_uploader.CrashFileManager;
import org.chromium.content_public.browser.BrowserStartupController;
import org.chromium.content_public.browser.DeviceUtils;
import org.chromium.content_public.browser.SpeechRecognition;
@@ -407,15 +408,26 @@
ContentUriUtils.setFileProviderUtil(new FileProviderHelper());
ServiceManagerStartupUtils.registerEnabledFeatures();
- // When a minidump is detected, extract and append a logcat to it, then upload it to the
- // crash server. Note that the logcat extraction might fail. This is ok; in that case, the
- // minidump will be found and uploaded upon the next browser launch.
- CrashDumpManager.registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File minidump) {
- AsyncTask.THREAD_POOL_EXECUTOR.execute(new LogcatExtractionRunnable(minidump));
- }
- });
+ // When a child process crashes, search for the most recent minidump for the child's process
+ // ID and attach a logcat to it. Then upload it to the crash server. Note that the logcat
+ // extraction might fail. This is ok; in that case, the minidump will be found and uploaded
+ // upon the next browser launch.
+ ChildProcessCrashObserver.registerCrashCallback(
+ new ChildProcessCrashObserver.ChildCrashedCallback() {
+ @Override
+ public void childCrashed(int pid) {
+ CrashFileManager crashFileManager = new CrashFileManager(
+ ContextUtils.getApplicationContext().getCacheDir());
+
+ File minidump = crashFileManager.getMinidumpSansLogcatForPid(pid);
+ if (minidump != null) {
+ AsyncTask.THREAD_POOL_EXECUTOR.execute(
+ new LogcatExtractionRunnable(minidump));
+ } else {
+ Log.e(TAG, "Missing dump for child " + pid);
+ }
+ }
+ });
MemoryPressureUma.initializeForBrowser();
if (mTasksToRunWithNative != null) {
diff --git a/chrome/app/chrome_crash_reporter_client.cc b/chrome/app/chrome_crash_reporter_client.cc
index 691a2e1..34ac6e84 100644
--- a/chrome/app/chrome_crash_reporter_client.cc
+++ b/chrome/app/chrome_crash_reporter_client.cc
@@ -50,7 +50,7 @@
ChromeCrashReporterClient::~ChromeCrashReporterClient() {}
-#if !defined(OS_MACOSX)
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
void ChromeCrashReporterClient::SetCrashReporterClientIdFromGUID(
const std::string& client_guid) {
crash_keys::SetMetricsClientIdFromGUID(client_guid);
diff --git a/chrome/app/chrome_crash_reporter_client.h b/chrome/app/chrome_crash_reporter_client.h
index a98b8d4..fa5f6d7 100644
--- a/chrome/app/chrome_crash_reporter_client.h
+++ b/chrome/app/chrome_crash_reporter_client.h
@@ -20,7 +20,7 @@
static void Create();
// crash_reporter::CrashReporterClient implementation.
-#if !defined(OS_MACOSX)
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
void SetCrashReporterClientIdFromGUID(
const std::string& client_guid) override;
#endif
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 2d7e3f23..1b594a1 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -130,7 +130,7 @@
#include "ui/base/x/x11_util.h" // nogncheck
#endif
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
#include "components/crash/content/app/breakpad_linux.h"
#include "v8/include/v8.h"
#endif
@@ -139,7 +139,7 @@
#include "base/environment.h"
#endif
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
#include "chrome/browser/policy/policy_path_parser.h"
#include "components/crash/content/app/crashpad.h"
#endif
@@ -922,12 +922,11 @@
// Zygote needs to call InitCrashReporter() in RunZygote().
if (process_type != service_manager::switches::kZygoteProcess) {
#if defined(OS_ANDROID)
+ crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
if (process_type.empty()) {
- breakpad::InitCrashReporter(process_type);
base::android::InitJavaExceptionReporter();
UninstallPureJavaExceptionHandler();
} else {
- breakpad::InitNonBrowserCrashReporterForAndroid(process_type);
base::android::InitJavaExceptionReporterForChildProcess();
}
#else // !defined(OS_ANDROID)
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc
index 02aac02..d92ad08e 100644
--- a/chrome/browser/chrome_browser_main_android.cc
+++ b/chrome/browser/chrome_browser_main_android.cc
@@ -4,9 +4,6 @@
#include "chrome/browser/chrome_browser_main_android.h"
-#include "base/base_switches.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_current.h"
#include "base/path_service.h"
@@ -17,9 +14,6 @@
#include "chrome/browser/android/seccomp_support_detector.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/descriptors_android.h"
-#include "components/crash/content/app/breakpad_linux.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
#include "components/crash/content/browser/child_process_crash_observer_android.h"
#include "components/metrics/stability_metrics_helper.h"
@@ -47,34 +41,11 @@
int result_code = ChromeBrowserMainParts::PreCreateThreads();
- // The ChildProcessCrashObserver must be registered before any child
- // process is created (as it needs to be notified during child
- // process creation). Such processes are created on the
- // PROCESS_LAUNCHER thread, and so the observer is initialized and
- // the manager registered before that thread is created.
+ // The ChildExitObserver needs to be created before any child process is
+ // created because it needs to be notified during process creation.
crash_reporter::ChildExitObserver::Create();
-
-#if defined(GOOGLE_CHROME_BUILD)
- // TODO(jcivelli): we should not initialize the crash-reporter when it was not
- // enabled. Right now if it is disabled we still generate the minidumps but we
- // do not upload them.
- bool breakpad_enabled = true;
-#else
- bool breakpad_enabled = false;
-#endif
-
- // Allow Breakpad to be enabled in Chromium builds for testing purposes.
- if (!breakpad_enabled)
- breakpad_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableCrashReporterForTesting);
-
- if (breakpad_enabled) {
- base::FilePath crash_dump_dir;
- base::PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_dir);
- crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
- std::make_unique<crash_reporter::ChildProcessCrashObserver>(
- crash_dump_dir, kAndroidMinidumpDescriptor));
- }
+ crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
+ std::make_unique<crash_reporter::ChildProcessCrashObserver>());
return result_code;
}
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index ec2b2a5..ee3d340 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -429,8 +429,10 @@
#endif
#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#if !defined(OS_ANDROID)
#include "base/debug/leak_annotations.h"
#include "components/crash/content/app/breakpad_linux.h"
+#endif // !defined(OS_ANDROID)
#include "components/crash/content/browser/crash_handler_host_linux.h"
#endif
@@ -755,7 +757,11 @@
}
#endif
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
+#if defined(OS_ANDROID)
+int GetCrashSignalFD(const base::CommandLine& command_line) {
+ return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
+}
+#elif defined(OS_POSIX) && !defined(OS_MACOSX)
breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
const std::string& process_type) {
base::FilePath dumps_path;
@@ -830,7 +836,7 @@
return -1;
}
-#endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
+#endif // defined(OS_ANDROID)
void SetApplicationLocaleOnIOThread(const std::string& locale) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -1941,7 +1947,12 @@
client_info->client_id);
}
#elif defined(OS_POSIX)
- if (breakpad::IsCrashReporterEnabled()) {
+#if defined(OS_ANDROID)
+ bool enable_crash_reporter = true;
+#else
+ bool enable_crash_reporter = breakpad::IsCrashReporterEnabled();
+#endif
+ if (enable_crash_reporter) {
std::string switch_value;
std::unique_ptr<metrics::ClientInfo> client_info =
GoogleUpdateSettings::LoadMetricsClientInfo();
@@ -3537,18 +3548,14 @@
mappings->ShareWithRegion(kAndroidSecondaryLocalePakDescriptor, fd, region);
}
- crash_reporter::ChildExitObserver::GetInstance()->BrowserChildProcessStarted(
- child_process_id, mappings);
-
base::FilePath app_data_path;
base::PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data_path);
DCHECK(!app_data_path.empty());
-#else
+#endif // defined(OS_ANDROID)
int crash_signal_fd = GetCrashSignalFD(command_line);
if (crash_signal_fd >= 0) {
mappings->Share(service_manager::kCrashDumpSignal, crash_signal_fd);
}
-#endif // defined(OS_ANDROID)
}
#endif // defined(OS_POSIX) && !defined(OS_MACOSX)
diff --git a/chrome/browser/crash_upload_list/crash_upload_list.cc b/chrome/browser/crash_upload_list/crash_upload_list.cc
index c1bbfc7..a2073c0 100644
--- a/chrome/browser/crash_upload_list/crash_upload_list.cc
+++ b/chrome/browser/crash_upload_list/crash_upload_list.cc
@@ -17,21 +17,25 @@
#endif
#if defined(OS_ANDROID)
+#include "base/android/path_utils.h"
#include "chrome/browser/crash_upload_list/crash_upload_list_android.h"
#endif
scoped_refptr<UploadList> CreateCrashUploadList() {
#if defined(OS_MACOSX) || defined(OS_WIN)
return new CrashUploadListCrashpad();
+#elif defined(OS_ANDROID)
+ base::FilePath cache_dir;
+ base::android::GetCacheDirectory(&cache_dir);
+ base::FilePath upload_log_path =
+ cache_dir.Append("Crash Reports")
+ .AppendASCII(CrashUploadList::kReporterLogFilename);
+ return new CrashUploadListAndroid(upload_log_path);
#else
base::FilePath crash_dir_path;
base::PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dir_path);
base::FilePath upload_log_path =
crash_dir_path.AppendASCII(CrashUploadList::kReporterLogFilename);
-#if defined(OS_ANDROID)
- return new CrashUploadListAndroid(upload_log_path);
-#else
return new TextLogUploadList(upload_log_path);
-#endif // defined(OS_ANDROID)
#endif // defined(OS_MACOSX) || defined(OS_WIN)
}
diff --git a/chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc b/chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc
index eadccef..f1d167b 100644
--- a/chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc
+++ b/chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc
@@ -27,6 +27,8 @@
#include "components/ukm/content/source_url_recorder.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
@@ -42,9 +44,8 @@
#if defined(OS_ANDROID)
#include "chrome/common/descriptors_android.h"
-#include "components/crash/content/browser/child_process_crash_observer_android.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "components/crash/content/browser/child_process_crash_observer_android.h"
#endif
#if defined(OS_ANDROID)
@@ -83,62 +84,6 @@
};
#endif // defined(OS_ANDROID)
-// This class ensures we always have an empty minidump file associated with the
-// process a navigation finishes in.
-class DumpCreator : public content::WebContentsObserver {
- public:
- explicit DumpCreator(content::WebContents* contents)
- : content::WebContentsObserver(contents) {
- CreateDump(contents->GetRenderViewHost()->GetProcess()->GetID(),
- true /*is_empty */);
- }
- ~DumpCreator() override = default;
-
- void CreateDump(int render_process_id, bool is_empty) {
-#if defined(OS_ANDROID)
- // Simulate a call to ChildStart and create an empty crash dump.
- std::string contents = is_empty ? "" : "non empty minidump";
- auto write_task =
- [](int render_process_id, const std::string& contents,
- std::map<int, base::ScopedFD>* rph_id_to_minidump_file) {
- const auto it = rph_id_to_minidump_file->find(render_process_id);
- int fd;
- if (it == rph_id_to_minidump_file->end()) {
- base::ScopedFD minidump =
- breakpad::CrashDumpManager::GetInstance()
- ->CreateMinidumpFileForChild(render_process_id);
- fd = minidump.get();
- (*rph_id_to_minidump_file)[render_process_id] = std::move(minidump);
- } else {
- fd = it->second.get();
- }
- EXPECT_TRUE(
- base::WriteFileDescriptor(fd, contents.data(), contents.size()));
- };
-
- base::RunLoop run_loop;
- base::PostTaskWithTraitsAndReply(
- FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
- base::BindOnce(write_task, render_process_id, contents,
- &rph_id_to_minidump_file_),
- run_loop.QuitClosure());
- run_loop.Run();
-#endif
- }
-
- private:
- // content::WebContentsObserver:
- void DidFinishNavigation(content::NavigationHandle* handle) override {
- CreateDump(
- handle->GetWebContents()->GetRenderViewHost()->GetProcess()->GetID(),
- true /* is_empty */);
- }
-
-#if defined(OS_ANDROID)
- std::map<int, base::ScopedFD> rph_id_to_minidump_file_;
-#endif
-};
-
class OutOfMemoryReporterTest : public ChromeRenderViewHostTestHarness,
public OutOfMemoryReporter::Observer {
public:
@@ -147,18 +92,14 @@
// ChromeRenderViewHostTestHarness:
void SetUp() override {
- ChromeRenderViewHostTestHarness::SetUp();
- EXPECT_NE(content::ChildProcessHost::kInvalidUniqueID, process()->GetID());
#if defined(OS_ANDROID)
crash_reporter::ChildExitObserver::Create();
- base::FilePath crash_dump_dir;
- base::PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_dir);
crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
- std::make_unique<crash_reporter::ChildProcessCrashObserver>(
- crash_dump_dir, kAndroidMinidumpDescriptor));
+ std::make_unique<crash_reporter::ChildProcessCrashObserver>());
#endif
- dump_creator_ = std::make_unique<DumpCreator>(web_contents());
+ ChromeRenderViewHostTestHarness::SetUp();
+ EXPECT_NE(content::ChildProcessHost::kInvalidUniqueID, process()->GetID());
OutOfMemoryReporter::CreateForWebContents(web_contents());
OutOfMemoryReporter* reporter =
@@ -180,8 +121,16 @@
last_oom_url_ = url;
}
+ void SimulateRendererCreated() {
+ content::NotificationService::current()->Notify(
+ content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+ content::Source<content::RenderProcessHost>(process()),
+ content::NotificationService::NoDetails());
+ }
+
void SimulateOOM() {
test_tick_clock_->Advance(base::TimeDelta::FromSeconds(3));
+ SimulateRendererCreated();
#if defined(OS_ANDROID)
process()->SimulateRenderProcessExit(base::TERMINATION_STATUS_OOM_PROTECTED,
0);
@@ -235,17 +184,11 @@
}
}
- void WriteMinidumpFile(bool is_empty) {
- dump_creator_->CreateDump(
- web_contents()->GetRenderViewHost()->GetProcess()->GetID(), is_empty);
- }
-
protected:
base::ShadowingAtExitManager at_exit_;
base::Optional<GURL> last_oom_url_;
std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
- std::unique_ptr<DumpCreator> dump_creator_;
private:
base::SimpleTestTickClock* test_tick_clock_;
@@ -266,8 +209,10 @@
TEST_F(OutOfMemoryReporterTest, NormalCrash_NoOOM) {
const GURL url("https://example.test/");
NavigateAndCommit(url);
+ SimulateRendererCreated();
#if defined(OS_ANDROID)
- WriteMinidumpFile(false /*is_empty */);
+ crash_reporter::ChildExitObserver::GetInstance()->ChildReceivedCrashSignal(
+ process()->GetProcess().Handle(), SIGSEGV);
#endif
RunCrashClosureAndWait(
base::BindOnce(&content::MockRenderProcessHost::SimulateRenderProcessExit,
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index 6cc2c913..cac96e6 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -232,7 +232,7 @@
if (!GetDefaultUserDataDirectory(&cur))
return false;
#endif
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
cur = cur.Append(FILE_PATH_LITERAL("Crashpad"));
#else
cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn
index 1e2ae17..154675f 100644
--- a/chromecast/android/BUILD.gn
+++ b/chromecast/android/BUILD.gn
@@ -26,6 +26,7 @@
"//chromecast/base/metrics",
"//chromecast/browser",
"//components/crash/android:crash_android",
+ "//components/minidump_uploader",
"//content/public/app:both",
"//content/public/browser",
"//skia",
diff --git a/chromecast/app/BUILD.gn b/chromecast/app/BUILD.gn
index 271343d..5166e88 100644
--- a/chromecast/app/BUILD.gn
+++ b/chromecast/app/BUILD.gn
@@ -64,7 +64,6 @@
"//chromecast/base:cast_sys_info",
"//chromecast/base:cast_version",
"//chromecast/browser:jni_headers",
- "//third_party/breakpad:client",
]
}
}
diff --git a/chromecast/app/android/DEPS b/chromecast/app/android/DEPS
index 8bb2b12..01e92c2 100644
--- a/chromecast/app/android/DEPS
+++ b/chromecast/app/android/DEPS
@@ -3,5 +3,4 @@
"+chromecast/browser/android",
"+jni",
"+services/service_manager/embedder",
- "+third_party/breakpad",
]
diff --git a/chromecast/app/android/cast_crash_reporter_client_android.cc b/chromecast/app/android/cast_crash_reporter_client_android.cc
index 005c554..42184357e 100644
--- a/chromecast/app/android/cast_crash_reporter_client_android.cc
+++ b/chromecast/app/android/cast_crash_reporter_client_android.cc
@@ -25,17 +25,6 @@
}
void CastCrashReporterClientAndroid::GetProductNameAndVersion(
- const char** product_name,
- const char** version) {
- *product_name = "media_shell";
- *version = PRODUCT_VERSION
-#if CAST_IS_DEBUG_BUILD()
- ".debug"
-#endif
- "." CAST_BUILD_REVISION;
-}
-
-void CastCrashReporterClientAndroid::GetProductNameAndVersion(
std::string* product_name,
std::string* version,
std::string* channel) {
@@ -54,7 +43,7 @@
}
// static
-bool CastCrashReporterClientAndroid::GetCrashDumpLocation(
+bool CastCrashReporterClientAndroid::GetCrashReportsLocation(
const std::string& process_type,
base::FilePath* crash_dir) {
base::FilePath crash_dir_local;
@@ -79,8 +68,13 @@
bool CastCrashReporterClientAndroid::GetCrashDumpLocation(
base::FilePath* crash_dir) {
- return CastCrashReporterClientAndroid::GetCrashDumpLocation(process_type_,
- crash_dir);
+ base::FilePath app_data;
+ if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data)) {
+ return false;
+ }
+
+ *crash_dir = app_data.Append("Crashpad");
+ return true;
}
bool CastCrashReporterClientAndroid::GetCollectStatsConsent() {
diff --git a/chromecast/app/android/cast_crash_reporter_client_android.h b/chromecast/app/android/cast_crash_reporter_client_android.h
index 38557d0..139d4ba 100644
--- a/chromecast/app/android/cast_crash_reporter_client_android.h
+++ b/chromecast/app/android/cast_crash_reporter_client_android.h
@@ -19,12 +19,11 @@
explicit CastCrashReporterClientAndroid(const std::string& process_type);
~CastCrashReporterClientAndroid() override;
- static bool GetCrashDumpLocation(const std::string& process_type,
- base::FilePath* crash_dir);
+ // Return the path to a directory of MIME-encoded crash reports.
+ static bool GetCrashReportsLocation(const std::string& process_type,
+ base::FilePath* crash_dir);
// crash_reporter::CrashReporterClient implementation:
- void GetProductNameAndVersion(const char** product_name,
- const char** version) override;
void GetProductNameAndVersion(std::string* product_name,
std::string* version,
std::string* channel) override;
diff --git a/chromecast/app/android/crash_handler.cc b/chromecast/app/android/crash_handler.cc
index 56d0434..4bdef99 100644
--- a/chromecast/app/android/crash_handler.cc
+++ b/chromecast/app/android/crash_handler.cc
@@ -16,13 +16,10 @@
#include "chromecast/app/android/cast_crash_reporter_client_android.h"
#include "chromecast/base/chromecast_config_android.h"
#include "chromecast/base/version.h"
-#include "components/crash/content/app/breakpad_linux.h"
#include "components/crash/content/app/crash_reporter_client.h"
+#include "components/crash/content/app/crashpad.h"
#include "content/public/common/content_switches.h"
#include "jni/CastCrashHandler_jni.h"
-#include "services/service_manager/embedder/switches.h"
-#include "third_party/breakpad/breakpad/src/client/linux/handler/exception_handler.h"
-#include "third_party/breakpad/breakpad/src/client/linux/handler/minidump_descriptor.h"
namespace {
@@ -47,6 +44,13 @@
crash_dir);
}
+// static
+bool CrashHandler::GetCrashReportsLocation(base::FilePath* reports_dir) {
+ DCHECK(g_crash_handler);
+ return g_crash_handler->crash_reporter_client_->GetCrashReportsLocation(
+ g_crash_handler->process_type_, reports_dir);
+}
+
CrashHandler::CrashHandler(const std::string& process_type,
const base::FilePath& log_file_path)
: log_file_path_(log_file_path),
@@ -64,22 +68,19 @@
}
void CrashHandler::Initialize() {
- if (process_type_.empty()) {
- breakpad::InitCrashReporter(process_type_);
- return;
- }
- if (process_type_ != service_manager::switches::kZygoteProcess) {
- breakpad::InitNonBrowserCrashReporterForAndroid(process_type_);
- }
+ crash_reporter::InitializeCrashpad(process_type_.empty(), process_type_);
}
// static
void CrashHandler::UploadDumps(const base::FilePath& crash_dump_path,
+ const base::FilePath& reports_path,
const std::string& uuid,
const std::string& application_feedback) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jstring> crash_dump_path_java =
base::android::ConvertUTF8ToJavaString(env, crash_dump_path.value());
+ base::android::ScopedJavaLocalRef<jstring> reports_path_java =
+ base::android::ConvertUTF8ToJavaString(env, reports_path.value());
base::android::ScopedJavaLocalRef<jstring> uuid_java =
base::android::ConvertUTF8ToJavaString(env, uuid);
base::android::ScopedJavaLocalRef<jstring> application_feedback_java =
@@ -90,11 +91,13 @@
android::ChromecastConfigAndroid::GetInstance()->CanSendUsageStats();
if (can_send_usage_stats) {
- Java_CastCrashHandler_uploadOnce(env, crash_dump_path_java, uuid_java,
+ Java_CastCrashHandler_uploadOnce(env, crash_dump_path_java,
+ reports_path_java, uuid_java,
application_feedback_java,
/* UploadToStaging = */ false);
} else {
- Java_CastCrashHandler_removeCrashDumps(env, crash_dump_path_java, uuid_java,
+ Java_CastCrashHandler_removeCrashDumps(env, crash_dump_path_java,
+ reports_path_java, uuid_java,
application_feedback_java,
/* UploadToStaging = */ false);
}
diff --git a/chromecast/app/android/crash_handler.h b/chromecast/app/android/crash_handler.h
index 8a3c5b0..6af19a67 100644
--- a/chromecast/app/android/crash_handler.h
+++ b/chromecast/app/android/crash_handler.h
@@ -24,9 +24,17 @@
static void Initialize(const std::string& process_type,
const base::FilePath& log_file_path);
- // Returns the directory location for crash dumps.
+ // Returns the directory location to use for a crashpad::CrashReportDatabase
+ // of raw minidump files. Prior to upload, these files are re-written as MIME
+ // multipart messages allowing upload metadata and attachments to be included
+ // as parts of the message.
static bool GetCrashDumpLocation(base::FilePath* crash_dir);
+
+ // Returns the directory of crash reports re-written as MIME messages.
+ static bool GetCrashReportsLocation(base::FilePath* reports_dir);
+
static void UploadDumps(const base::FilePath& crash_dump_path,
+ const base::FilePath& reports_path,
const std::string& uuid,
const std::string& application_feedback);
diff --git a/chromecast/app/cast_main_delegate.cc b/chromecast/app/cast_main_delegate.cc
index fce86db..1e43be0 100644
--- a/chromecast/app/cast_main_delegate.cc
+++ b/chromecast/app/cast_main_delegate.cc
@@ -99,7 +99,7 @@
if (process_type.empty()) {
// Get a listing of all of the crash dump files.
base::FilePath crash_directory;
- if (CastCrashReporterClientAndroid::GetCrashDumpLocation(
+ if (CastCrashReporterClientAndroid::GetCrashReportsLocation(
process_type, &crash_directory)) {
base::FileEnumerator crash_directory_list(crash_directory, false,
base::FileEnumerator::FILES);
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn
index e0c54182..93952de 100644
--- a/chromecast/browser/android/BUILD.gn
+++ b/chromecast/browser/android/BUILD.gn
@@ -143,6 +143,7 @@
"//components/crash/android:java",
"//components/embedder_support/android:content_view_java",
"//components/embedder_support/android:view_java",
+ "//components/minidump_uploader:minidump_uploader_java",
"//content/public/android:content_java",
"//media/base/android:media_java",
"//net/android:net_java",
diff --git a/chromecast/browser/android/DEPS b/chromecast/browser/android/DEPS
index 0a2a2f05..302002c 100644
--- a/chromecast/browser/android/DEPS
+++ b/chromecast/browser/android/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+components/embedder_support/android",
+ "+components/minidump_uploader",
"+content/public/android",
"+jni",
"+ui/android",
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
index 7dc4268..f449108 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
@@ -15,18 +15,18 @@
private static final String TAG = "cr_CastCrashHandler";
@CalledByNative
- public static void uploadOnce(String crashDumpPath, String uuid, String applicationFeedback,
- boolean uploadCrashToStaging) {
+ public static void uploadOnce(String crashDumpPath, String crashReportsPath, String uuid,
+ String applicationFeedback, boolean uploadCrashToStaging) {
CastCrashUploader uploader = CastCrashUploaderFactory.createCastCrashUploader(
- crashDumpPath, uuid, applicationFeedback, uploadCrashToStaging);
+ crashDumpPath, crashReportsPath, uuid, applicationFeedback, uploadCrashToStaging);
uploader.uploadOnce();
}
@CalledByNative
- public static void removeCrashDumps(String crashDumpPath, String uuid,
+ public static void removeCrashDumps(String crashDumpPath, String crashReportsPath, String uuid,
String applicationFeedback, boolean uploadCrashToStaging) {
CastCrashUploader uploader = CastCrashUploaderFactory.createCastCrashUploader(
- crashDumpPath, uuid, applicationFeedback, uploadCrashToStaging);
+ crashDumpPath, crashReportsPath, uuid, applicationFeedback, uploadCrashToStaging);
uploader.removeCrashDumps();
}
}
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
index 14307bb2..53d247bd 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
@@ -5,6 +5,7 @@
package org.chromium.chromecast.shell;
import org.chromium.base.Log;
+import org.chromium.components.minidump_uploader.CrashReportMimeWriter;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
@@ -44,17 +45,19 @@
private final ScheduledExecutorService mExecutorService;
private final ElidedLogcatProvider mLogcatProvider;
private final String mCrashDumpPath;
+ private final String mCrashReportPath;
private final String mCrashReportUploadUrl;
private final String mUuid;
private final String mApplicationFeedback;
private final Runnable mQueueAllCrashDumpUploadsRunnable = () -> checkForCrashDumps();
public CastCrashUploader(ScheduledExecutorService executorService,
- ElidedLogcatProvider logcatProvider, String crashDumpPath, String uuid,
- String applicationFeedback, boolean uploadCrashToStaging) {
+ ElidedLogcatProvider logcatProvider, String crashDumpPath, String crashReportPath,
+ String uuid, String applicationFeedback, boolean uploadCrashToStaging) {
mExecutorService = executorService;
mLogcatProvider = logcatProvider;
mCrashDumpPath = crashDumpPath;
+ mCrashReportPath = crashReportPath;
mUuid = uuid;
mApplicationFeedback = applicationFeedback;
mCrashReportUploadUrl = uploadCrashToStaging
@@ -69,8 +72,8 @@
public void removeCrashDumps() {
Log.i(TAG, "Remove crash dumps");
- File crashDumpDirectory = new File(mCrashDumpPath);
- for (File potentialDump : crashDumpDirectory.listFiles()) {
+ File crashReportDirectory = new File(mCrashReportPath);
+ for (File potentialDump : crashReportDirectory.listFiles()) {
if (potentialDump.getName().matches(DUMP_FILE_REGEX)) {
potentialDump.delete();
}
@@ -89,12 +92,19 @@
Log.i(TAG, "Checking for crash dumps");
File crashDumpDirectory = new File(mCrashDumpPath);
+ File crashReportDirectory = new File(mCrashReportPath);
- int numCrashDumps = crashDumpDirectory.listFiles().length;
+ if (!crashDumpDirectory.isDirectory() || !crashReportDirectory.isDirectory()) {
+ return;
+ }
+
+ CrashReportMimeWriter.rewriteMinidumpsAsMIMEs(crashDumpDirectory, crashReportDirectory);
+
+ int numCrashDumps = crashReportDirectory.listFiles().length;
if (numCrashDumps > 0) {
Log.i(TAG, numCrashDumps + " crash dumps found");
mLogcatProvider.getElidedLogcat(
- (String logs) -> queueAllCrashDumpUploadsWithLogs(crashDumpDirectory, logs));
+ (String logs) -> queueAllCrashDumpUploadsWithLogs(crashReportDirectory, logs));
}
}
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploaderFactory.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploaderFactory.java
index c1e1dcb..df3b4347 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploaderFactory.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploaderFactory.java
@@ -13,16 +13,17 @@
*/
public final class CastCrashUploaderFactory {
private static ScheduledExecutorService sExecutorService;
- public static CastCrashUploader createCastCrashUploader(String crashDumpPath, String uuid,
- String applicationFeedback, boolean uploadCrashToStaging) {
+ public static CastCrashUploader createCastCrashUploader(String crashDumpPath,
+ String crashReportsPath, String uuid, String applicationFeedback,
+ boolean uploadCrashToStaging) {
if (sExecutorService == null) {
sExecutorService = Executors.newScheduledThreadPool(1);
}
ElidedLogcatProvider logcatProvider = shouldUseRemoteServiceLogs()
? new ExternalServiceDeviceLogcatProvider()
: new AndroidAppLogcatProvider();
- return new CastCrashUploader(sExecutorService, logcatProvider, crashDumpPath, uuid,
- applicationFeedback, uploadCrashToStaging);
+ return new CastCrashUploader(sExecutorService, logcatProvider, crashDumpPath,
+ crashReportsPath, uuid, applicationFeedback, uploadCrashToStaging);
}
private static boolean shouldUseRemoteServiceLogs() {
@@ -30,4 +31,4 @@
&& !BuildConfig.DEVICE_LOGS_PROVIDER_PACKAGE.equals("")
&& !BuildConfig.DEVICE_LOGS_PROVIDER_CLASS.equals("");
}
-}
\ No newline at end of file
+}
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index add06dc..0e2759f 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -43,7 +43,6 @@
#include "chromecast/browser/tts/tts_platform_stub.h"
#include "chromecast/browser/url_request_context_factory.h"
#include "chromecast/chromecast_buildflags.h"
-#include "chromecast/common/global_descriptors.h"
#include "chromecast/graphics/cast_window_manager.h"
#include "chromecast/media/base/key_systems_common.h"
#include "chromecast/media/base/media_resource_tracker.h"
@@ -416,16 +415,9 @@
int CastBrowserMainParts::PreCreateThreads() {
#if defined(OS_ANDROID)
- // GPU process is started immediately after threads are created,
- // requiring ChildProcessCrashObserver to be initialized beforehand.
- base::FilePath crash_dumps_dir;
- if (!chromecast::CrashHandler::GetCrashDumpLocation(&crash_dumps_dir)) {
- LOG(ERROR) << "Could not find crash dump location.";
- }
crash_reporter::ChildExitObserver::Create();
crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
- std::make_unique<crash_reporter::ChildProcessCrashObserver>(
- crash_dumps_dir, kAndroidMinidumpDescriptor));
+ std::make_unique<crash_reporter::ChildProcessCrashObserver>());
#endif
cast_browser_process_->SetPrefService(
@@ -598,7 +590,9 @@
void CastBrowserMainParts::OnStartPeriodicCrashReportUpload() {
base::FilePath crash_dir;
CrashHandler::GetCrashDumpLocation(&crash_dir);
- CrashHandler::UploadDumps(crash_dir, "", "");
+ base::FilePath reports_dir;
+ CrashHandler::GetCrashReportsLocation(&reports_dir);
+ CrashHandler::UploadDumps(crash_dir, reports_dir, "", "");
}
#endif // defined(OS_ANDROID)
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 2ecb3e5..ce183fb 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -90,14 +90,17 @@
#endif // ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS
#if defined(OS_LINUX) || defined(OS_ANDROID)
-#include "components/crash/content/app/breakpad_linux.h"
#include "components/crash/content/browser/crash_handler_host_linux.h"
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+#if defined(OS_LINUX)
+#include "components/crash/content/app/breakpad_linux.h"
+#endif // defined(OS_LINUX)
+
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
#include "components/cdm/browser/cdm_message_filter_android.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
+#include "components/crash/content/app/crashpad.h"
#include "media/mojo/services/android_mojo_media_client.h"
#if !BUILDFLAG(USE_CHROMECAST_CDMS)
#include "components/cdm/browser/media_drm_storage_impl.h"
@@ -482,12 +485,19 @@
base::CommandLine::ForCurrentProcess();
#if !defined(OS_FUCHSIA)
+#if defined(OS_ANDROID)
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableCrashReporter)) {
+ command_line->AppendSwitch(switches::kEnableCrashReporter);
+ }
+#else
// IsCrashReporterEnabled() is set when InitCrashReporter() is called, and
// controlled by GetBreakpadClient()->EnableBreakpadForProcess(), therefore
// it's ok to add switch to every process here.
if (breakpad::IsCrashReporterEnabled()) {
command_line->AppendSwitch(switches::kEnableCrashReporter);
}
+#endif // defined(OS_ANDROID)
#endif // !defined(OS_FUCHSIA)
// Command-line for different processes.
@@ -782,9 +792,8 @@
kAndroidPakDescriptor,
base::GlobalDescriptors::GetInstance()->Get(kAndroidPakDescriptor),
base::GlobalDescriptors::GetInstance()->GetRegion(kAndroidPakDescriptor));
- crash_reporter::ChildExitObserver::GetInstance()->BrowserChildProcessStarted(
- child_process_id, mappings);
-#elif !defined(OS_FUCHSIA)
+#endif // defined(OS_ANDROID)
+#if !defined(OS_FUCHSIA)
// TODO(crbug.com/753619): Enable crash reporting on Fuchsia.
int crash_signal_fd = GetCrashSignalFD(command_line);
if (crash_signal_fd >= 0) {
@@ -828,7 +837,12 @@
return nullptr;
}
-#if !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#if defined(OS_ANDROID)
+int CastContentBrowserClient::GetCrashSignalFD(
+ const base::CommandLine& command_line) {
+ return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
+}
+#elif !defined(OS_FUCHSIA)
int CastContentBrowserClient::GetCrashSignalFD(
const base::CommandLine& command_line) {
std::string process_type =
@@ -866,7 +880,7 @@
crash_handler->StartUploaderThread();
return crash_handler;
}
-#endif // !defined(OS_ANDROID)
+#endif // defined(OS_ANDROID)
std::vector<std::unique_ptr<content::NavigationThrottle>>
CastContentBrowserClient::CreateThrottlesForNavigation(
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index a1fb844e..67fceb5 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -234,10 +234,11 @@
scoped_refptr<net::SSLPrivateKey>)>&
continue_callback);
-#if !defined(OS_ANDROID)
+#if !defined(OS_FUCHSIA)
// Returns the crash signal FD corresponding to the current process type.
int GetCrashSignalFD(const base::CommandLine& command_line);
+#if !defined(OS_ANDROID)
// Creates a CrashHandlerHost instance for the given process type.
breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
const std::string& process_type);
@@ -249,6 +250,7 @@
// with OS for this).
std::unique_ptr<MemoryPressureControllerImpl> memory_pressure_controller_;
#endif // !defined(OS_ANDROID)
+#endif // !defined(OS_FUCHSIA)
#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND)
// CMA thread used by AudioManager, MojoRenderer, and MediaPipelineBackend.
diff --git a/components/crash/android/BUILD.gn b/components/crash/android/BUILD.gn
index 1212d3de..c61e671 100644
--- a/components/crash/android/BUILD.gn
+++ b/components/crash/android/BUILD.gn
@@ -6,7 +6,6 @@
_jni_sources = [
"java/src/org/chromium/components/crash/browser/ChildProcessCrashObserver.java",
- "java/src/org/chromium/components/crash/browser/CrashDumpManager.java",
"java/src/org/chromium/components/crash/browser/PackagePaths.java",
"java/src/org/chromium/components/crash/CrashKeys.java",
]
@@ -42,18 +41,6 @@
]
}
-android_library("javatests") {
- testonly = true
- deps = [
- ":java",
- "//base:base_java",
- "//base:base_java_test_support",
- "//third_party/android_support_test_runner:runner_java",
- "//third_party/junit",
- ]
- java_files = [ "javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java" ]
-}
-
source_set("unit_tests") {
testonly = true
sources = [
diff --git a/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java b/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java
deleted file mode 100644
index 4955561..0000000
--- a/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.components.crash.browser;
-
-import org.chromium.base.Log;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.CalledByNative;
-
-import java.io.File;
-
-/**
- * A Java-side bridge for continuing the upload processing for child process crash minidumps.
- */
-public class CrashDumpManager {
- private static final String TAG = "CrashDumpManager";
-
- /**
- * An interface for providing a callback that will try to upload a minidump. The callback should
- * be registered on, and will be run on, the UI thread.
- */
- public interface UploadMinidumpCallback { public void tryToUploadMinidump(File minidump); }
-
- /**
- * The globally registered callback for uploading minidumps, or null if no callback has been
- * registered yet.
- */
- private static UploadMinidumpCallback sCallback;
-
- /**
- * Registers a callback for uploading minidumps. May be called at most once, and only on the UI
- * thread.
- *
- * @param callback The callback to trigger when a new minidump is generated by a child process.
- */
- public static void registerUploadCallback(UploadMinidumpCallback callback) {
- ThreadUtils.assertOnUiThread();
- assert sCallback == null;
- sCallback = callback;
- }
-
- /**
- * Attempts to upload the specified child process minidump (or a no-op if no observer has been
- * registered).
- *
- * @param minidumpPath The file path for the generated minidump.
- */
- @CalledByNative
- public static void tryToUploadMinidump(String minidumpPath) {
- // The C++ code that calls into this method should be running on a background thread. It's
- // important to be off the UI thread for the file operations done below.
- ThreadUtils.assertOnBackgroundThread();
-
- if (minidumpPath == null) {
- Log.e(TAG, "Minidump path should be non-null! Bailing...");
- return;
- }
-
- final File minidump = new File(minidumpPath);
- if (!minidump.exists() || !minidump.isFile()) {
- Log.e(TAG,
- "Minidump path '" + minidumpPath
- + "' should describe a file that exists! Bailing...");
- return;
- }
-
- // The callback should only be accessed on the UI thread.
- ThreadUtils.postOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (sCallback == null) {
- Log.w(TAG, "Ignoring crash observed before a callback was registered...");
- return;
- }
- sCallback.tryToUploadMinidump(minidump);
- }
- });
- }
-}
diff --git a/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java b/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
deleted file mode 100644
index cbcbaf1..0000000
--- a/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.components.crash.browser;
-
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.TestFileUtil;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Unittests for {@link CrashDumpManager}.
- */
-@RunWith(BaseJUnit4ClassRunner.class)
-public class CrashDumpManagerTest {
- File mTempDir;
-
- @Before
- public void setUp() throws Exception {
- ContextUtils.initApplicationContextForTests(InstrumentationRegistry.getInstrumentation()
- .getTargetContext()
- .getApplicationContext());
- mTempDir = ContextUtils.getApplicationContext().getCacheDir();
- assert mTempDir.exists();
- }
-
- @After
- public void tearDown() throws Exception {
- File[] files = mTempDir.listFiles();
- if (files == null) return;
-
- for (File file : files) {
- TestFileUtil.deleteFile(file);
- }
- }
-
- @Test
- @SmallTest
- @Feature({"Android-AppBase"})
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_NoCallback() throws IOException {
- File minidump = new File(mTempDir, "mini.dmp");
- Assert.assertTrue(minidump.createNewFile());
-
- CrashDumpManager.tryToUploadMinidump(minidump.getAbsolutePath());
- }
-
- @Test
- @SmallTest
- @Feature({"Android-AppBase"})
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_NullMinidumpPath() {
- registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File minidump) {
- Assert.fail("The callback should not be called when the minidump path is null.");
- }
- });
-
- CrashDumpManager.tryToUploadMinidump(null);
- }
-
- // @SmallTest
- // @Feature({"Android-AppBase"})
- @Test
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_FileDoesntExist() {
- registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File minidump) {
- Assert.fail(
- "The callback should not be called when the minidump file doesn't exist.");
- }
- });
-
- CrashDumpManager.tryToUploadMinidump(
- mTempDir.getAbsolutePath() + "/some/file/that/doesnt/exist");
- }
-
- @Test
- @SmallTest
- @Feature({"Android-AppBase"})
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_MinidumpPathIsDirectory() throws IOException {
- File directory = new File(mTempDir, "a_directory");
- Assert.assertTrue(directory.mkdir());
-
- registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File minidump) {
- Assert.fail(
- "The callback should not be called when the minidump path is not a file.");
- }
- });
-
- CrashDumpManager.tryToUploadMinidump(directory.getAbsolutePath());
- }
-
- @Test
- @SmallTest
- @Feature({"Android-AppBase"})
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_MinidumpPathIsValid() throws IOException {
- final File minidump = new File(mTempDir, "mini.dmp");
- Assert.assertTrue(minidump.createNewFile());
-
- registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File actualMinidump) {
- Assert.assertEquals("Should call the callback with the correct filename.", minidump,
- actualMinidump);
- }
- });
-
- CrashDumpManager.tryToUploadMinidump(minidump.getAbsolutePath());
- }
-
- /**
- * A convenience wrapper that registers the upload {@param callback}, running the registration
- * on the UI thread, as expected by the CrashDumpManager code.
- * @param callback The callback for uploading minidumps.
- */
- private static void registerUploadCallback(
- final CrashDumpManager.UploadMinidumpCallback callback) {
- ThreadUtils.runOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- CrashDumpManager.registerUploadCallback(callback);
- }
- });
- }
-}
diff --git a/components/crash/content/app/BUILD.gn b/components/crash/content/app/BUILD.gn
index 851190e3..cd4dac9 100644
--- a/components/crash/content/app/BUILD.gn
+++ b/components/crash/content/app/BUILD.gn
@@ -36,17 +36,17 @@
sources += [ "crashpad.cc" ]
}
- if (is_android || is_linux) {
- # Want these files on both Linux and Android.
+ if (is_android || (is_linux && !is_chromeos)) {
set_sources_assignment_filter([])
+ sources += [ "crashpad_linux.cc" ]
+ }
+
+ if (is_linux) {
sources += [
"breakpad_linux.cc",
"breakpad_linux.h",
"breakpad_linux_impl.h",
]
- if (!is_chromeos) {
- sources += [ "crashpad_linux.cc" ]
- }
}
defines = [ "CRASH_IMPLEMENTATION" ]
@@ -77,9 +77,12 @@
"//content/public/common:content_descriptors",
"//content/public/common:result_codes",
"//sandbox",
- "//third_party/breakpad:client",
"//third_party/crashpad/crashpad/snapshot",
]
+
+ if (is_linux) {
+ deps += [ "//third_party/breakpad:client" ]
+ }
}
if (is_win) {
diff --git a/components/crash/content/app/crash_reporter_client.cc b/components/crash/content/app/crash_reporter_client.cc
index f08b9b24..b3b09cee 100644
--- a/components/crash/content/app/crash_reporter_client.cc
+++ b/components/crash/content/app/crash_reporter_client.cc
@@ -36,7 +36,7 @@
CrashReporterClient::CrashReporterClient() {}
CrashReporterClient::~CrashReporterClient() {}
-#if !defined(OS_MACOSX) && !defined(OS_WIN)
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_ANDROID)
void CrashReporterClient::SetCrashReporterClientIdFromGUID(
const std::string& client_guid) {}
#endif
@@ -152,6 +152,10 @@
return 100;
}
+bool CrashReporterClient::GetBrowserProcessType(std::string* ptype) {
+ return false;
+}
+
int CrashReporterClient::GetAndroidMinidumpDescriptor() {
return 0;
}
diff --git a/components/crash/content/app/crash_reporter_client.h b/components/crash/content/app/crash_reporter_client.h
index 33a946a..caebf67 100644
--- a/components/crash/content/app/crash_reporter_client.h
+++ b/components/crash/content/app/crash_reporter_client.h
@@ -36,14 +36,14 @@
CrashReporterClient();
virtual ~CrashReporterClient();
-#if !defined(OS_MACOSX) && !defined(OS_WIN)
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_ANDROID)
// Sets the crash reporting client ID, a unique identifier for the client
// that is sending crash reports. After it is set, it should not be changed.
// |client_guid| may either be a full GUID or a GUID that was already stripped
// from its dashes.
//
- // On Mac OS X and Windows, this is the responsibility of Crashpad, and can
- // not be set directly by the client.
+ // On macOS, Windows, and Android this is the responsibility of Crashpad, and
+ // can not be set directly by the client.
virtual void SetCrashReporterClientIdFromGUID(const std::string& client_guid);
#endif
@@ -158,6 +158,10 @@
// percentage.
virtual unsigned int GetCrashDumpPercentageForWebView();
+ // Returns true if |ptype| was set to a value to override the default `ptype`
+ // annotation used for the browser process.
+ virtual bool GetBrowserProcessType(std::string* ptype);
+
// Returns the descriptor key of the android minidump global descriptor.
virtual int GetAndroidMinidumpDescriptor();
diff --git a/components/crash/content/app/crashpad.cc b/components/crash/content/app/crashpad.cc
index 0981ca31..a04a4d84 100644
--- a/components/crash/content/app/crashpad.cc
+++ b/components/crash/content/app/crashpad.cc
@@ -271,6 +271,12 @@
}
#endif
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+void CrashWithoutDumping(const std::string& message) {
+ crashpad::CrashpadClient::CrashWithoutDump(message);
+}
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+
void GetReports(std::vector<Report>* reports) {
#if defined(OS_WIN)
// On Windows, the crash client may be linked into another module, which
diff --git a/components/crash/content/app/crashpad.h b/components/crash/content/app/crashpad.h
index 847b6f0..c16f6b87 100644
--- a/components/crash/content/app/crashpad.h
+++ b/components/crash/content/app/crashpad.h
@@ -130,6 +130,12 @@
void DumpWithoutCrashing();
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+// Logs message and immediately crashes the current process without triggering a
+// crash dump.
+void CrashWithoutDumping(const std::string& message);
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+
// Returns the Crashpad database path, only valid in the browser.
base::FilePath GetCrashpadDatabasePath();
diff --git a/components/crash/content/app/crashpad_linux.cc b/components/crash/content/app/crashpad_linux.cc
index 79b19cc..d13f851 100644
--- a/components/crash/content/app/crashpad_linux.cc
+++ b/components/crash/content/app/crashpad_linux.cc
@@ -466,6 +466,13 @@
BuildHandlerArgs(client, &database_path, &metrics_path, &url,
&process_annotations, &arguments);
+#if defined(OS_ANDROID)
+ std::string browser_ptype;
+ if (GetCrashReporterClient()->GetBrowserProcessType(&browser_ptype)) {
+ process_annotations["ptype"] = browser_ptype;
+ }
+#endif // defined(OS_ANDROID)
+
base::FilePath exe_dir;
base::FilePath handler_path;
if (!GetHandlerPath(&exe_dir, &handler_path)) {
diff --git a/components/crash/content/browser/BUILD.gn b/components/crash/content/browser/BUILD.gn
index d3dbf58..0f38a770 100644
--- a/components/crash/content/browser/BUILD.gn
+++ b/components/crash/content/browser/BUILD.gn
@@ -15,8 +15,6 @@
"child_exit_observer_android.h",
"child_process_crash_observer_android.cc",
"child_process_crash_observer_android.h",
- "crash_dump_manager_android.cc",
- "crash_dump_manager_android.h",
"crash_memory_metrics_collector_android.cc",
"crash_memory_metrics_collector_android.h",
"crash_metrics_reporter_android.cc",
@@ -28,7 +26,6 @@
"//components/crash/content/app",
"//content/public/browser",
"//content/public/common",
- "//third_party/breakpad:client",
]
if (is_linux || is_android) {
@@ -39,10 +36,14 @@
"crash_handler_host_linux.cc",
"crash_handler_host_linux.h",
]
+ }
+
+ if (!is_chromeos) {
+ deps += [ "//third_party/crashpad/crashpad/client" ]
+ }
+
+ if (!is_android) {
deps += [ "//third_party/breakpad:client" ]
- if (!is_chromeos) {
- deps += [ "//third_party/crashpad/crashpad/client" ]
- }
}
# This is not in the GYP build but this target includes breakpad client
@@ -63,7 +64,6 @@
source_set("unit_tests") {
testonly = true
sources = [
- "crash_dump_manager_android_unittest.cc",
"crash_metrics_reporter_android_unittest.cc",
]
deps = [
diff --git a/components/crash/content/browser/child_exit_observer_android.cc b/components/crash/content/browser/child_exit_observer_android.cc
index 5d9aa4c6..cd62274d37 100644
--- a/components/crash/content/browser/child_exit_observer_android.cc
+++ b/components/crash/content/browser/child_exit_observer_android.cc
@@ -129,20 +129,6 @@
}
}
-void ChildExitObserver::BrowserChildProcessStarted(
- int process_host_id,
- content::PosixFileDescriptorInfo* mappings) {
- std::vector<Client*> registered_clients_copy;
- {
- base::AutoLock auto_lock(registered_clients_lock_);
- for (auto& client : registered_clients_)
- registered_clients_copy.push_back(client.get());
- }
- for (auto* client : registered_clients_copy) {
- client->OnChildStart(process_host_id, mappings);
- }
-}
-
void ChildExitObserver::BrowserChildProcessHostDisconnected(
const content::ChildProcessData& data) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -230,12 +216,18 @@
return;
}
const auto& iter = process_host_id_to_pid_.find(rph->GetID());
- if (iter != process_host_id_to_pid_.end()) {
- if (info.pid == base::kNullProcessHandle) {
- info.pid = iter->second;
- }
- process_host_id_to_pid_.erase(iter);
+ // NOTIFICATION_RENDERER_PROCESS_CLOSED corresponds to death of an underlying
+ // RenderProcess. NOTIFICATION_RENDERER_PROCESS_TERMINATED corresponds to when
+ // the RenderProcessHost's lifetime is ending. Ideally, we'd only listen to
+ // the former, but if the RenderProcessHost is destroyed before the
+ // RenderProcess, then the former is never sent.
+ if (iter == process_host_id_to_pid_.end()) {
+ return;
}
+ if (info.pid == base::kNullProcessHandle) {
+ info.pid = iter->second;
+ }
+ process_host_id_to_pid_.erase(iter);
OnChildExit(&info);
}
diff --git a/components/crash/content/browser/child_exit_observer_android.h b/components/crash/content/browser/child_exit_observer_android.h
index adbccc4..161d2e8 100644
--- a/components/crash/content/browser/child_exit_observer_android.h
+++ b/components/crash/content/browser/child_exit_observer_android.h
@@ -12,7 +12,6 @@
#include "base/android/application_status_listener.h"
#include "base/android/child_process_binding_types.h"
#include "base/lazy_instance.h"
-#include "base/memory/ref_counted.h"
#include "base/process/process.h"
#include "base/scoped_observer.h"
#include "base/synchronization/lock.h"
@@ -20,7 +19,6 @@
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/posix_file_descriptor_info.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/process_type.h"
#include "third_party/blink/public/common/oom_intervention/oom_intervention_types.h"
@@ -46,7 +44,6 @@
TerminationInfo(const TerminationInfo& other);
TerminationInfo& operator=(const TerminationInfo& other);
- // TODO(jperaza): Not valid until Crashpad is enabled.
bool is_crashed() const { return crash_signo != kInvalidSigno; }
int process_host_id = content::ChildProcessHost::kInvalidUniqueID;
@@ -55,7 +52,6 @@
base::android::ApplicationState app_state =
base::android::APPLICATION_STATE_UNKNOWN;
- // TODO(jperaza): Not valid until Crashpad is enabled.
// The crash signal the child process received before it exited.
int crash_signo = kInvalidSigno;
@@ -109,9 +105,6 @@
// process type.
class Client {
public:
- // OnChildStart is called on the launcher thread.
- virtual void OnChildStart(int process_host_id,
- content::PosixFileDescriptorInfo* mappings) = 0;
// OnChildExit is called on the UI thread.
// OnChildExit may be called twice for the same process.
virtual void OnChildExit(const TerminationInfo& info) = 0;
@@ -134,14 +127,6 @@
// crashpad::CrashHandlerHost::Observer
void ChildReceivedCrashSignal(base::ProcessId pid, int signo) override;
- // BrowserChildProcessStarted must be called from
- // ContentBrowserClient::GetAdditionalMappedFilesForChildProcess
- // overrides, to notify the ChildExitObserver of child process
- // creation, and to allow clients to register any fd mappings they
- // need.
- void BrowserChildProcessStarted(int process_host_id,
- content::PosixFileDescriptorInfo* mappings);
-
private:
friend struct base::LazyInstanceTraitsBase<ChildExitObserver>;
diff --git a/components/crash/content/browser/child_process_crash_observer_android.cc b/components/crash/content/browser/child_process_crash_observer_android.cc
index e235ba3..cd46b75b 100644
--- a/components/crash/content/browser/child_process_crash_observer_android.cc
+++ b/components/crash/content/browser/child_process_crash_observer_android.cc
@@ -4,47 +4,45 @@
#include "components/crash/content/browser/child_process_crash_observer_android.h"
-#include <utility>
-
+#include "base/android/jni_android.h"
#include "base/bind.h"
-#include "base/files/file_util.h"
#include "base/task/post_task.h"
-#include "components/crash/content/app/breakpad_linux.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "base/task/task_traits.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "components/crash/content/browser/crash_metrics_reporter_android.h"
+#include "jni/ChildProcessCrashObserver_jni.h"
namespace crash_reporter {
-ChildProcessCrashObserver::ChildProcessCrashObserver(
- const base::FilePath crash_dump_dir,
- int descriptor_id)
- : crash_dump_dir_(crash_dump_dir), descriptor_id_(descriptor_id) {}
-
-ChildProcessCrashObserver::~ChildProcessCrashObserver() {}
-
-void ChildProcessCrashObserver::OnChildStart(
- int process_host_id,
- content::PosixFileDescriptorInfo* mappings) {
- if (!breakpad::IsCrashReporterEnabled())
- return;
-
- base::ScopedFD file(
- breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
- process_host_id));
- if (file.is_valid())
- mappings->Transfer(descriptor_id_, std::move(file));
+ChildProcessCrashObserver::ChildProcessCrashObserver() {
+ task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
}
+ChildProcessCrashObserver::~ChildProcessCrashObserver() = default;
+
void ChildProcessCrashObserver::OnChildExit(
const ChildExitObserver::TerminationInfo& info) {
- // This might be called twice for a given child process, with a
- // NOTIFICATION_RENDERER_PROCESS_TERMINATED and then with
- // NOTIFICATION_RENDERER_PROCESS_CLOSED.
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ChildProcessCrashObserver::OnChildExitImpl,
+ base::Unretained(this), info));
+}
- base::PostTaskWithTraits(
- FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
- base::Bind(&breakpad::CrashDumpManager::ProcessMinidumpFileFromChild,
- base::Unretained(breakpad::CrashDumpManager::GetInstance()),
- crash_dump_dir_, info));
+void ChildProcessCrashObserver::OnChildExitImpl(
+ const ChildExitObserver::TerminationInfo& info) {
+ crash_reporter::CrashMetricsReporter::GetInstance()->ChildProcessExited(info);
+
+ if (!info.is_crashed()) {
+ return;
+ }
+
+ base::ScopedBlockingCall sbc(base::BlockingType::WILL_BLOCK);
+
+ // Hop over to Java to attempt to attach the logcat to the crash. This may
+ // fail, which is ok -- if it does, the crash will still be uploaded on the
+ // next browser start.
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_ChildProcessCrashObserver_childCrashed(env, info.pid);
}
} // namespace crash_reporter
diff --git a/components/crash/content/browser/child_process_crash_observer_android.h b/components/crash/content/browser/child_process_crash_observer_android.h
index 7710e6f..a401459 100644
--- a/components/crash/content/browser/child_process_crash_observer_android.h
+++ b/components/crash/content/browser/child_process_crash_observer_android.h
@@ -5,28 +5,28 @@
#ifndef COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_
#define COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_
-#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequenced_task_runner.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
namespace crash_reporter {
+// Records metrics and initiates minidump upload in response to child process
+// crashes.
class ChildProcessCrashObserver
: public crash_reporter::ChildExitObserver::Client {
public:
- ChildProcessCrashObserver(const base::FilePath crash_dump_dir,
- int descriptor_id);
+ ChildProcessCrashObserver();
~ChildProcessCrashObserver() override;
// crash_reporter::ChildExitObserver::Client implementation:
- void OnChildStart(int process_host_id,
- content::PosixFileDescriptorInfo* mappings) override;
void OnChildExit(const ChildExitObserver::TerminationInfo& info) override;
private:
- base::FilePath crash_dump_dir_;
- // The id used to identify the file descriptor in the set of file
- // descriptor mappings passed to the child process.
- int descriptor_id_;
+ void OnChildExitImpl(const ChildExitObserver::TerminationInfo& info);
+
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(ChildProcessCrashObserver);
};
diff --git a/components/crash/content/browser/crash_dump_manager_android.cc b/components/crash/content/browser/crash_dump_manager_android.cc
deleted file mode 100644
index 07132888..0000000
--- a/components/crash/content/browser/crash_dump_manager_android.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/crash/content/browser/crash_dump_manager_android.h"
-
-#include <stdint.h>
-
-#include <string>
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/files/file_util.h"
-#include "base/format_macros.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/process/process.h"
-#include "base/rand_util.h"
-#include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/scoped_blocking_call.h"
-#include "components/crash/content/app/breakpad_linux.h"
-#include "components/crash/content/browser/crash_metrics_reporter_android.h"
-#include "jni/CrashDumpManager_jni.h"
-
-namespace breakpad {
-
-namespace {
-
-base::LazyInstance<CrashDumpManager>::Leaky g_instance =
- LAZY_INSTANCE_INITIALIZER;
-
-class DefaultUploader : public CrashDumpManager::Uploader {
- public:
- DefaultUploader() = default;
- ~DefaultUploader() override = default;
-
- // CrashDumpManager::Uploader:
- void TryToUploadCrashDump(const base::FilePath& crash_dump_path) override {
- // Hop over to Java to attempt to attach the logcat to the crash. This may
- // fail, which is ok -- if it does, the crash will still be uploaded on the
- // next browser start.
- JNIEnv* env = base::android::AttachCurrentThread();
- base::android::ScopedJavaLocalRef<jstring> j_dump_path =
- base::android::ConvertUTF8ToJavaString(env, crash_dump_path.value());
- Java_CrashDumpManager_tryToUploadMinidump(env, j_dump_path);
- }
-};
-
-} // namespace
-
-// static
-CrashDumpManager* CrashDumpManager::GetInstance() {
- return g_instance.Pointer();
-}
-
-CrashDumpManager::CrashDumpManager()
- : uploader_(std::make_unique<DefaultUploader>()) {}
-
-CrashDumpManager::~CrashDumpManager() {}
-
-base::ScopedFD CrashDumpManager::CreateMinidumpFileForChild(
- int process_host_id) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
- base::FilePath minidump_path;
- if (!base::CreateTemporaryFile(&minidump_path)) {
- LOG(ERROR) << "Failed to create temporary file, crash won't be reported.";
- return base::ScopedFD();
- }
-
- // We need read permission as the minidump is generated in several phases
- // and needs to be read at some point.
- int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
- base::File::FLAG_WRITE;
- base::File minidump_file(minidump_path, flags);
- if (!minidump_file.IsValid()) {
- LOG(ERROR) << "Failed to open temporary file, crash won't be reported.";
- return base::ScopedFD();
- }
-
- SetMinidumpPath(process_host_id, minidump_path);
- return base::ScopedFD(minidump_file.TakePlatformFile());
-}
-
-void CrashDumpManager::ProcessMinidumpFileFromChild(
- base::FilePath crash_dump_dir,
- const crash_reporter::ChildExitObserver::TerminationInfo& info) {
- CrashDumpManager::CrashDumpStatus status =
- ProcessMinidumpFileFromChildInternal(crash_dump_dir, info);
- crash_reporter::CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
- info, status);
-}
-
-CrashDumpManager::CrashDumpStatus
-CrashDumpManager::ProcessMinidumpFileFromChildInternal(
- base::FilePath crash_dump_dir,
- const crash_reporter::ChildExitObserver::TerminationInfo& info) {
- base::FilePath minidump_path;
- // If the minidump for a given child process has already been
- // processed, then there is no more work to do.
- if (!GetMinidumpPath(info.process_host_id, &minidump_path)) {
- return CrashDumpStatus::kMissingDump;
- }
-
- int64_t file_size = 0;
-
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
- if (!base::PathExists(minidump_path)) {
- LOG(ERROR) << "minidump does not exist " << minidump_path.value();
- return CrashDumpStatus::kMissingDump;
- }
-
- int r = base::GetFileSize(minidump_path, &file_size);
- DCHECK(r) << "Failed to retrieve size for minidump " << minidump_path.value();
-
- if (file_size == 0) {
- // Empty minidump, this process did not crash. Just remove the file.
- r = base::DeleteFile(minidump_path, false);
- DCHECK(r) << "Failed to delete temporary minidump file "
- << minidump_path.value();
- return CrashDumpStatus::kEmptyDump;
- }
-
- // We are dealing with a valid minidump. Copy it to the crash report
- // directory from where Java code will upload it later on.
- if (crash_dump_dir.empty()) {
- NOTREACHED() << "Failed to retrieve the crash dump directory.";
- return CrashDumpStatus::kDumpProcessingFailed;
- }
- const uint64_t rand = base::RandUint64();
- const std::string filename =
- base::StringPrintf("chromium-renderer-minidump-%016" PRIx64 ".dmp%d",
- rand, info.process_host_id);
- base::FilePath dest_path = crash_dump_dir.Append(filename);
- r = base::Move(minidump_path, dest_path);
- if (!r) {
- LOG(ERROR) << "Failed to move crash dump from " << minidump_path.value()
- << " to " << dest_path.value();
- base::DeleteFile(minidump_path, false);
- return CrashDumpStatus::kDumpProcessingFailed;
- }
- VLOG(1) << "Crash minidump successfully generated: " << dest_path.value();
-
- uploader_->TryToUploadCrashDump(dest_path);
- return CrashDumpStatus::kValidDump;
-}
-
-void CrashDumpManager::SetMinidumpPath(int process_host_id,
- const base::FilePath& minidump_path) {
- base::AutoLock auto_lock(process_host_id_to_minidump_path_lock_);
- DCHECK(
- !base::ContainsKey(process_host_id_to_minidump_path_, process_host_id));
- process_host_id_to_minidump_path_[process_host_id] = minidump_path;
-}
-
-bool CrashDumpManager::GetMinidumpPath(int process_host_id,
- base::FilePath* minidump_path) {
- base::AutoLock auto_lock(process_host_id_to_minidump_path_lock_);
- ChildProcessIDToMinidumpPath::iterator iter =
- process_host_id_to_minidump_path_.find(process_host_id);
- if (iter == process_host_id_to_minidump_path_.end()) {
- return false;
- }
- *minidump_path = iter->second;
- process_host_id_to_minidump_path_.erase(iter);
- return true;
-}
-
-} // namespace breakpad
diff --git a/components/crash/content/browser/crash_dump_manager_android.h b/components/crash/content/browser/crash_dump_manager_android.h
deleted file mode 100644
index bc10af0..0000000
--- a/components/crash/content/browser/crash_dump_manager_android.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
-#define COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
-
-#include <map>
-#include <memory>
-#include <utility>
-
-#include "base/android/application_status_listener.h"
-#include "base/files/file_path.h"
-#include "base/files/platform_file.h"
-#include "base/lazy_instance.h"
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
-#include "content/public/common/child_process_host.h"
-#include "content/public/common/process_type.h"
-
-namespace breakpad {
-
-// This class manages the crash minidumps.
-// On Android, because of process isolation, each renderer process runs with a
-// different UID. As a result, we cannot generate the minidumps in the browser
-// (as the browser process does not have access to some system files for the
-// crashed process). So the minidump is generated in the renderer process.
-// Since the isolated process cannot open files, we provide it on creation with
-// a file descriptor into which to write the minidump in the event of a crash.
-// This class creates these file descriptors and associates them with render
-// processes and takes the appropriate action when the render process
-// terminates.
-class CrashDumpManager {
- public:
- enum class CrashDumpStatus {
- // The dump for this process did not have a path set. This can happen if the
- // dump was already processed or if crash dump generation is not turned on.
- kMissingDump,
-
- // The crash dump was empty.
- kEmptyDump,
-
- // Minidump file was found, but could not be copied to crash dir.
- kDumpProcessingFailed,
-
- // The crash dump is valid.
- kValidDump,
- };
-
- // Class which aids in uploading a crash dump.
- class Uploader {
- public:
- virtual ~Uploader() = default;
-
- // Attempts to upload the specified child process minidump.
- virtual void TryToUploadCrashDump(
- const base::FilePath& crash_dump_path) = 0;
- };
-
- static CrashDumpManager* GetInstance();
-
- void ProcessMinidumpFileFromChild(
- base::FilePath crash_dump_dir,
- const crash_reporter::ChildExitObserver::TerminationInfo& info);
-
- base::ScopedFD CreateMinidumpFileForChild(int process_host_id);
-
- // Careful, |uploader_| is accessed on one of the task scheduler threads.
- // Tests should set this before any other threads are spawned.
- void set_uploader_for_testing(std::unique_ptr<Uploader> uploader) {
- DCHECK(uploader);
- uploader_ = std::move(uploader);
- }
-
- private:
- friend struct base::LazyInstanceTraitsBase<CrashDumpManager>;
-
- CrashDumpManager();
- ~CrashDumpManager();
-
- CrashDumpStatus ProcessMinidumpFileFromChildInternal(
- base::FilePath crash_dump_dir,
- const crash_reporter::ChildExitObserver::TerminationInfo& info);
-
- typedef std::map<int, base::FilePath> ChildProcessIDToMinidumpPath;
-
- void SetMinidumpPath(int process_host_id,
- const base::FilePath& minidump_path);
- bool GetMinidumpPath(int process_host_id, base::FilePath* minidump_path);
-
- // Should never be nullptr.
- std::unique_ptr<Uploader> uploader_;
-
- // This map should only be accessed with its lock aquired as it is accessed
- // from the PROCESS_LAUNCHER and UI threads.
- base::Lock process_host_id_to_minidump_path_lock_;
- ChildProcessIDToMinidumpPath process_host_id_to_minidump_path_;
-
- DISALLOW_COPY_AND_ASSIGN(CrashDumpManager);
-};
-
-} // namespace breakpad
-
-#endif // COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
diff --git a/components/crash/content/browser/crash_dump_manager_android_unittest.cc b/components/crash/content/browser/crash_dump_manager_android_unittest.cc
deleted file mode 100644
index 0b284e1..0000000
--- a/components/crash/content/browser/crash_dump_manager_android_unittest.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/crash/content/browser/crash_dump_manager_android.h"
-
-#include <string>
-#include <utility>
-
-#include "base/at_exit.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/files/file.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/optional.h"
-#include "base/run_loop.h"
-#include "base/sequenced_task_runner.h"
-#include "base/task/post_task.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/threading/thread_restrictions.h"
-#include "components/crash/content/browser/crash_metrics_reporter_android.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace breakpad {
-
-class CrashDumpManagerTest;
-
-class CrashMetricsReporterObserver
- : public crash_reporter::CrashMetricsReporter::Observer {
- public:
- CrashMetricsReporterObserver() {}
- ~CrashMetricsReporterObserver() {}
-
- // crash_reporter::CrashMetricsReporter::Observer:
- void OnCrashDumpProcessed(
- int rph_id,
- const crash_reporter::CrashMetricsReporter::ReportedCrashTypeSet&
- reported_counts) override {
- wait_run_loop_.QuitClosure().Run();
- }
-
- void WaitForProcessed() { wait_run_loop_.Run(); }
-
- private:
- base::RunLoop wait_run_loop_;
- DISALLOW_COPY_AND_ASSIGN(CrashMetricsReporterObserver);
-};
-
-class NoOpUploader : public CrashDumpManager::Uploader {
- public:
- NoOpUploader(scoped_refptr<base::SequencedTaskRunner> test_runner,
- CrashDumpManagerTest* test_harness)
- : test_runner_(std::move(test_runner)), test_harness_(test_harness) {}
- ~NoOpUploader() override = default;
-
- // CrashDumpManager::Uploader:
- void TryToUploadCrashDump(const base::FilePath& crash_dump_path) override;
-
- private:
- scoped_refptr<base::SequencedTaskRunner> test_runner_;
- CrashDumpManagerTest* test_harness_;
- DISALLOW_COPY_AND_ASSIGN(NoOpUploader);
-};
-
-class CrashDumpManagerTest : public testing::Test {
- public:
- CrashDumpManagerTest()
- : scoped_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
- ~CrashDumpManagerTest() override {}
-
- void SetUp() override {
- // Initialize the manager.
- ASSERT_TRUE(CrashDumpManager::GetInstance());
- CrashDumpManager::GetInstance()->set_uploader_for_testing(
- std::make_unique<NoOpUploader>(base::SequencedTaskRunnerHandle::Get(),
- this));
- }
-
- void OnUploadedCrashDump() {
- dumps_uploaded_++;
- if (!upload_waiter_.is_null())
- std::move(upload_waiter_).Run();
- }
-
- void WaitForCrashDumpsUploaded(int num_dumps) {
- EXPECT_LE(num_dumps, dumps_uploaded_);
- while (num_dumps < dumps_uploaded_) {
- base::RunLoop run_loop;
- upload_waiter_ = run_loop.QuitClosure();
- run_loop.Run();
- }
- }
-
- static void CreateAndProcessCrashDump(
- const crash_reporter::ChildExitObserver::TerminationInfo& info,
- const std::string& data) {
- base::ScopedFD fd =
- CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
- info.process_host_id);
- EXPECT_TRUE(fd.is_valid());
- base::WriteFileDescriptor(fd.get(), data.data(), data.size());
- base::ScopedTempDir dump_dir;
- EXPECT_TRUE(dump_dir.CreateUniqueTempDir());
- CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild(
- dump_dir.GetPath(), info);
- }
-
- protected:
- int dumps_uploaded_ = 0;
-
- private:
- base::ShadowingAtExitManager at_exit_;
- base::test::ScopedTaskEnvironment scoped_environment_;
- base::OnceClosure upload_waiter_;
- DISALLOW_COPY_AND_ASSIGN(CrashDumpManagerTest);
-};
-
-void NoOpUploader::TryToUploadCrashDump(const base::FilePath& crash_dump_path) {
- test_runner_->PostTask(
- FROM_HERE, base::BindOnce(&CrashDumpManagerTest::OnUploadedCrashDump,
- base::Unretained(test_harness_)));
-}
-
-TEST_F(CrashDumpManagerTest, NonOomCrash) {
- base::HistogramTester histogram_tester;
-
- CrashMetricsReporterObserver observer;
- crash_reporter::CrashMetricsReporter::GetInstance()->AddObserver(&observer);
-
- crash_reporter::ChildExitObserver::TerminationInfo termination_info;
- termination_info.process_host_id = 1;
- termination_info.pid = base::kNullProcessHandle;
- termination_info.process_type = content::PROCESS_TYPE_RENDERER;
- termination_info.app_state =
- base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
- termination_info.normal_termination = false;
- termination_info.binding_state = base::android::ChildBindingState::STRONG;
- termination_info.was_killed_intentionally_by_browser = false;
- termination_info.was_oom_protected_status = true;
- base::PostTaskWithTraits(
- FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
- base::BindOnce(&CrashDumpManagerTest::CreateAndProcessCrashDump,
- termination_info, "Some non-empty crash data"));
- observer.WaitForProcessed();
-
- histogram_tester.ExpectUniqueSample(
- "Tab.RendererDetailedExitStatus",
- crash_reporter::CrashMetricsReporter::VALID_MINIDUMP_WHILE_RUNNING, 1);
- WaitForCrashDumpsUploaded(1);
-}
-
-} // namespace breakpad
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.cc b/components/crash/content/browser/crash_metrics_reporter_android.cc
index bf6d85a2..9ddeee9f 100644
--- a/components/crash/content/browser/crash_metrics_reporter_android.cc
+++ b/components/crash/content/browser/crash_metrics_reporter_android.cc
@@ -8,7 +8,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/optional.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "base/rand_util.h"
namespace crash_reporter {
namespace {
@@ -108,35 +108,17 @@
async_observers_->RemoveObserver(observer);
}
-void CrashMetricsReporter::CrashDumpProcessed(
- const ChildExitObserver::TerminationInfo& info,
- breakpad::CrashDumpManager::CrashDumpStatus status) {
+void CrashMetricsReporter::ChildProcessExited(
+ const ChildExitObserver::TerminationInfo& info) {
ReportedCrashTypeSet reported_counts;
-
- // Avoid duplicating processing for the same process.
- if (status == breakpad::CrashDumpManager::CrashDumpStatus::kMissingDump)
- return;
-
- bool has_valid_dump = false;
- switch (status) {
- case breakpad::CrashDumpManager::CrashDumpStatus::kMissingDump:
- NOTREACHED();
- break;
- case breakpad::CrashDumpManager::CrashDumpStatus::kEmptyDump:
- has_valid_dump = false;
- break;
- case breakpad::CrashDumpManager::CrashDumpStatus::kValidDump:
- case breakpad::CrashDumpManager::CrashDumpStatus::kDumpProcessingFailed:
- has_valid_dump = true;
- break;
- }
+ const bool crashed = info.is_crashed();
const bool app_foreground =
info.app_state ==
base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES ||
info.app_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
const bool intentional_kill = info.was_killed_intentionally_by_browser;
const bool android_oom_kill = !info.was_killed_intentionally_by_browser &&
- !has_valid_dump && !info.normal_termination;
+ !crashed && !info.normal_termination;
const bool renderer_visible = info.renderer_has_visible_clients;
const bool renderer_subframe = info.renderer_was_subframe;
const bool renderer_allocation_failed =
@@ -170,7 +152,7 @@
if (info.process_type == content::PROCESS_TYPE_RENDERER && app_foreground) {
if (renderer_visible) {
- if (has_valid_dump) {
+ if (crashed) {
ReportCrashCount(
renderer_subframe
? ProcessedCrashCounts::kRendererForegroundVisibleSubframeCrash
@@ -219,7 +201,7 @@
vm_size_kb / 1024);
}
}
- } else if (!has_valid_dump) {
+ } else if (!crashed) {
// Record stats when renderer is not visible, but the process has oom
// protected bindings. This case occurs when a tab is switched or closed,
// the bindings are updated later than visibility on web contents.
@@ -267,7 +249,7 @@
&reported_counts);
}
- if (has_valid_dump) {
+ if (crashed) {
if (info.process_type == content::PROCESS_TYPE_RENDERER) {
ReportCrashCount(ProcessedCrashCounts::kRendererCrashAll,
&reported_counts);
@@ -305,7 +287,7 @@
info.remaining_process_with_strong_binding, 20);
}
- ReportLegacyCrashUma(info, has_valid_dump);
+ ReportLegacyCrashUma(info, crashed);
NotifyObservers(info.process_host_id, reported_counts);
}
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.h b/components/crash/content/browser/crash_metrics_reporter_android.h
index f098ac2..c2ededf 100644
--- a/components/crash/content/browser/crash_metrics_reporter_android.h
+++ b/components/crash/content/browser/crash_metrics_reporter_android.h
@@ -8,7 +8,6 @@
#include "base/containers/flat_set.h"
#include "base/observer_list_threadsafe.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
namespace crash_reporter {
@@ -75,8 +74,8 @@
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
- void CrashDumpProcessed(const ChildExitObserver::TerminationInfo& info,
- breakpad::CrashDumpManager::CrashDumpStatus status);
+ void ChildProcessExited(
+ const crash_reporter::ChildExitObserver::TerminationInfo& info);
private:
CrashMetricsReporter();
diff --git a/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc b/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
index 380b9ab..a01347f 100644
--- a/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
+++ b/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
@@ -4,6 +4,8 @@
#include "components/crash/content/browser/crash_metrics_reporter_android.h"
+#include <signal.h>
+
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
@@ -47,20 +49,6 @@
base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
~CrashMetricsReporterTest() override {}
- static void CreateAndProcessCrashDump(
- const ChildExitObserver::TerminationInfo& info,
- const std::string& data) {
- base::ScopedFD fd =
- breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
- info.process_host_id);
- EXPECT_TRUE(fd.is_valid());
- base::WriteFileDescriptor(fd.get(), data.data(), data.size());
- base::ScopedTempDir dump_dir;
- EXPECT_TRUE(dump_dir.CreateUniqueTempDir());
- breakpad::CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild(
- dump_dir.GetPath(), info);
- }
-
protected:
blink::OomInterventionMetrics InterventionMetrics(bool allocation_failed) {
blink::OomInterventionMetrics metrics;
@@ -81,9 +69,7 @@
CrashMetricsReporterObserver crash_dump_observer;
CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
- CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
- termination_info,
- breakpad::CrashDumpManager::CrashDumpStatus::kEmptyDump);
+ CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
crash_dump_observer.WaitForProcessed();
EXPECT_EQ(expected_crash_types, crash_dump_observer.recorded_crash_types());
@@ -180,6 +166,7 @@
termination_info.process_type = content::PROCESS_TYPE_UTILITY;
termination_info.app_state =
base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+ termination_info.crash_signo = SIGSEGV;
termination_info.normal_termination = false;
termination_info.binding_state = base::android::ChildBindingState::STRONG;
termination_info.was_killed_intentionally_by_browser = false;
@@ -189,9 +176,7 @@
CrashMetricsReporterObserver crash_dump_observer;
CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
- CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
- termination_info,
- breakpad::CrashDumpManager::CrashDumpStatus::kValidDump);
+ CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
crash_dump_observer.WaitForProcessed();
EXPECT_EQ(CrashMetricsReporter::ReportedCrashTypeSet(
@@ -329,6 +314,7 @@
termination_info.process_type = content::PROCESS_TYPE_RENDERER;
termination_info.app_state =
base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+ termination_info.crash_signo = SIGSEGV;
termination_info.normal_termination = true;
termination_info.binding_state = base::android::ChildBindingState::STRONG;
termination_info.was_killed_intentionally_by_browser = true;
@@ -338,9 +324,7 @@
CrashMetricsReporterObserver crash_dump_observer;
CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
- CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
- termination_info,
- breakpad::CrashDumpManager::CrashDumpStatus::kValidDump);
+ CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
crash_dump_observer.WaitForProcessed();
EXPECT_EQ(
diff --git a/components/crash/core/common/BUILD.gn b/components/crash/core/common/BUILD.gn
index c8e02ebf..81912a5 100644
--- a/components/crash/core/common/BUILD.gn
+++ b/components/crash/core/common/BUILD.gn
@@ -20,7 +20,8 @@
}
}
-use_crashpad_annotation = (is_mac || is_win) && !use_crash_key_stubs
+use_crashpad_annotation =
+ (is_mac || is_win || is_android) && !use_crash_key_stubs
buildflag_header("crash_buildflags") {
header = "crash_buildflags.h"
@@ -143,7 +144,7 @@
sources += [ "objc_zombie_unittest.mm" ]
}
- if (!is_mac && !is_win && !is_fuchsia) {
+ if (!is_mac && !is_win && !is_fuchsia && !is_android) {
include_dirs = [ "//third_party/breakpad/breakpad/src/" ]
sources += [ "crash_key_breakpad_unittest.cc" ]
}
diff --git a/components/crash/core/common/crash_keys.cc b/components/crash/core/common/crash_keys.cc
index 0261928..6a3c9599 100644
--- a/components/crash/core/common/crash_keys.cc
+++ b/components/crash/core/common/crash_keys.cc
@@ -24,7 +24,7 @@
namespace {
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
// When using Crashpad, the crash reporting client ID is the responsibility of
// Crashpad. It is not set directly by Chrome. To make the metrics client ID
// available on the server, it's stored in a distinct key.
@@ -51,7 +51,7 @@
}
void ClearMetricsClientId() {
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
// Crashpad always monitors for crashes, but doesn't upload them when
// crash reporting is disabled. The preference to upload crash reports is
// linked to the preference for metrics reporting. When metrics reporting is
diff --git a/components/minidump_uploader/BUILD.gn b/components/minidump_uploader/BUILD.gn
index 6742e9c8..dbf3c437 100644
--- a/components/minidump_uploader/BUILD.gn
+++ b/components/minidump_uploader/BUILD.gn
@@ -14,6 +14,7 @@
static_library("minidump_uploader") {
sources = [
"rewrite_minidumps_as_mimes.cc",
+ "rewrite_minidumps_as_mimes.h",
]
deps = [
diff --git a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java
index 5ac81f2..520c84f 100644
--- a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java
+++ b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java
@@ -28,26 +28,21 @@
/**
* The CrashFileManager is responsible for managing the "Crash Reports" directory containing
- * minidump files and shepherding them through a state machine represented by the file names. Note
- * that the second step is optional.
- * 1. foo.dmp is a minidump file, written to the directory by Breakpad.
- * (2) foo.dmpNNNNN is a minidump file, where NNNNN is the PID (process id) of the crashing
- * process. This step is optional -- that is, a minidump could fail to have its PID included in
- * the filename.
- * 3. foo.dmp.try0 or foo.dmpNNNNN.try0 is a minidump file with recent logcat output attached to
- * it; or a file for which logcat output has been intentionally omitted. Notably,
- * Webview-generated minidumps do not include logcat output.
- * 4. foo.dmpNNNNN.tryM for M > 0 is a minidump file that's been attempted to be uploaded to the
+ * minidump files and shepherding them through a state machine represented by the file names.
+ * 1. Minidumps are read from Crashpad's CrashReportDatabase and re-written as MIME files in the
+ * "Crash Reports" directory as foo.dmpNNNNN where NNNNN is the PID (process id) of the
+ * crashing process.
+ * 2. foo.dmpNNNNN.try0 is a minidump file with recent logcat output attached to it; or a file for
+ * which logcat output has been intentionally omitted. Notably, Webview-generated minidumps do
+ * not include logcat output.
+ * 3. foo.dmpNNNNN.tryM for M > 0 is a minidump file that's been attempted to be uploaded to the
* crash server, but for which M upload attempts have failed.
- * 5. foo.up.tryM and foo.upNNNNN.tryM are both valid possible names for a successfully uploaded
- * file.
- * 6. foo.skipped.tryM and foo.skippedNNNNN.tryM are both valid possible names for a file whose
- * upload was skipped. An upload may be skipped, for example, if the user has not consented to
- * uploading crash reports. These files are marked as skipped rather than deleted immediately to
- * allow the user to manually initiate an upload.
- * 7. foo.forced.tryM and foo.forcedNNNNN.tryM are both valid possible names for a file that the
- * user has manually requested to upload.
- * 8. foo.tmp is a temporary file.
+ * 4. foo.upNNNNN.tryM names a successfully uploaded file.
+ * 5. foo.skippedNNNNN.tryM names for a file whose upload was skipped. An upload may be skipped,
+ * for example, if the user has not consented to uploading crash reports. These files are marked
+ * as skipped rather than deleted immediately to allow the user to manually initiate an upload.
+ * 6. foo.forcedNNNNN.tryM names a file that the user has manually requested to upload.
+ * 7. foo.tmp is a temporary file.
*/
public class CrashFileManager {
private static final String TAG = "CrashFileManager";
@@ -351,9 +346,11 @@
/**
* Returns the most recent minidump without a logcat for a given pid, or null if no such
- * minidump exists.
+ * minidump exists. This method begins by reading all minidumps from Crashpad's database and
+ * rewriting them as MIME files in the Crash Reports directory.
*/
public File getMinidumpSansLogcatForPid(int pid) {
+ importCrashpadMinidumps();
File[] foundFiles = listCrashFiles(
Pattern.compile("\\.dmp" + Integer.toString(pid) + "\\z"));
return foundFiles.length > 0 ? foundFiles[0] : null;
@@ -361,11 +358,14 @@
/**
* Returns all minidump files that definitely do not have logcat output, sorted by modification
- * time stamp. Note: This method does not provide an "if and only if" test: it may return omit
- * some files that lack logcat output, if logcat output has been intentionally skipped for those
- * minidumps. However, any files returned definitely lack logcat output.
+ * time stamp. This method begins by reading all minidumps from Crashpad's database and
+ * rewriting them as MIME files in the Crash Reports directory. Note: This method does not
+ * provide an "if and only if" test: it may return omit some files that lack logcat output, if
+ * logcat output has been intentionally skipped for those minidumps. However, any files returned
+ * definitely lack logcat output.
*/
public File[] getMinidumpsSansLogcat() {
+ importCrashpadMinidumps();
return listCrashFiles(MINIDUMP_SANS_LOGCAT_PATTERN);
}
diff --git a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashTestRule.java b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashTestRule.java
index 071c9b9..e9ddcab 100644
--- a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashTestRule.java
+++ b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashTestRule.java
@@ -12,6 +12,8 @@
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
import java.io.File;
@@ -51,6 +53,7 @@
private void setUp() throws Exception {
ContextUtils.initApplicationContextForTests(
InstrumentationRegistry.getTargetContext().getApplicationContext());
+ LibraryLoader.getInstance().ensureInitialized(LibraryProcessType.PROCESS_BROWSER);
if (mCacheDir == null) {
mCacheDir = getExistingCacheDir();
}
diff --git a/components/minidump_uploader/rewrite_minidumps_as_mimes.cc b/components/minidump_uploader/rewrite_minidumps_as_mimes.cc
index f75f515..b9869ba3 100644
--- a/components/minidump_uploader/rewrite_minidumps_as_mimes.cc
+++ b/components/minidump_uploader/rewrite_minidumps_as_mimes.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "components/minidump_uploader/rewrite_minidumps_as_mimes.h"
+
#include <utility>
#include "base/android/jni_string.h"
@@ -9,7 +11,6 @@
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "jni/CrashReportMimeWriter_jni.h"
-#include "third_party/crashpad/crashpad/client/crash_report_database.h"
#include "third_party/crashpad/crashpad/handler/minidump_to_upload_parameters.h"
#include "third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h"
#include "third_party/crashpad/crashpad/util/file/file_writer.h"
@@ -18,13 +19,6 @@
namespace minidump_uploader {
-bool MimeifyReport(const crashpad::CrashReportDatabase::UploadReport& report,
- crashpad::HTTPMultipartBuilder* http_multipart_builder,
- pid_t* pid);
-
-bool WriteBodyToFile(crashpad::HTTPBodyStream* body,
- crashpad::FileWriterInterface* writer);
-
namespace {
#if defined(OS_ANDROID)
diff --git a/components/minidump_uploader/rewrite_minidumps_as_mimes.h b/components/minidump_uploader/rewrite_minidumps_as_mimes.h
new file mode 100644
index 0000000..3238d97
--- /dev/null
+++ b/components/minidump_uploader/rewrite_minidumps_as_mimes.h
@@ -0,0 +1,34 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MINIDUMP_UPLOADER_REWRITE_MINIDUMPS_AS_MIMES_H_
+#define COMPONENTS_MINIDUMP_UPLOADER_REWRITE_MINIDUMPS_AS_MIMES_H_
+
+#include <sys/types.h>
+
+#include "third_party/crashpad/crashpad/client/crash_report_database.h"
+
+namespace crashpad {
+class HTTPMultipartBuilder;
+class HTTPBodyStream;
+class FileWriterInterface;
+} // namespace crashpad
+
+namespace minidump_uploader {
+
+// Re-encodes report as a MIME and places the result in http_multipart_builder.
+// pid is set to the process ID extracted from the report. Returns `true` on
+// success.
+bool MimeifyReport(const crashpad::CrashReportDatabase::UploadReport& report,
+ crashpad::HTTPMultipartBuilder* http_multipart_builder,
+ pid_t* pid);
+
+// Consumes all bytes from body and writes them to writer. Returns `true` on
+// success.
+bool WriteBodyToFile(crashpad::HTTPBodyStream* body,
+ crashpad::FileWriterInterface* writer);
+
+} // namespace minidump_uploader
+
+#endif // COMPONENTS_MINIDUMP_UPLOADER_REWRITE_MINIDUMPS_AS_MIMES_H_
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc
index 30468f1..537e1a40 100644
--- a/content/shell/app/shell_main_delegate.cc
+++ b/content/shell/app/shell_main_delegate.cc
@@ -68,7 +68,7 @@
#include "content/shell/android/shell_descriptors.h"
#endif
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
#include "components/crash/content/app/crashpad.h" // nogncheck
#endif
@@ -85,7 +85,7 @@
#include "content/shell/common/v8_crashpad_support_win.h"
#endif
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
#include "components/crash/content/app/breakpad_linux.h"
#endif
@@ -328,18 +328,13 @@
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kProcessType);
crash_reporter::SetCrashReporterClient(g_shell_crash_client.Pointer());
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
#elif defined(OS_LINUX)
// Reporting for sub-processes will be initialized in ZygoteForked.
if (process_type != service_manager::switches::kZygoteProcess)
breakpad::InitCrashReporter(process_type);
-#elif defined(OS_ANDROID)
- if (process_type.empty())
- breakpad::InitCrashReporter(process_type);
- else
- breakpad::InitNonBrowserCrashReporterForAndroid(process_type);
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
}
#endif // !defined(OS_FUCHSIA)
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc
index 5dac9b3..10f1b0c 100644
--- a/content/shell/browser/shell_browser_main_parts.cc
+++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -154,11 +154,8 @@
base::CommandLine::ForCurrentProcess();
crash_reporter::ChildExitObserver::Create();
if (command_line->HasSwitch(switches::kEnableCrashReporter)) {
- base::FilePath crash_dumps_dir =
- command_line->GetSwitchValuePath(switches::kCrashDumpsDir);
crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
- std::make_unique<crash_reporter::ChildProcessCrashObserver>(
- crash_dumps_dir, kAndroidMinidumpDescriptor));
+ std::make_unique<crash_reporter::ChildProcessCrashObserver>());
}
#endif
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 02225da..9f4f1f1 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -56,7 +56,7 @@
#if defined(OS_ANDROID)
#include "base/android/apk_assets.h"
#include "base/android/path_utils.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
+#include "components/crash/content/app/crashpad.h"
#include "content/shell/android/shell_descriptors.h"
#endif
@@ -68,9 +68,8 @@
#include "services/ws/test_ws/test_ws.mojom.h" // nogncheck
#endif
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_ANDROID)
#include "base/debug/leak_annotations.h"
-#include "components/crash/content/app/breakpad_linux.h"
#include "components/crash/content/browser/crash_handler_host_linux.h"
#include "content/public/common/content_descriptors.h"
#endif
@@ -91,7 +90,11 @@
ShellContentBrowserClient* g_browser_client;
-#if defined(OS_LINUX)
+#if defined(OS_ANDROID)
+int GetCrashSignalFD(const base::CommandLine& command_line) {
+ return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
+}
+#elif defined(OS_LINUX)
breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
const std::string& process_type) {
base::FilePath dumps_path =
@@ -137,7 +140,7 @@
return -1;
}
-#endif // defined(OS_LINUX)
+#endif // defined(OS_ANDROID)
} // namespace
@@ -423,15 +426,11 @@
kShellPakDescriptor,
base::GlobalDescriptors::GetInstance()->Get(kShellPakDescriptor),
base::GlobalDescriptors::GetInstance()->GetRegion(kShellPakDescriptor));
-
- crash_reporter::ChildExitObserver::GetInstance()->BrowserChildProcessStarted(
- child_process_id, mappings);
-#else
+#endif
int crash_signal_fd = GetCrashSignalFD(command_line);
if (crash_signal_fd >= 0) {
mappings->Share(service_manager::kCrashDumpSignal, crash_signal_fd);
}
-#endif // !defined(OS_ANDROID)
}
#endif // defined(OS_LINUX) || defined(OS_ANDROID)