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

Side by Side Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 9748012: Fix memory leak when errors happens in NaClProcessHost::Launch. Allow Launch to (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: fix compile error Created 8 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/nacl_host/nacl_process_host.h" 5 #include "chrome/browser/nacl_host/nacl_process_host.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 28 matching lines...) Expand all
39 #include "base/threading/thread.h" 39 #include "base/threading/thread.h"
40 #include "base/process_util.h" 40 #include "base/process_util.h"
41 #include "chrome/browser/nacl_host/nacl_broker_service_win.h" 41 #include "chrome/browser/nacl_host/nacl_broker_service_win.h"
42 #include "native_client/src/trusted/service_runtime/win/debug_exception_handler. h" 42 #include "native_client/src/trusted/service_runtime/win/debug_exception_handler. h"
43 #endif 43 #endif
44 44
45 using content::BrowserThread; 45 using content::BrowserThread;
46 using content::ChildProcessData; 46 using content::ChildProcessData;
47 using content::ChildProcessHost; 47 using content::ChildProcessHost;
48 48
49 static const char dummy[1<<16]="1";
Mark Seaborn 2012/03/21 20:41:29 Left in by mistake?
halyavin 2012/03/22 08:35:47 Sorry, I was doing an experiment in this working c
50
49 #if defined(OS_WIN) 51 #if defined(OS_WIN)
50 class NaClProcessHost::DebugContext 52 class NaClProcessHost::DebugContext
51 : public base::RefCountedThreadSafe<NaClProcessHost::DebugContext> { 53 : public base::RefCountedThreadSafe<NaClProcessHost::DebugContext> {
52 public: 54 public:
53 DebugContext() 55 DebugContext()
54 : can_send_start_msg_(false), 56 : can_send_start_msg_(false),
55 child_process_host_(NULL) { 57 child_process_host_(NULL) {
56 } 58 }
57 59
58 ~DebugContext() { 60 ~DebugContext() {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 }; 230 };
229 231
230 #if defined(OS_WIN) 232 #if defined(OS_WIN)
231 static bool RunningOnWOW64() { 233 static bool RunningOnWOW64() {
232 return (base::win::OSInfo::GetInstance()->wow64_status() == 234 return (base::win::OSInfo::GetInstance()->wow64_status() ==
233 base::win::OSInfo::WOW64_ENABLED); 235 base::win::OSInfo::WOW64_ENABLED);
234 } 236 }
235 #endif 237 #endif
236 238
237 NaClProcessHost::NaClProcessHost(const std::wstring& url) 239 NaClProcessHost::NaClProcessHost(const std::wstring& url)
238 : reply_msg_(NULL), 240 :
241 #if defined(OS_WIN)
242 process_launched_by_broker_(false),
243 #endif
244 reply_msg_(NULL),
239 internal_(new NaClInternal()), 245 internal_(new NaClInternal()),
240 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 246 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
241 process_.reset(content::BrowserChildProcessHost::Create( 247 process_.reset(content::BrowserChildProcessHost::Create(
242 content::PROCESS_TYPE_NACL_LOADER, this)); 248 content::PROCESS_TYPE_NACL_LOADER, this));
243 process_->SetName(WideToUTF16Hack(url)); 249 process_->SetName(WideToUTF16Hack(url));
244 #if defined(OS_WIN) 250 #if defined(OS_WIN)
245 if (!RunningOnWOW64()) { 251 if (!RunningOnWOW64()) {
246 debug_context_ = new DebugContext(); 252 debug_context_ = new DebugContext();
247 } 253 }
248 #endif 254 #endif
(...skipping 16 matching lines...) Expand all
265 LOG(ERROR) << "nacl::Close() failed"; 271 LOG(ERROR) << "nacl::Close() failed";
266 } 272 }
267 } 273 }
268 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { 274 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
269 if (nacl::Close(internal_->sockets_for_sel_ldr[i]) != 0) { 275 if (nacl::Close(internal_->sockets_for_sel_ldr[i]) != 0) {
270 LOG(ERROR) << "nacl::Close() failed"; 276 LOG(ERROR) << "nacl::Close() failed";
271 } 277 }
272 } 278 }
273 279
274 if (reply_msg_) { 280 if (reply_msg_) {
275 // The process failed to launch for some reason. 281 SendNaClLaunchError();
276 // Don't keep the renderer hanging.
277 reply_msg_->set_reply_error();
278 chrome_render_message_filter_->Send(reply_msg_);
279 } 282 }
280 #if defined(OS_WIN) 283 #if defined(OS_WIN)
281 if (RunningOnWOW64()) { 284 if (process_launched_by_broker_) {
282 // If the nacl-gdb switch is not empty, the NaCl loader has been launched 285 NaClBrokerService::GetInstance()->OnLoaderDied();
283 // without the broker and so we shouldn't inform the broker about 286 }
284 // the loader termination. 287 if (!RunningOnWOW64()) {
Mark Seaborn 2012/03/21 20:41:29 On merging with HEAD this becomes "if (debug_conte
halyavin 2012/03/22 08:35:47 Done.
285 if (CommandLine::ForCurrentProcess()->GetSwitchValuePath(
286 switches::kNaClGdb).empty()) {
287 NaClBrokerService::GetInstance()->OnLoaderDied();
288 }
289 } else {
290 debug_context_->SetChildProcessHost(NULL); 288 debug_context_->SetChildProcessHost(NULL);
291 } 289 }
292 #endif 290 #endif
293 } 291 }
294 292
295 // Attempt to ensure the IRT will be available when we need it, but don't wait. 293 // Attempt to ensure the IRT will be available when we need it, but don't wait.
296 bool NaClBrowser::EnsureIrtAvailable() { 294 bool NaClBrowser::EnsureIrtAvailable() {
297 if (IrtAvailable()) 295 if (IrtAvailable())
298 return true; 296 return true;
299 297
(...skipping 13 matching lines...) Expand all
313 // This is called at browser startup. 311 // This is called at browser startup.
314 // static 312 // static
315 void NaClProcessHost::EarlyStartup() { 313 void NaClProcessHost::EarlyStartup() {
316 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 314 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
317 // Open the IRT file early to make sure that it isn't replaced out from 315 // Open the IRT file early to make sure that it isn't replaced out from
318 // under us by autoupdate. 316 // under us by autoupdate.
319 NaClBrowser::GetInstance()->EnsureIrtAvailable(); 317 NaClBrowser::GetInstance()->EnsureIrtAvailable();
320 #endif 318 #endif
321 } 319 }
322 320
323 bool NaClProcessHost::Launch( 321 void NaClProcessHost::SendNaClLaunchError() {
Mark Seaborn 2012/03/21 20:41:29 This method only has one call site, doesn't it? Y
halyavin 2012/03/22 08:35:47 Done.
322 // The process failed to launch for some reason.
323 // Don't keep the renderer hanging.
324 reply_msg_->set_reply_error();
325 chrome_render_message_filter_->Send(reply_msg_);
326 reply_msg_ = NULL;
327 chrome_render_message_filter_ = NULL;
328 }
329
330 void NaClProcessHost::Launch(
324 ChromeRenderMessageFilter* chrome_render_message_filter, 331 ChromeRenderMessageFilter* chrome_render_message_filter,
325 int socket_count, 332 int socket_count,
326 IPC::Message* reply_msg) { 333 IPC::Message* reply_msg) {
334 chrome_render_message_filter_ = chrome_render_message_filter;
335 reply_msg_ = reply_msg;
336
327 // Place an arbitrary limit on the number of sockets to limit 337 // Place an arbitrary limit on the number of sockets to limit
328 // exposure in case the renderer is compromised. We can increase 338 // exposure in case the renderer is compromised. We can increase
329 // this if necessary. 339 // this if necessary.
330 if (socket_count > 8) { 340 if (socket_count > 8) {
331 return false; 341 delete this;
342 return;
332 } 343 }
333 344
334 // Start getting the IRT open asynchronously while we launch the NaCl process. 345 // Start getting the IRT open asynchronously while we launch the NaCl process.
335 // We'll make sure this actually finished in OnProcessLaunched, below. 346 // We'll make sure this actually finished in OnProcessLaunched, below.
336 if (!NaClBrowser::GetInstance()->EnsureIrtAvailable()) { 347 if (!NaClBrowser::GetInstance()->EnsureIrtAvailable()) {
337 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed"; 348 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed";
338 return false; 349 delete this;
350 return;
339 } 351 }
340 352
341 // Rather than creating a socket pair in the renderer, and passing 353 // Rather than creating a socket pair in the renderer, and passing
342 // one side through the browser to sel_ldr, socket pairs are created 354 // one side through the browser to sel_ldr, socket pairs are created
343 // in the browser and then passed to the renderer and sel_ldr. 355 // in the browser and then passed to the renderer and sel_ldr.
344 // 356 //
345 // This is mainly for the benefit of Windows, where sockets cannot 357 // This is mainly for the benefit of Windows, where sockets cannot
346 // be passed in messages, but are copied via DuplicateHandle(). 358 // be passed in messages, but are copied via DuplicateHandle().
347 // This means the sandboxed renderer cannot send handles to the 359 // This means the sandboxed renderer cannot send handles to the
348 // browser process. 360 // browser process.
349 361
350 for (int i = 0; i < socket_count; i++) { 362 for (int i = 0; i < socket_count; i++) {
351 nacl::Handle pair[2]; 363 nacl::Handle pair[2];
352 // Create a connected socket 364 // Create a connected socket
353 if (nacl::SocketPair(pair) == -1) 365 if (nacl::SocketPair(pair) == -1) {
354 return false; 366 delete this;
367 return;
368 }
355 internal_->sockets_for_renderer.push_back(pair[0]); 369 internal_->sockets_for_renderer.push_back(pair[0]);
356 internal_->sockets_for_sel_ldr.push_back(pair[1]); 370 internal_->sockets_for_sel_ldr.push_back(pair[1]);
357 SetCloseOnExec(pair[0]); 371 SetCloseOnExec(pair[0]);
358 SetCloseOnExec(pair[1]); 372 SetCloseOnExec(pair[1]);
359 } 373 }
360 374
361 // Launch the process 375 // Launch the process
362 if (!LaunchSelLdr()) { 376 if (!LaunchSelLdr()) {
363 return false; 377 delete this;
364 } 378 }
365
366 chrome_render_message_filter_ = chrome_render_message_filter;
367
368 // On success, we take responsibility for sending the reply.
369 reply_msg_ = reply_msg;
370 return true;
371 } 379 }
372 380
373 scoped_ptr<CommandLine> NaClProcessHost::LaunchWithNaClGdb( 381 scoped_ptr<CommandLine> NaClProcessHost::LaunchWithNaClGdb(
374 const FilePath& nacl_gdb, CommandLine* line) { 382 const FilePath& nacl_gdb, CommandLine* line) {
375 CommandLine* cmd_line = new CommandLine(nacl_gdb); 383 CommandLine* cmd_line = new CommandLine(nacl_gdb);
376 // We can't use PrependWrapper because our parameters contain spaces. 384 // We can't use PrependWrapper because our parameters contain spaces.
377 cmd_line->AppendArg("--eval-command"); 385 cmd_line->AppendArg("--eval-command");
378 const FilePath::StringType& irt_path = 386 const FilePath::StringType& irt_path =
379 NaClBrowser::GetInstance()->GetIrtFilePath().value(); 387 NaClBrowser::GetInstance()->GetIrtFilePath().value();
380 cmd_line->AppendArgNative(FILE_PATH_LITERAL("nacl-irt ") + irt_path); 388 cmd_line->AppendArgNative(FILE_PATH_LITERAL("nacl-irt ") + irt_path);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 #elif defined(OS_POSIX) 476 #elif defined(OS_POSIX)
469 process_->Launch(nacl_loader_prefix.empty(), // use_zygote 477 process_->Launch(nacl_loader_prefix.empty(), // use_zygote
470 base::EnvironmentVector(), 478 base::EnvironmentVector(),
471 cmd_line.release()); 479 cmd_line.release());
472 #endif 480 #endif
473 481
474 return true; 482 return true;
475 } 483 }
476 484
477 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { 485 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
486 #if defined(OS_WIN)
487 process_launched_by_broker_ = true;
488 #endif
478 process_->SetHandle(handle); 489 process_->SetHandle(handle);
479 OnProcessLaunched(); 490 OnProcessLaunched();
480 } 491 }
481 492
482 void NaClProcessHost::OnProcessCrashed(int exit_code) { 493 void NaClProcessHost::OnProcessCrashed(int exit_code) {
483 std::string message = base::StringPrintf( 494 std::string message = base::StringPrintf(
484 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); 495 "NaCl process exited with status %i (0x%x)", exit_code, exit_code);
485 LOG(ERROR) << message; 496 LOG(ERROR) << message;
486 } 497 }
487 498
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 process_->Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); 813 process_->Send(new NaClProcessMsg_Start(handles_for_sel_ldr));
803 #endif 814 #endif
804 815
805 internal_->sockets_for_sel_ldr.clear(); 816 internal_->sockets_for_sel_ldr.clear();
806 } 817 }
807 818
808 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { 819 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
809 NOTREACHED() << "Invalid message with type = " << msg.type(); 820 NOTREACHED() << "Invalid message with type = " << msg.type();
810 return false; 821 return false;
811 } 822 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698