| Index: content/child/child_thread.cc
|
| diff --git a/content/child/child_thread.cc b/content/child/child_thread.cc
|
| index d5fc4b4703895f653973b696bf04acfb38390d07..72be9fba30678ed1e49a9cec6b18d4e0166d84e0 100644
|
| --- a/content/child/child_thread.cc
|
| +++ b/content/child/child_thread.cc
|
| @@ -70,6 +70,45 @@ base::LazyInstance<base::ThreadLocalPointer<ChildThread> > g_lazy_tls =
|
| // plugins), PluginThread has EnsureTerminateMessageFilter.
|
| #if defined(OS_POSIX)
|
|
|
| +// TODO(earthdok): Re-enable on CrOS http://crbug.com/360622
|
| +#if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
|
| + defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS)
|
| +// A thread delegate that waits for |duration| and then exits the process with
|
| +// _exit(0).
|
| +class WaitAndExitDelegate : public base::PlatformThread::Delegate {
|
| + public:
|
| + explicit WaitAndExitDelegate(base::TimeDelta duration)
|
| + : duration_(duration) {}
|
| + virtual ~WaitAndExitDelegate() OVERRIDE {}
|
| +
|
| + virtual void ThreadMain() OVERRIDE {
|
| + base::PlatformThread::Sleep(duration_);
|
| + _exit(0);
|
| + }
|
| +
|
| + private:
|
| + const base::TimeDelta duration_;
|
| + DISALLOW_COPY_AND_ASSIGN(WaitAndExitDelegate);
|
| +};
|
| +
|
| +bool CreateWaitAndExitThread(base::TimeDelta duration) {
|
| + scoped_ptr<WaitAndExitDelegate> delegate(new WaitAndExitDelegate(duration));
|
| +
|
| + const bool thread_created =
|
| + base::PlatformThread::CreateNonJoinable(0, delegate.get());
|
| + if (!thread_created)
|
| + return false;
|
| +
|
| + // A non joinable thread has been created. The thread will either terminate
|
| + // the process or will be terminated by the process. Therefore, keep the
|
| + // delegate object alive for the lifetime of the process.
|
| + WaitAndExitDelegate* leaking_delegate = delegate.release();
|
| + ANNOTATE_LEAKING_OBJECT_PTR(leaking_delegate);
|
| + ignore_result(leaking_delegate);
|
| + return true;
|
| +}
|
| +#endif
|
| +
|
| class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter {
|
| public:
|
| // IPC::ChannelProxy::MessageFilter
|
| @@ -89,7 +128,21 @@ class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter {
|
| //
|
| // So, we install a filter on the channel so that we can process this event
|
| // here and kill the process.
|
| + // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622
|
| +#if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
|
| + defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS)
|
| + // Some sanitizer tools rely on exit handlers (e.g. to run leak detection,
|
| + // or dump code coverage data to disk). Instead of exiting the process
|
| + // immediately, we give it 60 seconds to run exit handlers.
|
| + CHECK(CreateWaitAndExitThread(base::TimeDelta::FromSeconds(60)));
|
| +#if defined(LEAK_SANITIZER)
|
| + // Invoke LeakSanitizer early to avoid detecting shutdown-only leaks. If
|
| + // leaks are found, the process will exit here.
|
| + __lsan_do_leak_check();
|
| +#endif
|
| +#else
|
| _exit(0);
|
| +#endif
|
| }
|
|
|
| protected:
|
|
|