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

Side by Side Diff: content/child/child_thread.cc

Issue 227563004: Re-land 261836 "Restore --child-clean-exit behavior for ASan/LSan..." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 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
« no previous file with comments | « content/browser/child_process_launcher.cc ('k') | tools/lsan/suppressions.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "content/child/child_thread.h" 5 #include "content/child/child_thread.h"
6 6
7 #include <signal.h> 7 #include <signal.h>
8 8
9 #include <string> 9 #include <string>
10 10
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 const int kConnectionTimeoutS = 15; 63 const int kConnectionTimeoutS = 15;
64 64
65 base::LazyInstance<base::ThreadLocalPointer<ChildThread> > g_lazy_tls = 65 base::LazyInstance<base::ThreadLocalPointer<ChildThread> > g_lazy_tls =
66 LAZY_INSTANCE_INITIALIZER; 66 LAZY_INSTANCE_INITIALIZER;
67 67
68 // This isn't needed on Windows because there the sandbox's job object 68 // This isn't needed on Windows because there the sandbox's job object
69 // terminates child processes automatically. For unsandboxed processes (i.e. 69 // terminates child processes automatically. For unsandboxed processes (i.e.
70 // plugins), PluginThread has EnsureTerminateMessageFilter. 70 // plugins), PluginThread has EnsureTerminateMessageFilter.
71 #if defined(OS_POSIX) 71 #if defined(OS_POSIX)
72 72
73 // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622
74 #if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
75 defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS)
76 // A thread delegate that waits for |duration| and then exits the process with
77 // _exit(0).
78 class WaitAndExitDelegate : public base::PlatformThread::Delegate {
79 public:
80 explicit WaitAndExitDelegate(base::TimeDelta duration)
81 : duration_(duration) {}
82 virtual ~WaitAndExitDelegate() OVERRIDE {}
83
84 virtual void ThreadMain() OVERRIDE {
85 base::PlatformThread::Sleep(duration_);
86 _exit(0);
87 }
88
89 private:
90 const base::TimeDelta duration_;
91 DISALLOW_COPY_AND_ASSIGN(WaitAndExitDelegate);
92 };
93
94 bool CreateWaitAndExitThread(base::TimeDelta duration) {
95 scoped_ptr<WaitAndExitDelegate> delegate(new WaitAndExitDelegate(duration));
96
97 const bool thread_created =
98 base::PlatformThread::CreateNonJoinable(0, delegate.get());
99 if (!thread_created)
100 return false;
101
102 // A non joinable thread has been created. The thread will either terminate
103 // the process or will be terminated by the process. Therefore, keep the
104 // delegate object alive for the lifetime of the process.
105 WaitAndExitDelegate* leaking_delegate = delegate.release();
106 ANNOTATE_LEAKING_OBJECT_PTR(leaking_delegate);
107 ignore_result(leaking_delegate);
108 return true;
109 }
110 #endif
111
73 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter { 112 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter {
74 public: 113 public:
75 // IPC::ChannelProxy::MessageFilter 114 // IPC::ChannelProxy::MessageFilter
76 virtual void OnChannelError() OVERRIDE { 115 virtual void OnChannelError() OVERRIDE {
77 // For renderer/worker processes: 116 // For renderer/worker processes:
78 // On POSIX, at least, one can install an unload handler which loops 117 // On POSIX, at least, one can install an unload handler which loops
79 // forever and leave behind a renderer process which eats 100% CPU forever. 118 // forever and leave behind a renderer process which eats 100% CPU forever.
80 // 119 //
81 // This is because the terminate signals (ViewMsg_ShouldClose and the error 120 // This is because the terminate signals (ViewMsg_ShouldClose and the error
82 // from the IPC channel) are routed to the main message loop but never 121 // from the IPC channel) are routed to the main message loop but never
83 // processed (because that message loop is stuck in V8). 122 // processed (because that message loop is stuck in V8).
84 // 123 //
85 // One could make the browser SIGKILL the renderers, but that leaves open a 124 // One could make the browser SIGKILL the renderers, but that leaves open a
86 // large window where a browser failure (or a user, manually terminating 125 // large window where a browser failure (or a user, manually terminating
87 // the browser because "it's stuck") will leave behind a process eating all 126 // the browser because "it's stuck") will leave behind a process eating all
88 // the CPU. 127 // the CPU.
89 // 128 //
90 // So, we install a filter on the channel so that we can process this event 129 // So, we install a filter on the channel so that we can process this event
91 // here and kill the process. 130 // here and kill the process.
131 // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622
132 #if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
133 defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS)
134 // Some sanitizer tools rely on exit handlers (e.g. to run leak detection,
135 // or dump code coverage data to disk). Instead of exiting the process
136 // immediately, we give it 60 seconds to run exit handlers.
137 CHECK(CreateWaitAndExitThread(base::TimeDelta::FromSeconds(60)));
138 #if defined(LEAK_SANITIZER)
139 // Invoke LeakSanitizer early to avoid detecting shutdown-only leaks. If
140 // leaks are found, the process will exit here.
141 __lsan_do_leak_check();
142 #endif
143 #else
92 _exit(0); 144 _exit(0);
145 #endif
93 } 146 }
94 147
95 protected: 148 protected:
96 virtual ~SuicideOnChannelErrorFilter() {} 149 virtual ~SuicideOnChannelErrorFilter() {}
97 }; 150 };
98 151
99 #endif // OS(POSIX) 152 #endif // OS(POSIX)
100 153
101 #if defined(OS_ANDROID) 154 #if defined(OS_ANDROID)
102 ChildThread* g_child_thread = NULL; 155 ChildThread* g_child_thread = NULL;
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 // inflight that would addref it. 533 // inflight that would addref it.
481 Send(new ChildProcessHostMsg_ShutdownRequest); 534 Send(new ChildProcessHostMsg_ShutdownRequest);
482 } 535 }
483 536
484 void ChildThread::EnsureConnected() { 537 void ChildThread::EnsureConnected() {
485 VLOG(0) << "ChildThread::EnsureConnected()"; 538 VLOG(0) << "ChildThread::EnsureConnected()";
486 base::KillProcess(base::GetCurrentProcessHandle(), 0, false); 539 base::KillProcess(base::GetCurrentProcessHandle(), 0, false);
487 } 540 }
488 541
489 } // namespace content 542 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/child_process_launcher.cc ('k') | tools/lsan/suppressions.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698