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

Side by Side Diff: chrome/browser/renderer_host/browser_render_process_host.cc

Issue 14504: Get render_process_host to build on Linux by butchering a bunch of files. (Closed)
Patch Set: re-upload Created 11 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
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Represents the browser side of the browser <--> renderer communication
6 // channel. There will be one RenderProcessHost per renderer process.
7
5 #include "chrome/browser/renderer_host/browser_render_process_host.h" 8 #include "chrome/browser/renderer_host/browser_render_process_host.h"
6 9
10 #include "build/build_config.h"
11
7 #include <algorithm> 12 #include <algorithm>
8 #include <sstream> 13 #include <sstream>
9 #include <vector> 14 #include <vector>
10 15
11 #include "base/command_line.h" 16 #include "base/command_line.h"
12 #include "base/debug_util.h" 17 #include "base/debug_util.h"
13 #include "base/file_util.h" 18 #include "base/file_util.h"
14 #include "base/logging.h" 19 #include "base/logging.h"
15 #include "base/path_service.h" 20 #include "base/path_service.h"
16 #include "base/process_util.h" 21 #include "base/process_util.h"
17 #include "base/shared_memory.h" 22 #include "base/shared_memory.h"
18 #include "base/singleton.h" 23 #include "base/singleton.h"
19 #include "base/string_util.h" 24 #include "base/string_util.h"
20 #include "base/thread.h" 25 #include "base/thread.h"
21 #include "base/win_util.h"
22 #include "chrome/app/result_codes.h" 26 #include "chrome/app/result_codes.h"
23 #include "chrome/browser/browser.h" 27 // #include "chrome/browser/browser.h"
brettw 2009/01/21 19:18:50 Be sure to remove these commented ones.
brettw 2009/01/21 19:18:50 Be sure to remove these commented-out ones.
24 #include "chrome/browser/browser_process.h" 28 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/cache_manager_host.h" 29 #include "chrome/browser/cache_manager_host.h"
26 #include "chrome/browser/extensions/user_script_master.h" 30 #include "chrome/browser/extensions/user_script_master.h"
27 #include "chrome/browser/history/history.h" 31 #include "chrome/browser/history/history.h"
28 #include "chrome/browser/plugin_service.h" 32 #include "chrome/browser/plugin_service.h"
29 #include "chrome/browser/render_widget_helper.h" 33 #include "chrome/browser/render_widget_helper.h"
30 #include "chrome/browser/render_view_host.h"
31 #include "chrome/browser/renderer_security_policy.h" 34 #include "chrome/browser/renderer_security_policy.h"
32 #include "chrome/browser/resource_message_filter.h" 35 #include "chrome/browser/resource_message_filter.h"
33 #include "chrome/browser/sandbox_policy.h"
34 #include "chrome/browser/spellchecker.h" 36 #include "chrome/browser/spellchecker.h"
35 #include "chrome/browser/visitedlink_master.h" 37 #include "chrome/browser/visitedlink_master.h"
36 #include "chrome/browser/tab_contents/web_contents.h" 38 // #include "chrome/browser/tab_contents/web_contents.h"
37 #include "chrome/common/chrome_paths.h" 39 #include "chrome/common/chrome_paths.h"
38 #include "chrome/common/chrome_switches.h" 40 #include "chrome/common/chrome_switches.h"
39 #include "chrome/common/debug_flags.h" 41 #include "chrome/common/debug_flags.h"
40 #include "chrome/common/l10n_util.h" 42 #include "chrome/common/l10n_util.h"
41 #include "chrome/common/logging_chrome.h" 43 #include "chrome/common/logging_chrome.h"
42 #include "chrome/common/pref_names.h" 44 #include "chrome/common/pref_names.h"
43 #include "chrome/common/pref_service.h" 45 #include "chrome/common/pref_service.h"
44 #include "chrome/common/process_watcher.h" 46 #include "chrome/common/process_watcher.h"
45 #include "chrome/common/win_util.h"
46 #include "chrome/renderer/render_process.h" 47 #include "chrome/renderer/render_process.h"
47 #include "net/base/cookie_monster.h" 48 #include "net/base/cookie_monster.h"
48 #include "net/base/net_util.h" 49 #include "net/base/net_util.h"
50
51 #if defined(OS_WIN)
52 // TODO(port): see comment by the only usage of RenderViewHost in this file.
53 #include "chrome/browser/render_view_host.h"
54
55 // Once the above TODO is finished, then this block is all Windows-specific
56 // files.
57 #include "base/win_util.h"
58 #include "chrome/browser/sandbox_policy.h"
59 #include "chrome/common/win_util.h"
49 #include "sandbox/src/sandbox.h" 60 #include "sandbox/src/sandbox.h"
61 #endif
50 62
51 #include "SkBitmap.h" 63 #include "SkBitmap.h"
52 64
53 #include "generated_resources.h" 65 #include "generated_resources.h"
54 66
55 namespace { 67 namespace {
56 68
57 // ---------------------------------------------------------------------------- 69 // ----------------------------------------------------------------------------
58 70
59 class RendererMainThread : public base::Thread { 71 class RendererMainThread : public base::Thread {
60 public: 72 public:
61 explicit RendererMainThread(const std::wstring& channel_id) 73 explicit RendererMainThread(const std::wstring& channel_id)
62 : base::Thread("Chrome_InProcRendererThread"), 74 : base::Thread("Chrome_InProcRendererThread"),
63 channel_id_(channel_id) { 75 channel_id_(channel_id) {
64 } 76 }
65 77
66 protected: 78 protected:
67 virtual void Init() { 79 virtual void Init() {
80 #if defined(OS_WIN)
68 CoInitialize(NULL); 81 CoInitialize(NULL);
82 #endif
69 83
70 bool rv = RenderProcess::GlobalInit(channel_id_); 84 bool rv = RenderProcess::GlobalInit(channel_id_);
71 DCHECK(rv); 85 DCHECK(rv);
72 // It's a little lame to manually set this flag. But the single process 86 // It's a little lame to manually set this flag. But the single process
73 // RendererThread will receive the WM_QUIT. We don't need to assert on 87 // RendererThread will receive the WM_QUIT. We don't need to assert on
74 // this thread, so just force the flag manually. 88 // this thread, so just force the flag manually.
75 // If we want to avoid this, we could create the InProcRendererThread 89 // If we want to avoid this, we could create the InProcRendererThread
76 // directly with _beginthreadex() rather than using the Thread class. 90 // directly with _beginthreadex() rather than using the Thread class.
77 base::Thread::SetThreadWasQuitProperly(true); 91 base::Thread::SetThreadWasQuitProperly(true);
78 } 92 }
79 93
80 virtual void CleanUp() { 94 virtual void CleanUp() {
81 RenderProcess::GlobalCleanup(); 95 RenderProcess::GlobalCleanup();
82 96
97 #if defined(OS_WIN)
83 CoUninitialize(); 98 CoUninitialize();
99 #endif
84 } 100 }
85 101
86 private: 102 private:
87 std::wstring channel_id_; 103 std::wstring channel_id_;
88 }; 104 };
89 105
90 // Used for a View_ID where the renderer has not been attached yet 106 // Used for a View_ID where the renderer has not been attached yet
91 const int32 kInvalidViewID = -1; 107 const int32 kInvalidViewID = -1;
92 108
93 // Get the path to the renderer executable, which is the same as the 109 // Get the path to the renderer executable, which is the same as the
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 148
133 BrowserRenderProcessHost::~BrowserRenderProcessHost() { 149 BrowserRenderProcessHost::~BrowserRenderProcessHost() {
134 // Some tests hold BrowserRenderProcessHost in a scoped_ptr, so we must call 150 // Some tests hold BrowserRenderProcessHost in a scoped_ptr, so we must call
135 // Unregister here as well as in response to Release(). 151 // Unregister here as well as in response to Release().
136 Unregister(); 152 Unregister();
137 153
138 // We may have some unsent messages at this point, but that's OK. 154 // We may have some unsent messages at this point, but that's OK.
139 channel_.reset(); 155 channel_.reset();
140 156
141 if (process_.handle() && !run_renderer_in_process()) { 157 if (process_.handle() && !run_renderer_in_process()) {
142 watcher_.StopWatching();
143 ProcessWatcher::EnsureProcessTerminated(process_.handle()); 158 ProcessWatcher::EnsureProcessTerminated(process_.handle());
144 } 159 }
145 160
146 profile()->GetPrefs()->RemovePrefObserver(prefs::kBlockPopups, this); 161 profile()->GetPrefs()->RemovePrefObserver(prefs::kBlockPopups, this);
147 162
148 NotificationService::current()->RemoveObserver(this, 163 NotificationService::current()->RemoveObserver(this,
149 NOTIFY_USER_SCRIPTS_LOADED, NotificationService::AllSources()); 164 NOTIFY_USER_SCRIPTS_LOADED, NotificationService::AllSources());
150 } 165 }
151 166
167 // When we're started with the --start-renderers-manually flag, we pop up a
168 // modal dialog requesting the user manually start up a renderer.
169 // |cmd_line| is the command line to start the renderer with.
170 static void RunStartRenderersManuallyDialog(const std::wstring& cmd_line) {
171 #if defined(OS_WIN)
172 std::wstring message =
173 L"Please start a renderer process using:\n" + cmd_line;
174
175 // We don't know the owner window for RenderProcessHost and therefore we
176 // pass a NULL HWND argument.
177 win_util::MessageBox(NULL,
178 message,
179 switches::kBrowserStartRenderersManually,
180 MB_OK);
181 #else
182 // TODO(port): refactor above code / pop up a message box here.
183 NOTIMPLEMENTED();
184 #endif
185 }
186
152 bool BrowserRenderProcessHost::Init() { 187 bool BrowserRenderProcessHost::Init() {
153 // calling Init() more than once does nothing, this makes it more convenient 188 // calling Init() more than once does nothing, this makes it more convenient
154 // for the view host which may not be sure in some cases 189 // for the view host which may not be sure in some cases
155 if (channel_.get()) 190 if (channel_.get())
156 return true; 191 return true;
157 192
158 // run the IPC channel on the shared IO thread. 193 // run the IPC channel on the shared IO thread.
159 base::Thread* io_thread = g_browser_process->io_thread(); 194 base::Thread* io_thread = g_browser_process->io_thread();
160 195
161 scoped_refptr<ResourceMessageFilter> resource_message_filter = 196 scoped_refptr<ResourceMessageFilter> resource_message_filter =
162 new ResourceMessageFilter(g_browser_process->resource_dispatcher_host(), 197 new ResourceMessageFilter(g_browser_process->resource_dispatcher_host(),
163 PluginService::GetInstance(), 198 PluginService::GetInstance(),
164 g_browser_process->print_job_manager(), 199 g_browser_process->print_job_manager(),
165 host_id(), 200 host_id(),
166 profile(), 201 profile(),
167 widget_helper_, 202 widget_helper_,
168 profile()->GetSpellChecker()); 203 profile()->GetSpellChecker());
169 204
170 CommandLine browser_command_line; 205 CommandLine browser_command_line;
171 206
207 #if defined(OS_WIN)
172 // setup IPC channel 208 // setup IPC channel
173 std::wstring channel_id = GenerateRandomChannelID(this); 209 const std::wstring channel_id = GenerateRandomChannelID(this);
174 channel_.reset( 210 channel_.reset(
175 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_SERVER, this, 211 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_SERVER, this,
176 resource_message_filter, 212 resource_message_filter,
177 io_thread->message_loop(), true, 213 io_thread->message_loop(), true,
178 g_browser_process->shutdown_event())); 214 g_browser_process->shutdown_event()));
179 // As a preventive mesure, we DCHECK if someone sends a synchronous message 215 // As a preventive mesure, we DCHECK if someone sends a synchronous message
180 // with no time-out, which in the context of the browser process we should not 216 // with no time-out, which in the context of the browser process we should not
181 // be doing. 217 // be doing.
182 channel_->set_sync_messages_with_no_timeout_allowed(false); 218 channel_->set_sync_messages_with_no_timeout_allowed(false);
219 #else
220 // TODO(port): this depends on resource_message_filter
221 NOTIMPLEMENTED();
222 io_thread = io_thread;
223 static const std::wstring channel_id = L"set to quiet the compiler";
224 #endif
183 225
184 // build command line for renderer, we have to quote the executable name to 226 // build command line for renderer, we have to quote the executable name to
185 // deal with spaces 227 // deal with spaces
186 std::wstring renderer_path = 228 std::wstring renderer_path =
187 browser_command_line.GetSwitchValue(switches::kRendererPath); 229 browser_command_line.GetSwitchValue(switches::kRendererPath);
188 if (renderer_path.empty()) 230 if (renderer_path.empty())
189 if (!GetRendererPath(&renderer_path)) 231 if (!GetRendererPath(&renderer_path))
190 return false; 232 return false;
191 std::wstring cmd_line; 233 std::wstring cmd_line;
192 cmd_line = L"\"" + renderer_path + L"\""; 234 cmd_line = L"\"" + renderer_path + L"\"";
(...skipping 27 matching lines...) Expand all
220 switches::kMessageLoopHistogrammer, 262 switches::kMessageLoopHistogrammer,
221 switches::kEnableDCHECK, 263 switches::kEnableDCHECK,
222 switches::kSilentDumpOnDCHECK, 264 switches::kSilentDumpOnDCHECK,
223 switches::kDisablePopupBlocking, 265 switches::kDisablePopupBlocking,
224 switches::kUseLowFragHeapCrt, 266 switches::kUseLowFragHeapCrt,
225 switches::kGearsInRenderer, 267 switches::kGearsInRenderer,
226 switches::kEnableUserScripts, 268 switches::kEnableUserScripts,
227 switches::kEnableVideo, 269 switches::kEnableVideo,
228 }; 270 };
229 271
230 for (int i = 0; i < arraysize(switch_names); ++i) { 272 for (size_t i = 0; i < arraysize(switch_names); ++i) {
231 if (browser_command_line.HasSwitch(switch_names[i])) { 273 if (browser_command_line.HasSwitch(switch_names[i])) {
232 CommandLine::AppendSwitchWithValue( 274 CommandLine::AppendSwitchWithValue(
233 &cmd_line, switch_names[i], 275 &cmd_line, switch_names[i],
234 browser_command_line.GetSwitchValue(switch_names[i])); 276 browser_command_line.GetSwitchValue(switch_names[i]));
235 } 277 }
236 } 278 }
237 279
238 // Pass on the browser locale. 280 // Pass on the browser locale.
239 const std::wstring locale = g_browser_process->GetApplicationLocale(); 281 const std::wstring locale = g_browser_process->GetApplicationLocale();
240 CommandLine::AppendSwitchWithValue(&cmd_line, switches::kLang, locale); 282 CommandLine::AppendSwitchWithValue(&cmd_line, switches::kLang, locale);
241 283
242 bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox); 284 bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox);
243 if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) { 285 if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) {
244 // In process plugins won't work if the sandbox is enabled. 286 // In process plugins won't work if the sandbox is enabled.
245 in_sandbox = false; 287 in_sandbox = false;
246 } 288 }
247 289
290 #if defined(OS_WIN)
248 bool child_needs_help = 291 bool child_needs_help =
249 DebugFlags::ProcessDebugFlags(&cmd_line, 292 DebugFlags::ProcessDebugFlags(&cmd_line,
250 DebugFlags::RENDERER, 293 DebugFlags::RENDERER,
251 in_sandbox); 294 in_sandbox);
295 #endif
252 CommandLine::AppendSwitchWithValue(&cmd_line, 296 CommandLine::AppendSwitchWithValue(&cmd_line,
253 switches::kProcessType, 297 switches::kProcessType,
254 switches::kRendererProcess); 298 switches::kRendererProcess);
255 299
256 CommandLine::AppendSwitchWithValue(&cmd_line, 300 CommandLine::AppendSwitchWithValue(&cmd_line,
257 switches::kProcessChannelID, 301 switches::kProcessChannelID,
258 channel_id); 302 channel_id);
259 303
260 const std::wstring& profile_path = 304 const std::wstring& profile_path =
261 browser_command_line.GetSwitchValue(switches::kUserDataDir); 305 browser_command_line.GetSwitchValue(switches::kUserDataDir);
(...skipping 16 matching lines...) Expand all
278 // 322 //
279 // TODO: We should consider how to better cleanup threads on exit. 323 // TODO: We should consider how to better cleanup threads on exit.
280 base::Thread *render_thread = new RendererMainThread(channel_id); 324 base::Thread *render_thread = new RendererMainThread(channel_id);
281 base::Thread::Options options; 325 base::Thread::Options options;
282 options.message_loop_type = MessageLoop::TYPE_IO; 326 options.message_loop_type = MessageLoop::TYPE_IO;
283 render_thread->StartWithOptions(options); 327 render_thread->StartWithOptions(options);
284 } else { 328 } else {
285 if (g_browser_process->local_state() && 329 if (g_browser_process->local_state() &&
286 g_browser_process->local_state()->GetBoolean( 330 g_browser_process->local_state()->GetBoolean(
287 prefs::kStartRenderersManually)) { 331 prefs::kStartRenderersManually)) {
288 std::wstring message = 332 RunStartRenderersManuallyDialog(cmd_line);
289 L"Please start a renderer process using:\n" + cmd_line;
290
291 // We don't know the owner window for BrowserRenderProcessHost and therefo re we
292 // pass a NULL HWND argument.
293 win_util::MessageBox(NULL,
294 message,
295 switches::kBrowserStartRenderersManually,
296 MB_OK);
297 } else { 333 } else {
334 #if defined(OS_WIN)
298 if (in_sandbox) { 335 if (in_sandbox) {
299 // spawn the child process in the sandbox 336 // spawn the child process in the sandbox
300 sandbox::BrokerServices* broker_service = 337 sandbox::BrokerServices* broker_service =
301 g_browser_process->broker_services(); 338 g_browser_process->broker_services();
302 339
303 sandbox::ResultCode result; 340 sandbox::ResultCode result;
304 PROCESS_INFORMATION target = {0}; 341 PROCESS_INFORMATION target = {0};
305 sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); 342 sandbox::TargetPolicy* policy = broker_service->CreatePolicy();
306 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); 343 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
307 344
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 Details<bool>(&on_sandbox_desktop)); 395 Details<bool>(&on_sandbox_desktop));
359 396
360 ResumeThread(target.hThread); 397 ResumeThread(target.hThread);
361 CloseHandle(target.hThread); 398 CloseHandle(target.hThread);
362 process_.set_handle(target.hProcess); 399 process_.set_handle(target.hProcess);
363 400
364 // Help the process a little. It can't start the debugger by itself if 401 // Help the process a little. It can't start the debugger by itself if
365 // the process is in a sandbox. 402 // the process is in a sandbox.
366 if (child_needs_help) 403 if (child_needs_help)
367 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); 404 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId);
368 } else { 405 } else
406 #endif // OS_WIN and sandbox
407 {
369 // spawn child process 408 // spawn child process
370 HANDLE process; 409 base::ProcessHandle process = 0;
410 // TODO(port): LaunchApp is actually no good on POSIX when
411 // we've constructed the command line as we have here, as the above
412 // calls all append to a single string while LaunchApp reaches in to
413 // the argv array. CommandLine should be fixed, but once it is, this
414 // code will be correct.
371 if (!base::LaunchApp(cmd_line, false, false, &process)) 415 if (!base::LaunchApp(cmd_line, false, false, &process))
372 return false; 416 return false;
373 process_.set_handle(process); 417 process_.set_handle(process);
374 } 418 }
375
376 watcher_.StartWatching(process_.handle(), this);
377 } 419 }
378 } 420 }
379 421
380 // Now that the process is created, set it's backgrounding accordingly. 422 // Now that the process is created, set it's backgrounding accordingly.
381 SetBackgrounded(backgrounded_); 423 SetBackgrounded(backgrounded_);
382 424
383 InitVisitedLinks(); 425 InitVisitedLinks();
384 InitUserScripts(); 426 InitUserScripts();
385 427
386 if (max_page_id_ != -1) 428 if (max_page_id_ != -1)
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 channel_->Send(new ViewMsg_UserScripts_NewScripts(handle_for_process)); 542 channel_->Send(new ViewMsg_UserScripts_NewScripts(handle_for_process));
501 } 543 }
502 } 544 }
503 545
504 bool BrowserRenderProcessHost::FastShutdownIfPossible() { 546 bool BrowserRenderProcessHost::FastShutdownIfPossible() {
505 if (!process_.handle()) 547 if (!process_.handle())
506 return false; // Render process is probably crashed. 548 return false; // Render process is probably crashed.
507 if (BrowserRenderProcessHost::run_renderer_in_process()) 549 if (BrowserRenderProcessHost::run_renderer_in_process())
508 return false; // Since process mode can't do fast shutdown. 550 return false; // Since process mode can't do fast shutdown.
509 551
552 #if defined(OS_WIN)
510 // Test if there's an unload listener 553 // Test if there's an unload listener
511 BrowserRenderProcessHost::listeners_iterator iter; 554 BrowserRenderProcessHost::listeners_iterator iter;
512 // NOTE: This is a bit dangerous. We know that for now, listeners are 555 // NOTE: This is a bit dangerous. We know that for now, listeners are
513 // always RenderWidgetHosts. But in theory, they don't have to be. 556 // always RenderWidgetHosts. But in theory, they don't have to be.
514 for (iter = listeners_begin(); iter != listeners_end(); ++iter) { 557 for (iter = listeners_begin(); iter != listeners_end(); ++iter) {
515 RenderWidgetHost* widget = static_cast<RenderWidgetHost*>(iter->second); 558 RenderWidgetHost* widget = static_cast<RenderWidgetHost*>(iter->second);
516 DCHECK(widget); 559 DCHECK(widget);
517 if (!widget || !widget->IsRenderView()) 560 if (!widget || !widget->IsRenderView())
518 continue; 561 continue;
519 RenderViewHost* rvh = static_cast<RenderViewHost*>(widget); 562 RenderViewHost* rvh = static_cast<RenderViewHost*>(widget);
520 if (!rvh->CanTerminate()) { 563 if (!rvh->CanTerminate()) {
521 // NOTE: It's possible that an onunload listener may be installed 564 // NOTE: It's possible that an onunload listener may be installed
522 // while we're shutting down, so there's a small race here. Given that 565 // while we're shutting down, so there's a small race here. Given that
523 // the window is small, it's unlikely that the web page has much 566 // the window is small, it's unlikely that the web page has much
524 // state that will be lost by not calling its unload handlers properly. 567 // state that will be lost by not calling its unload handlers properly.
525 return false; 568 return false;
526 } 569 }
527 } 570 }
571 #else
572 // TODO(port): the above is the only reason this file pulls in
573 // RenderWidgetHost and RenderViewHost.
574 // Perhaps IPC::Channel::Listener needs another method like CanTerminate()?
575 // No matter what, some abstractions are getting broken here...
576 NOTIMPLEMENTED();
577 #endif
528 578
529 // Otherwise, we're allowed to just terminate the process. Using exit code 0 579 // Otherwise, we're allowed to just terminate the process. Using exit code 0
530 // means that UMA won't treat this as a renderer crash. 580 // means that UMA won't treat this as a renderer crash.
531 process_.Terminate(ResultCodes::NORMAL_EXIT); 581 process_.Terminate(ResultCodes::NORMAL_EXIT);
532 return true; 582 return true;
533 } 583 }
534 584
535 bool BrowserRenderProcessHost::Send(IPC::Message* msg) { 585 bool BrowserRenderProcessHost::Send(IPC::Message* msg) {
536 if (!channel_.get()) { 586 if (!channel_.get()) {
537 delete msg; 587 delete msg;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 Send(reply); 620 Send(reply);
571 } 621 }
572 return; 622 return;
573 } 623 }
574 listener->OnMessageReceived(msg); 624 listener->OnMessageReceived(msg);
575 } 625 }
576 626
577 void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) { 627 void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) {
578 // process_ is not NULL if we created the renderer process 628 // process_ is not NULL if we created the renderer process
579 if (!process_.handle()) { 629 if (!process_.handle()) {
580 if (GetCurrentProcessId() == peer_pid) { 630 if (base::GetCurrentProcId() == peer_pid) {
581 // We are in single-process mode. In theory we should have access to 631 // We are in single-process mode. In theory we should have access to
582 // ourself but it may happen that we don't. 632 // ourself but it may happen that we don't.
583 process_.set_handle(GetCurrentProcess()); 633 process_.set_handle(base::GetCurrentProcessHandle());
584 } else { 634 } else {
635 #if defined(OS_WIN)
585 // Request MAXIMUM_ALLOWED to match the access a handle 636 // Request MAXIMUM_ALLOWED to match the access a handle
586 // returned by CreateProcess() has to the process object. 637 // returned by CreateProcess() has to the process object.
587 process_.set_handle(OpenProcess(MAXIMUM_ALLOWED, FALSE, peer_pid)); 638 process_.set_handle(OpenProcess(MAXIMUM_ALLOWED, FALSE, peer_pid));
639 #elif defined(OS_POSIX)
640 // ProcessHandle is just a pid.
641 process_.set_handle(peer_pid);
642 #endif
588 DCHECK(process_.handle()); 643 DCHECK(process_.handle());
589 watcher_.StartWatching(process_.handle(), this);
590 } 644 }
591 } else { 645 } else {
592 // Need to verify that the peer_pid is actually the process we know, if 646 // Need to verify that the peer_pid is actually the process we know, if
593 // it is not, we need to panic now. See bug 1002150. 647 // it is not, we need to panic now. See bug 1002150.
594 CHECK(peer_pid == process_.pid()); 648 CHECK(peer_pid == process_.pid());
595 } 649 }
596 } 650 }
597 651
598 // Static. This function can be called from the IO Thread or from the UI thread. 652 void RenderProcessHost::OnChannelError() {
599 void BrowserRenderProcessHost::BadMessageTerminateProcess(uint16 msg_type, 653 // Our child process has died. If we didn't expect it, it's a crash.
600 HANDLE process) { 654 // In any case, we need to let everyone know it's gone.
601 LOG(ERROR) << "bad message " << msg_type << " terminating renderer.";
602 if (BrowserRenderProcessHost::run_renderer_in_process()) {
603 // In single process mode it is better if we don't suicide but just crash.
604 CHECK(false);
605 }
606 NOTREACHED();
607 ::TerminateProcess(process, ResultCodes::KILLED_BAD_MESSAGE);
608 }
609 655
610 // indicates the renderer process has exited
611 void BrowserRenderProcessHost::OnObjectSignaled(HANDLE object) {
612 DCHECK(process_.handle()); 656 DCHECK(process_.handle());
613 DCHECK(channel_.get()); 657 DCHECK(channel_.get());
614 DCHECK_EQ(object, process_.handle()); 658 base::ProcessHandle process = process_.handle();
615 659
616 bool clean_shutdown = !base::DidProcessCrash(object); 660 bool clean_shutdown = !base::DidProcessCrash(process);
617 661
618 process_.Close(); 662 process_.Close();
619 663
620 channel_.reset(); 664 channel_.reset();
621 665
622 if (!notified_termination_) { 666 if (!notified_termination_) {
623 // If |close_expected| is false, it means the renderer process went away 667 // If |close_expected| is false, it means the renderer process went away
624 // before the web views expected it; count it as a crash. 668 // before the web views expected it; count it as a crash.
625 NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_TERMINATED, 669 NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_TERMINATED,
626 Source<RenderProcessHost>(this), 670 Source<RenderProcessHost>(this),
627 Details<bool>(&clean_shutdown)); 671 Details<bool>(&clean_shutdown));
628 notified_termination_ = true; 672 notified_termination_ = true;
629 } 673 }
630 674
631 // This process should detach all the listeners, causing the object to be 675 // This process should detach all the listeners, causing the object to be
632 // deleted. We therefore need a stack copy of the web view list to avoid 676 // deleted. We therefore need a stack copy of the web view list to avoid
633 // crashing when checking for the termination condition the last time. 677 // crashing when checking for the termination condition the last time.
634 IDMap<IPC::Channel::Listener> local_listeners(listeners_); 678 IDMap<IPC::Channel::Listener> local_listeners(listeners_);
635 for (IDMap<IPC::Channel::Listener>::const_iterator i = local_listeners.begin() ; 679 for (listeners_iterator i = local_listeners.begin();
636 i != local_listeners.end(); ++i) { 680 i != local_listeners.end(); ++i) {
637 i->second->OnMessageReceived(ViewHostMsg_RendererGone(i->first)); 681 i->second->OnMessageReceived(ViewHostMsg_RendererGone(i->first));
638 } 682 }
639 // at this point, this object should be deleted 683 // at this point, this object should be deleted
640 } 684 }
641 685
642 void BrowserRenderProcessHost::Unregister() { 686 void BrowserRenderProcessHost::Unregister() {
643 // RenderProcessHost::Unregister will clean up the host_id_, so we must 687 // RenderProcessHost::Unregister will clean up the host_id_, so we must
644 // do our cleanup that uses that variable before we call it. 688 // do our cleanup that uses that variable before we call it.
645 if (host_id() >= 0) { 689 if (host_id() >= 0) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 SendUserScriptsUpdate(shared_memory); 765 SendUserScriptsUpdate(shared_memory);
722 } 766 }
723 break; 767 break;
724 } 768 }
725 default: { 769 default: {
726 NOTREACHED(); 770 NOTREACHED();
727 break; 771 break;
728 } 772 }
729 } 773 }
730 } 774 }
775
776 std::wstring GenerateRandomChannelID(void* instance) {
777 // Note: the string must start with the current process id, this is how
778 // child processes determine the pid of the parent.
779 // Build the channel ID. This is composed of a unique identifier for the
780 // parent browser process, an identifier for the renderer/plugin instance,
781 // and a random component. We use a random component so that a hacked child
782 // process can't cause denial of service by causing future named pipe creation
783 // to fail.
784 return StringPrintf(L"%d.%x.%d",
785 base::GetCurrentProcId(), instance,
786 base::RandInt(0, std::numeric_limits<int>::max()));
787 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/browser_render_process_host.h ('k') | chrome/browser/renderer_host/render_process_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698