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

Side by Side Diff: components/crash/content/browser/crash_micro_dump_manager_android.cc

Issue 2393853002: Refactor CrashDump*Manager to use a shared CrashDumpObserver singleton. (Closed)
Patch Set: Rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/crash/content/browser/crash_micro_dump_manager_android.h"
6
7 #include <unistd.h>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/child_process_data.h"
13 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/notification_types.h"
15 #include "content/public/browser/render_process_host.h"
16
17 using content::BrowserThread;
18
19 namespace breakpad {
20
21 // static
22 CrashMicroDumpManager* CrashMicroDumpManager::GetInstance() {
23 return base::Singleton<CrashMicroDumpManager>::get();
24 }
25
26 CrashMicroDumpManager::CrashMicroDumpManager() : weak_factory_(this) {
27 DCHECK_CURRENTLY_ON(BrowserThread::UI);
28
29 notification_registrar_.Add(this,
30 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
31 content::NotificationService::AllSources());
32 notification_registrar_.Add(this,
33 content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
34 content::NotificationService::AllSources());
35 }
36
37 CrashMicroDumpManager::~CrashMicroDumpManager() {
38 base::AutoLock auto_lock(child_process_id_to_pipe_lock_);
39 child_process_id_to_pipe_.clear();
40 }
41
42 base::ScopedFD CrashMicroDumpManager::CreateCrashInfoChannel(
43 int child_process_id) {
44 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
45 std::unique_ptr<base::SyncSocket> local_pipe(new base::SyncSocket());
46 std::unique_ptr<base::SyncSocket> child_pipe(new base::SyncSocket());
47 if (!base::SyncSocket::CreatePair(local_pipe.get(), child_pipe.get()))
48 return base::ScopedFD();
49 {
50 base::AutoLock auto_lock(child_process_id_to_pipe_lock_);
51 DCHECK(!ContainsKey(child_process_id_to_pipe_, child_process_id));
52 child_process_id_to_pipe_[child_process_id] = std::move(local_pipe);
53 }
54 return base::ScopedFD(dup(child_pipe->handle()));
55 }
56
57 void CrashMicroDumpManager::HandleChildTerminationOnFileThread(
58 int child_process_id,
59 base::TerminationStatus termination_status) {
60 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
61
62 std::unique_ptr<base::SyncSocket> pipe;
63 {
64 base::AutoLock auto_lock(child_process_id_to_pipe_lock_);
65 const auto& iter = child_process_id_to_pipe_.find(child_process_id);
66 if (iter == child_process_id_to_pipe_.end()) {
67 // We might get a NOTIFICATION_RENDERER_PROCESS_TERMINATED and a
68 // NOTIFICATION_RENDERER_PROCESS_CLOSED.
69 return;
70 }
71 pipe = std::move(iter->second);
72 child_process_id_to_pipe_.erase(iter);
73 }
74 DCHECK(pipe->handle() != base::SyncSocket::kInvalidHandle);
75
76 if (termination_status == base::TERMINATION_STATUS_NORMAL_TERMINATION)
77 return;
78 if (pipe->Peek() >= sizeof(int)) {
79 int exit_code;
80 pipe->Receive(&exit_code, sizeof(exit_code));
81 LOG(FATAL) << "Renderer process crash detected (code " << exit_code
82 << "). Terminating browser.";
83 } else {
84 // The child process hasn't written anything into the pipe. This implies
85 // that it was terminated via SIGKILL by the low memory killer, and thus we
86 // need to perform a clean exit.
87 exit(0);
88 }
89 }
90
91 void CrashMicroDumpManager::Observe(
92 int type,
93 const content::NotificationSource& source,
94 const content::NotificationDetails& details) {
95 content::RenderProcessHost* rph =
96 content::Source<content::RenderProcessHost>(source).ptr();
97 // In case of a normal termination we just need to close the pipe_fd we kept
98 // open.
99 base::TerminationStatus termination_status =
100 base::TERMINATION_STATUS_NORMAL_TERMINATION;
101 switch (type) {
102 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
103 // NOTIFICATION_RENDERER_PROCESS_TERMINATED is sent when the renderer
104 // process is cleanly shutdown.
105 break;
106 }
107 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
108 // Android fast shutdowns is a known case where the renderer is
109 // intentionally killed when we are done with it.
110 if (!rph->FastShutdownStarted()) {
111 content::RenderProcessHost::RendererClosedDetails* process_details =
112 content::Details<content::RenderProcessHost::RendererClosedDetails>(
113 details).ptr();
114 termination_status = process_details->status;
115 }
116 break;
117 }
118 default:
119 NOTREACHED();
120 return;
121 }
122 BrowserThread::PostTask(
123 BrowserThread::FILE, FROM_HERE,
124 base::Bind(&CrashMicroDumpManager::HandleChildTerminationOnFileThread,
125 weak_factory_.GetWeakPtr(), rph->GetID(),
126 termination_status));
127 }
128
129 } // namespace breakpad
OLDNEW
« no previous file with comments | « components/crash/content/browser/crash_micro_dump_manager_android.h ('k') | content/shell/browser/shell_browser_main_parts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698