diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-10 23:28:46 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-10 23:28:46 +0000 |
commit | ac577490a5c20950f63d655de37058dc41486e99 (patch) | |
tree | e5a53f6cad3317c2451f8ef39bf0b19bd8706e79 /chrome | |
parent | 0f1169993f28f8da9be5a81496fb2e2abf311387 (diff) | |
download | chromium_src-ac577490a5c20950f63d655de37058dc41486e99.zip chromium_src-ac577490a5c20950f63d655de37058dc41486e99.tar.gz chromium_src-ac577490a5c20950f63d655de37058dc41486e99.tar.bz2 |
Revert 18109, 18111: Windows UI tests failed.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18112 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
24 files changed, 145 insertions, 494 deletions
diff --git a/chrome/app/breakpad_linux.cc b/chrome/app/breakpad_linux.cc index ef3dfa2..0ee0bed 100644 --- a/chrome/app/breakpad_linux.cc +++ b/chrome/app/breakpad_linux.cc @@ -14,13 +14,13 @@ #include "base/file_version_info_linux.h" #include "base/path_service.h" #include "base/rand_util.h" +#include "base/reserved_file_descriptors.h" #include "breakpad/linux/directory_reader.h" #include "breakpad/linux/exception_handler.h" #include "breakpad/linux/linux_libc_support.h" #include "breakpad/linux/linux_syscall_support.h" #include "breakpad/linux/memory.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/chrome_descriptors.h" #include "chrome/installer/util/google_update_settings.h" static const char kUploadURL[] = @@ -501,11 +501,13 @@ RendererCrashHandler(const void* crash_context, size_t crash_context_size, } void EnableRendererCrashDumping() { - const int fd = Singleton<base::GlobalDescriptors>()->Get(kCrashDumpSignal); + // When the browser forks off our process, it installs the crash signal file + // descriptor in slot kMagicCrashSignalFd. + // We deliberately leak this object. google_breakpad::ExceptionHandler* handler = new google_breakpad::ExceptionHandler("" /* unused */, NULL, NULL, - (void*) fd, true); + (void*) kMagicCrashSignalFd, true); handler->set_crash_handler(RendererCrashHandler); } diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc index 33e774c..b6ba22f 100644 --- a/chrome/app/chrome_dll_main.cc +++ b/chrome/app/chrome_dll_main.cc @@ -34,9 +34,6 @@ #include "base/at_exit.h" #include "base/command_line.h" #include "base/debug_util.h" -#if defined(OS_POSIX) -#include "base/global_descriptors_posix.h" -#endif #include "base/icu_util.h" #include "base/message_loop.h" #include "base/path_service.h" @@ -48,6 +45,9 @@ #if defined(OS_WIN) #include "base/win_util.h" #endif +#if defined(OS_LINUX) +#include "base/zygote_manager.h" +#endif #if defined(OS_MACOSX) #include "chrome/app/breakpad_mac.h" #elif defined(OS_LINUX) @@ -57,7 +57,6 @@ #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_counters.h" -#include "chrome/common/chrome_descriptors.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/logging_chrome.h" @@ -76,7 +75,6 @@ extern int RendererMain(const MainFunctionParams&); extern int PluginMain(const MainFunctionParams&); extern int WorkerMain(const MainFunctionParams&); extern int UtilityMain(const MainFunctionParams&); -extern int ZygoteMain(const MainFunctionParams&); #if defined(OS_WIN) // TODO(erikkay): isn't this already defined somewhere? @@ -294,19 +292,21 @@ int ChromeMain(int argc, const char** argv) { // its main event loop to get rid of the cruft. base::ScopedNSAutoreleasePool autorelease_pool; -#if defined(OS_POSIX) - base::GlobalDescriptors* g_fds = Singleton<base::GlobalDescriptors>::get(); - g_fds->Set(kPrimaryIPCChannel, - kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor); -#if defined(OS_LINUX) - g_fds->Set(kCrashDumpSignal, - kCrashDumpSignal + base::GlobalDescriptors::kBaseDescriptor); -#endif -#endif - // Initialize the command line. #if defined(OS_WIN) CommandLine::Init(0, NULL); +#elif defined(OS_LINUX) + base::ZygoteManager* zm = base::ZygoteManager::Get(); + std::vector<std::string>* zargv = NULL; + if (zm) + zargv = zm->Start(); + if (zargv) { + // Forked child. + CommandLine::Init(*zargv); + } else { + // Original process. + CommandLine::Init(argc, argv); + } #else CommandLine::Init(argc, argv); #endif @@ -339,13 +339,11 @@ int ChromeMain(int argc, const char** argv) { CHECK(sigaction(SIGPIPE, &action, 0) == 0); #endif // OS_POSIX } else { -#if defined(OS_WIN) std::wstring channel_name = parsed_command_line.GetSwitchValue(switches::kProcessChannelID); browser_pid = StringToInt(WideToASCII(channel_name)); DCHECK(browser_pid != 0); -#endif #if defined(OS_POSIX) // When you hit Ctrl-C in a terminal running the browser @@ -491,13 +489,6 @@ int ChromeMain(int argc, const char** argv) { #else NOTIMPLEMENTED(); #endif - } else if (process_type == switches::kZygoteProcess) { -#if defined(OS_LINUX) - if (ZygoteMain(main_params)) - RendererMain(main_params); -#else - NOTIMPLEMENTED(); -#endif } else if (process_type.empty()) { #if defined(OS_LINUX) // Glib type system initialization. Needed at least for gconf, diff --git a/chrome/app/chrome_main_uitest.cc b/chrome/app/chrome_main_uitest.cc index f229751..5ce05c2 100644 --- a/chrome/app/chrome_main_uitest.cc +++ b/chrome/app/chrome_main_uitest.cc @@ -18,14 +18,9 @@ TEST_F(ChromeMainTest, AppLaunch) { if (UITest::in_process_renderer()) { EXPECT_EQ(1, UITest::GetBrowserProcessCount()); } else { -#if defined(OS_LINUX) - // On Linux we'll have three processes: browser, renderer and zygote. - EXPECT_EQ(3, UITest::GetBrowserProcessCount()); -#else // We should have two instances of the browser process alive - // one is the Browser and the other is the Renderer. EXPECT_EQ(2, UITest::GetBrowserProcessCount()); -#endif } } diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 5216755..921f860 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -14,9 +14,6 @@ #include "app/app_switches.h" #include "base/command_line.h" -#if defined(OS_POSIX) -#include "base/global_descriptors_posix.h" -#endif #include "base/file_path.h" #include "base/file_util.h" #include "base/file_version_info.h" @@ -33,7 +30,6 @@ #include "chrome/browser/renderer_host/browser_render_process_host.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" -#include "chrome/common/chrome_descriptors.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_plugin_lib.h" #include "chrome/common/chrome_switches.h" @@ -397,10 +393,10 @@ bool PluginProcessHost::Init(const WebPluginInfo& info, // This code is duplicated with browser_render_process_host.cc, but // there's not a good place to de-duplicate it. base::file_handle_mapping_vector fds_to_map; - const int ipcfd = channel().GetClientFileDescriptor(); - if (ipcfd > -1) - fds_to_map.push_back(std::pair<int, int>( - ipcfd, kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); + int src_fd = -1, dest_fd = -1; + channel().GetClientFileDescriptorMapping(&src_fd, &dest_fd); + if (src_fd > -1) + fds_to_map.push_back(std::pair<int, int>(src_fd, dest_fd)); base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process); #endif diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 29e7ef0..829ef47 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -22,6 +22,7 @@ #include "base/path_service.h" #include "base/process_util.h" #include "base/rand_util.h" +#include "base/reserved_file_descriptors.h" #include "base/scoped_ptr.h" #include "base/shared_memory.h" #include "base/singleton.h" @@ -34,6 +35,9 @@ #include "chrome/browser/history/history.h" #include "chrome/browser/plugin_service.h" #include "chrome/browser/profile.h" +#if defined(OS_LINUX) +#include "chrome/browser/renderer_host/render_crash_handler_host_linux.h" +#endif #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_helper.h" #include "chrome/browser/renderer_host/render_widget_host.h" @@ -41,7 +45,6 @@ #include "chrome/browser/renderer_host/web_cache_manager.h" #include "chrome/browser/visitedlink_master.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/chrome_descriptors.h" #include "chrome/common/child_process_info.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/notification_service.h" @@ -51,11 +54,6 @@ #include "chrome/renderer/render_process.h" #include "grit/generated_resources.h" -#if defined(OS_LINUX) -#include "chrome/browser/zygote_host_linux.h" -#include "chrome/browser/renderer_host/render_crash_handler_host_linux.h" -#endif - using WebKit::WebCache; #if defined(OS_WIN) @@ -136,8 +134,7 @@ BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile) backgrounded_(true), ALLOW_THIS_IN_INITIALIZER_LIST(cached_dibs_cleaner_( base::TimeDelta::FromSeconds(5), - this, &BrowserRenderProcessHost::ClearTransportDIBCache)), - zygote_child_(false) { + this, &BrowserRenderProcessHost::ClearTransportDIBCache)) { widget_helper_ = new RenderWidgetHelper(); registrar_.Add(this, NotificationType::USER_SCRIPTS_UPDATED, @@ -173,13 +170,7 @@ BrowserRenderProcessHost::~BrowserRenderProcessHost() { audio_renderer_host_->Destroy(); if (process_.handle() && !run_renderer_in_process()) { - if (zygote_child_) { -#if defined(OS_LINUX) - Singleton<ZygoteHost>()->EnsureProcessTerminated(process_.handle()); -#endif - } else { - ProcessWatcher::EnsureProcessTerminated(process_.handle()); - } + ProcessWatcher::EnsureProcessTerminated(process_.handle()); } ClearTransportDIBCache(); @@ -303,9 +294,7 @@ bool BrowserRenderProcessHost::Init() { ASCIIToWide(field_trial->MakePersistentString())); #if defined(OS_POSIX) - const bool has_cmd_prefix = - browser_command_line.HasSwitch(switches::kRendererCmdPrefix); - if (has_cmd_prefix) { + if (browser_command_line.HasSwitch(switches::kRendererCmdPrefix)) { // launch the renderer child with some prefix (usually "gdb --args") const std::wstring prefix = browser_command_line.GetSwitchValue(switches::kRendererCmdPrefix); @@ -345,42 +334,24 @@ bool BrowserRenderProcessHost::Init() { base::ProcessHandle process = 0; #if defined(OS_WIN) process = sandbox::StartProcess(&cmd_line); -#elif defined(OS_POSIX) -#if defined(OS_LINUX) - if (!has_cmd_prefix) { - base::GlobalDescriptors::Mapping mapping; - const int ipcfd = channel_->GetClientFileDescriptor(); - mapping.push_back(std::pair<uint32_t, int>(kPrimaryIPCChannel, ipcfd)); - const int crash_signal_fd = - Singleton<RenderCrashHandlerHostLinux>()->GetDeathSignalSocket(); - if (crash_signal_fd >= 0) { - mapping.push_back(std::pair<uint32_t, int>(kCrashDumpSignal, - crash_signal_fd)); - } - process = Singleton<ZygoteHost>()->ForkRenderer(cmd_line.argv(), mapping); - zygote_child_ = true; - } else { -#endif - // NOTE: This code is duplicated with plugin_process_host.cc, but - // there's not a good place to de-duplicate it. - base::file_handle_mapping_vector fds_to_map; - const int ipcfd = channel_->GetClientFileDescriptor(); - fds_to_map.push_back(std::make_pair(ipcfd, kPrimaryIPCChannel + 3)); -#if defined(OS_LINUX) - const int crash_signal_fd = - Singleton<RenderCrashHandlerHostLinux>()->GetDeathSignalSocket(); - if (crash_signal_fd >= 0) { - fds_to_map.push_back(std::make_pair(crash_signal_fd, - kCrashDumpSignal + 3)); - } -#endif - base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process); - zygote_child_ = false; +#else + // NOTE: This code is duplicated with plugin_process_host.cc, but + // there's not a good place to de-duplicate it. + base::file_handle_mapping_vector fds_to_map; + int src_fd = -1, dest_fd = -1; + channel_->GetClientFileDescriptorMapping(&src_fd, &dest_fd); + if (src_fd > -1) + fds_to_map.push_back(std::pair<int, int>(src_fd, dest_fd)); #if defined(OS_LINUX) - } + const int crash_signal_fd = + Singleton<RenderCrashHandlerHostLinux>()->GetDeathSignalSocket(); + if (crash_signal_fd >= 0) + fds_to_map.push_back(std::make_pair(crash_signal_fd, kMagicCrashSignalFd)); + base::ForkApp(cmd_line.argv(), fds_to_map, &process); +#else + base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process); #endif #endif - if (!process) { channel_.reset(); return false; @@ -695,7 +666,7 @@ void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) { const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); if (cmd_line.HasSwitch(switches::kRendererCmdPrefix)) return; - CHECK(peer_pid == process_.pid()) << peer_pid << " " << process_.pid(); + CHECK(peer_pid == process_.pid()); } } } diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h index 6c259f0..b380211 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.h +++ b/chrome/browser/renderer_host/browser_render_process_host.h @@ -154,9 +154,6 @@ class BrowserRenderProcessHost : public RenderProcessHost, // Used in single-process mode. scoped_ptr<RendererMainThread> in_process_renderer_; - // True iff the renderer is a child of a zygote process. - bool zygote_child_; - DISALLOW_COPY_AND_ASSIGN(BrowserRenderProcessHost); }; diff --git a/chrome/browser/zygote_host_linux.cc b/chrome/browser/zygote_host_linux.cc deleted file mode 100644 index f56e6e93..0000000 --- a/chrome/browser/zygote_host_linux.cc +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/zygote_host_linux.h" - -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include "base/command_line.h" -#include "base/eintr_wrapper.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/pickle.h" -#include "base/process_util.h" -#include "base/unix_domain_socket_posix.h" - -#include "chrome/common/chrome_switches.h" - -ZygoteHost::ZygoteHost() { - std::wstring chrome_path; - CHECK(PathService::Get(base::FILE_EXE, &chrome_path)); - CommandLine cmd_line(chrome_path); - - cmd_line.AppendSwitchWithValue(switches::kProcessType, - switches::kZygoteProcess); - - int fds[2]; - CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0); - base::file_handle_mapping_vector fds_to_map; - fds_to_map.push_back(std::make_pair(fds[1], 3)); - - const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); - if (browser_command_line.HasSwitch(switches::kZygoteCmdPrefix)) { - const std::wstring prefix = - browser_command_line.GetSwitchValue(switches::kZygoteCmdPrefix); - cmd_line.PrependWrapper(prefix); - } - - base::ProcessHandle process; - base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process); - CHECK(process != -1) << "Failed to launch zygote process"; - - close(fds[1]); - control_fd_ = fds[0]; -} - -ZygoteHost::~ZygoteHost() { - close(control_fd_); -} - -pid_t ZygoteHost::ForkRenderer( - const std::vector<std::string>& argv, - const base::GlobalDescriptors::Mapping& mapping) { - Pickle pickle; - - pickle.WriteInt(kCmdFork); - pickle.WriteInt(argv.size()); - for (std::vector<std::string>::const_iterator - i = argv.begin(); i != argv.end(); ++i) - pickle.WriteString(*i); - - pickle.WriteInt(mapping.size()); - - std::vector<int> fds; - for (base::GlobalDescriptors::Mapping::const_iterator - i = mapping.begin(); i != mapping.end(); ++i) { - pickle.WriteUInt32(i->first); - fds.push_back(i->second); - } - - if (!base::SendMsg(control_fd_, pickle.data(), pickle.size(), fds)) - return -1; - - pid_t pid; - if (HANDLE_EINTR(read(control_fd_, &pid, sizeof(pid))) != sizeof(pid)) - return -1; - - return pid; -} - -void ZygoteHost::EnsureProcessTerminated(pid_t process) { - Pickle pickle; - - pickle.WriteInt(kCmdReap); - pickle.WriteInt(process); - - HANDLE_EINTR(write(control_fd_, pickle.data(), pickle.size())); -} diff --git a/chrome/browser/zygote_host_linux.h b/chrome/browser/zygote_host_linux.h deleted file mode 100644 index 279918d..0000000 --- a/chrome/browser/zygote_host_linux.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_ZYGOTE_HOST_LINUX_H_ -#define CHROME_BROWSER_ZYGOTE_HOST_LINUX_H_ - -#include <string> -#include <vector> - -#include "base/global_descriptors_posix.h" -#include "base/singleton.h" - -// http://code.google.com/p/chromium/wiki/LinuxZygote - -// The zygote host is the interface, in the browser process, to the zygote -// process. -class ZygoteHost { - public: - ~ZygoteHost(); - - pid_t ForkRenderer(const std::vector<std::string>& command_line, - const base::GlobalDescriptors::Mapping& mapping); - void EnsureProcessTerminated(pid_t process); - - // These are the command codes used on the wire between the browser and the - // zygote. - enum { - kCmdFork = 0, // Fork off a new renderer. - kCmdReap = 1, // Reap a renderer child. - }; - - private: - friend struct DefaultSingletonTraits<ZygoteHost>; - ZygoteHost(); - void LaunchZygoteProcess(); - - int control_fd_; // the socket to the zygote -}; - -#endif // CHROME_BROWSER_ZYGOTE_HOST_LINUX_H_ diff --git a/chrome/browser/zygote_main_linux.cc b/chrome/browser/zygote_main_linux.cc deleted file mode 100644 index d450c39..0000000 --- a/chrome/browser/zygote_main_linux.cc +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <unistd.h> -#include <sys/epoll.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/signal.h> - -#include "base/command_line.h" -#include "base/eintr_wrapper.h" -#include "base/global_descriptors_posix.h" -#include "base/pickle.h" -#include "base/unix_domain_socket_posix.h" - -#include "chrome/browser/zygote_host_linux.h" -#include "chrome/common/chrome_descriptors.h" -#include "chrome/common/main_function_params.h" -#include "chrome/common/process_watcher.h" - -// http://code.google.com/p/chromium/wiki/LinuxZygote - -// This is the object which implements the zygote. The ZygoteMain function, -// which is called from ChromeMain, at the the bottom and simple constructs one -// of these objects and runs it. -class Zygote { - public: - bool ProcessRequests() { - // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the - // browser on it. - - // We need to accept SIGCHLD, even though our handler is a no-op because - // otherwise we cannot wait on children. (According to POSIX 2001.) - struct sigaction action; - memset(&action, 0, sizeof(action)); - action.sa_handler = SIGCHLDHandler; - CHECK(sigaction(SIGCHLD, &action, NULL) == 0); - - for (;;) { - if (HandleRequestFromBrowser(3)) - return true; - } - } - - private: - // See comment below, where sigaction is called. - static void SIGCHLDHandler(int signal) { } - - // --------------------------------------------------------------------------- - // Requests from the browser... - - // Read and process a request from the browser. Returns true if we are in a - // new process and thus need to unwind back into ChromeMain. - bool HandleRequestFromBrowser(int fd) { - std::vector<int> fds; - static const unsigned kMaxMessageLength = 2048; - char buf[kMaxMessageLength]; - const ssize_t len = base::RecvMsg(fd, buf, sizeof(buf), &fds); - if (len == -1) { - LOG(WARNING) << "Error reading message from browser: " << errno; - return false; - } - - if (len == 0) { - // EOF from the browser. We should die. - _exit(0); - return false; - } - - Pickle pickle(buf, len); - void* iter = NULL; - - int kind; - if (!pickle.ReadInt(&iter, &kind)) - goto error; - - if (kind == ZygoteHost::kCmdFork) { - return HandleForkRequest(fd, pickle, iter, fds); - } else if (kind == ZygoteHost::kCmdReap) { - if (fds.size()) - goto error; - return HandleReapRequest(fd, pickle, iter); - } - - error: - LOG(WARNING) << "Error parsing message from browser"; - for (std::vector<int>::const_iterator - i = fds.begin(); i != fds.end(); ++i) - close(*i); - return false; - } - - bool HandleReapRequest(int fd, Pickle& pickle, void* iter) { - pid_t child; - - if (!pickle.ReadInt(&iter, &child)) { - LOG(WARNING) << "Error parsing reap request from browser"; - return false; - } - - ProcessWatcher::EnsureProcessTerminated(child); - - return false; - } - - // Handle a 'fork' request from the browser: this means that the browser - // wishes to start a new renderer. - bool HandleForkRequest(int fd, Pickle& pickle, void* iter, - std::vector<int>& fds) { - std::vector<std::string> args; - int argc, numfds; - base::GlobalDescriptors::Mapping mapping; - pid_t child; - - if (!pickle.ReadInt(&iter, &argc)) - goto error; - - for (int i = 0; i < argc; ++i) { - std::string arg; - if (!pickle.ReadString(&iter, &arg)) - goto error; - args.push_back(arg); - } - - if (!pickle.ReadInt(&iter, &numfds)) - goto error; - if (numfds != static_cast<int>(fds.size())) - goto error; - - for (int i = 0; i < numfds; ++i) { - base::GlobalDescriptors::Key key; - if (!pickle.ReadUInt32(&iter, &key)) - goto error; - mapping.push_back(std::make_pair(key, fds[i])); - } - - child = fork(); - - if (!child) { - close(3); // our socket from the browser is in fd 3 - Singleton<base::GlobalDescriptors>()->Reset(mapping); - CommandLine::Reset(); - CommandLine::Init(args); - return true; - } - - for (std::vector<int>::const_iterator - i = fds.begin(); i != fds.end(); ++i) - close(*i); - - HANDLE_EINTR(write(fd, &child, sizeof(child))); - return false; - - error: - LOG(WARNING) << "Error parsing fork request from browser"; - for (std::vector<int>::const_iterator - i = fds.begin(); i != fds.end(); ++i) - close(*i); - return false; - } - // --------------------------------------------------------------------------- -}; - -bool ZygoteMain(const MainFunctionParams& params) { - Zygote zygote; - return zygote.ProcessRequests(); -} diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index c1aefab..d9ea3ea 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1613,8 +1613,6 @@ 'browser/worker_host/worker_process_host.h', 'browser/worker_host/worker_service.cc', 'browser/worker_host/worker_service.h', - 'browser/zygote_host_linux.cc', - 'browser/zygote_main_linux.cc', 'tools/build/win/precompiled_wtl.h', 'tools/build/win/precompiled_wtl.cc', diff --git a/chrome/common/chrome_descriptors.h b/chrome/common/chrome_descriptors.h deleted file mode 100644 index 3d6be45..0000000 --- a/chrome/common/chrome_descriptors.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_CHROME_DESCRIPTORS_H_ -#define CHROME_COMMON_CHROME_DESCRIPTORS_H_ - -// This is a list of global descriptor keys to be used with the -// base::GlobalDescriptors object (see base/global_descriptors_posix.h) -enum { - kPrimaryIPCChannel = 0, - kCrashDumpSignal = 1, -}; - -#endif // CHROME_COMMON_CHROME_DESCRIPTORS_H_ diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index e5bce97..48511d3 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -63,9 +63,6 @@ const wchar_t kHomePage[] = L"homepage"; // Causes the process to run as renderer instead of as browser. const wchar_t kRendererProcess[] = L"renderer"; -// Causes the process to run as a renderer zygote. -const wchar_t kZygoteProcess[] = L"zygote"; - // Path to the exe to run for the renderer and plugin subprocesses. const wchar_t kBrowserSubprocessPath[] = L"browser-subprocess-path"; @@ -493,9 +490,6 @@ const wchar_t kNoDefaultBrowserCheck[] = L"no-default-browser-check"; // Enables the benchmarking extensions. const wchar_t kEnableBenchmarking[] = L"enable-benchmarking"; -// The prefix used when starting the zygote process. (i.e. 'gdb --args') -const wchar_t kZygoteCmdPrefix[] = L"zygote-cmd-prefix"; - // Enables using ThumbnailStore instead of ThumbnailDatabase for setting and // getting thumbnails for the new tab page. const wchar_t kThumbnailStore[] = L"thumbnail-store"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 33a0239..8259d72 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -26,7 +26,6 @@ extern const wchar_t kProcessChannelID[]; extern const wchar_t kTestingChannelID[]; extern const wchar_t kHomePage[]; extern const wchar_t kRendererProcess[]; -extern const wchar_t kZygoteProcess[]; extern const wchar_t kBrowserSubprocessPath[]; extern const wchar_t kPluginProcess[]; extern const wchar_t kWorkerProcess[]; @@ -186,8 +185,6 @@ extern const wchar_t kEnableBenchmarking[]; extern const wchar_t kNoDefaultBrowserCheck[]; -extern const wchar_t kZygoteCmdPrefix[]; - extern const wchar_t kThumbnailStore[]; } // namespace switches diff --git a/chrome/common/ipc_channel.h b/chrome/common/ipc_channel.h index 85b35fa..f619508 100644 --- a/chrome/common/ipc_channel.h +++ b/chrome/common/ipc_channel.h @@ -87,13 +87,14 @@ class Channel : public Message::Sender { #if defined(OS_POSIX) // On POSIX an IPC::Channel wraps a socketpair(), this method returns the - // FD # for the client end of the socket. + // FD # for the client end of the socket and the equivalent FD# to use for + // mapping it into the Child process. // This method may only be called on the server side of a channel. // // If the kTestingChannelID flag is specified on the command line then // a named FIFO is used as the channel transport mechanism rather than a - // socketpair() in which case this method returns -1. - int GetClientFileDescriptor() const; + // socketpair() in which case this method returns -1 for both parameters. + void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const; #endif // defined(OS_POSIX) private: diff --git a/chrome/common/ipc_channel_posix.cc b/chrome/common/ipc_channel_posix.cc index babc16c..52cad9d 100644 --- a/chrome/common/ipc_channel_posix.cc +++ b/chrome/common/ipc_channel_posix.cc @@ -17,16 +17,15 @@ #include "base/command_line.h" #include "base/eintr_wrapper.h" -#include "base/global_descriptors_posix.h" #include "base/lock.h" #include "base/logging.h" #include "base/process_util.h" +#include "base/reserved_file_descriptors.h" #include "base/scoped_ptr.h" #include "base/string_util.h" #include "base/singleton.h" #include "base/stats_counters.h" #include "chrome/common/chrome_counters.h" -#include "chrome/common/chrome_descriptors.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/file_descriptor_set_posix.h" #include "chrome/common/ipc_logging.h" @@ -41,7 +40,7 @@ namespace IPC { // // When creating a child subprocess, the parent side of the fork // arranges it such that the initial control channel ends up on the -// magic file descriptor kPrimaryIPCChannel in the child. Future +// magic file descriptor kClientChannelFd in the child. Future // connections (file descriptors) can then be passed via that // connection via sendmsg(). @@ -51,7 +50,7 @@ namespace { // The PipeMap class works around this quirk related to unit tests: // // When running as a server, we install the client socket in a -// specific file descriptor number (@kPrimaryIPCChannel). However, we +// specific file descriptor number (@kClientChannelFd). However, we // also have to support the case where we are running unittests in the // same process. (We do not support forking without execing.) // @@ -59,7 +58,7 @@ namespace { // The IPC server object will install a mapping in PipeMap from the // name which it was given to the client pipe. When forking the client, the // GetClientFileDescriptorMapping will ensure that the socket is installed in -// the magic slot (@kPrimaryIPCChannel). The client will search for the +// the magic slot (@kClientChannelFd). The client will search for the // mapping, but it won't find any since we are in a new process. Thus the // magic fd number is returned. Once the client connects, the server will // close its copy of the client socket and remove the mapping. @@ -125,7 +124,10 @@ int ChannelNameToClientFD(const std::string& channel_id) { // If we don't find an entry, we assume that the correct value has been // inserted in the magic slot. - return Singleton<base::GlobalDescriptors>()->Get(kPrimaryIPCChannel); + // kClientChannelFd is the file descriptor number that a client process + // expects to find its IPC socket; see reserved_file_descriptors.h. + + return kClientChannelFd; } //------------------------------------------------------------------------------ @@ -669,8 +671,11 @@ bool Channel::ChannelImpl::Send(Message* message) { return true; } -int Channel::ChannelImpl::GetClientFileDescriptor() const { - return client_pipe_; +void Channel::ChannelImpl::GetClientFileDescriptorMapping(int *src_fd, + int *dest_fd) const { + DCHECK(mode_ == MODE_SERVER); + *src_fd = client_pipe_; + *dest_fd = kClientChannelFd; } // Called by libevent when we can read from th pipe without blocking. @@ -798,8 +803,8 @@ bool Channel::Send(Message* message) { return channel_impl_->Send(message); } -int Channel::GetClientFileDescriptor() const { - return channel_impl_->GetClientFileDescriptor(); +void Channel::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const { + return channel_impl_->GetClientFileDescriptorMapping(src_fd, dest_fd); } } // namespace IPC diff --git a/chrome/common/ipc_channel_posix.h b/chrome/common/ipc_channel_posix.h index ed3d727..414730a 100644 --- a/chrome/common/ipc_channel_posix.h +++ b/chrome/common/ipc_channel_posix.h @@ -29,7 +29,7 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher { void Close(); void set_listener(Listener* listener) { listener_ = listener; } bool Send(Message* message); - int GetClientFileDescriptor() const; + void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const; private: bool CreatePipe(const std::string& channel_id, Mode mode); diff --git a/chrome/common/ipc_channel_proxy.cc b/chrome/common/ipc_channel_proxy.cc index c77ee7e..6e8919a3 100644 --- a/chrome/common/ipc_channel_proxy.cc +++ b/chrome/common/ipc_channel_proxy.cc @@ -289,10 +289,11 @@ void ChannelProxy::RemoveFilter(MessageFilter* filter) { // See the TODO regarding lazy initialization of the channel in // ChannelProxy::Init(). // We assume that IPC::Channel::GetClientFileDescriptorMapping() is thread-safe. -int ChannelProxy::GetClientFileDescriptor() const { +void ChannelProxy::GetClientFileDescriptorMapping(int *src_fd, + int *dest_fd) const { Channel *channel = context_.get()->channel_; DCHECK(channel); // Channel must have been created first. - return channel->GetClientFileDescriptor(); + channel->GetClientFileDescriptorMapping(src_fd, dest_fd); } #endif diff --git a/chrome/common/ipc_channel_proxy.h b/chrome/common/ipc_channel_proxy.h index 8adcb5b..a395b1f 100644 --- a/chrome/common/ipc_channel_proxy.h +++ b/chrome/common/ipc_channel_proxy.h @@ -121,7 +121,7 @@ class ChannelProxy : public Message::Sender { // Calls through to the underlying channel's methods. // TODO(playmobil): For now this is only implemented in the case of // create_pipe_now = true, we need to figure this out for the latter case. - int GetClientFileDescriptor() const; + void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const; #endif // defined(OS_POSIX) protected: diff --git a/chrome/common/ipc_tests.cc b/chrome/common/ipc_tests.cc index c2e0baa..d347fb5 100644 --- a/chrome/common/ipc_tests.cc +++ b/chrome/common/ipc_tests.cc @@ -21,16 +21,11 @@ #include "base/base_switches.h" #include "base/command_line.h" #include "base/debug_on_start.h" -#if defined(OS_POSIX) -#include "base/at_exit.h" -#include "base/global_descriptors_posix.h" -#endif #include "base/perftimer.h" #include "base/perf_test_suite.h" #include "base/test_suite.h" #include "base/thread.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/chrome_descriptors.h" #include "chrome/common/ipc_channel.h" #include "chrome/common/ipc_channel_proxy.h" #include "chrome/common/ipc_message_utils.h" @@ -91,9 +86,11 @@ base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type, CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugChildren); base::file_handle_mapping_vector fds_to_map; - const int ipcfd = channel->GetClientFileDescriptor(); - if (ipcfd > -1) { - fds_to_map.push_back(std::pair<int,int>(ipcfd, kPrimaryIPCChannel + 3)); + int src_fd; + int dest_fd; + channel->GetClientFileDescriptorMapping(&src_fd, &dest_fd); + if (src_fd > -1) { + fds_to_map.push_back(std::pair<int,int>(src_fd, dest_fd)); } base::ProcessHandle ret = NULL; @@ -261,9 +258,11 @@ TEST_F(IPCChannelTest, ChannelProxyTest) { bool debug_on_start = CommandLine::ForCurrentProcess()->HasSwitch( switches::kDebugChildren); base::file_handle_mapping_vector fds_to_map; - const int ipcfd = chan.GetClientFileDescriptor(); - if (ipcfd > -1) { - fds_to_map.push_back(std::pair<int,int>(ipcfd, kPrimaryIPCChannel + 3)); + int src_fd; + int dest_fd; + chan.GetClientFileDescriptorMapping(&src_fd, &dest_fd); + if (src_fd > -1) { + fds_to_map.push_back(std::pair<int,int>(src_fd, dest_fd)); } base::ProcessHandle process_handle = MultiProcessTest::SpawnChild( diff --git a/chrome/common/process_watcher_posix.cc b/chrome/common/process_watcher_posix.cc index f1ae4f4..497b80b 100644 --- a/chrome/common/process_watcher_posix.cc +++ b/chrome/common/process_watcher_posix.cc @@ -11,6 +11,7 @@ #include "base/eintr_wrapper.h" #include "base/platform_thread.h" +#include "base/zygote_manager.h" // Return true if the given child is dead. This will also reap the process. // Doesn't block. @@ -69,8 +70,20 @@ class BackgroundReaper : public PlatformThread::Delegate { // static void ProcessWatcher::EnsureProcessTerminated(base::ProcessHandle process) { // If the child is already dead, then there's nothing to do - if (IsChildDead(process)) + const int result = HANDLE_EINTR(waitpid(process, NULL, WNOHANG)); + if (result > 0) return; + if (result == -1) { +#if defined(OS_LINUX) + // If it wasn't our child, maybe it was the zygote manager's child + base::ZygoteManager* zm = base::ZygoteManager::Get(); + if (zm) { + zm->EnsureProcessTerminated(process); + return; + } +#endif // defined(OS_LINUX) + NOTREACHED(); + } BackgroundReaper* reaper = new BackgroundReaper(process); PlatformThread::CreateNonJoinable(0, reaper); diff --git a/chrome/plugin/plugin_main.cc b/chrome/plugin/plugin_main.cc index fb8880f..1bbb624 100644 --- a/chrome/plugin/plugin_main.cc +++ b/chrome/plugin/plugin_main.cc @@ -22,9 +22,6 @@ #if defined(OS_WIN) #include "chrome/test/injection_test_dll.h" #include "sandbox/src/sandbox.h" -#elif defined(OS_LINUX) -#include "chrome/common/chrome_descriptors.h" -#include "base/global_descriptors_posix.h" #endif // main() routine for running as the plugin process. diff --git a/chrome/renderer/renderer_main_unittest.cc b/chrome/renderer/renderer_main_unittest.cc index 605101e..18e67fa 100644 --- a/chrome/renderer/renderer_main_unittest.cc +++ b/chrome/renderer/renderer_main_unittest.cc @@ -53,9 +53,11 @@ void RendererMainTest::TearDown() { ProcessHandle RendererMainTest::SpawnChild(const std::wstring &procname, IPC::Channel *channel) { base::file_handle_mapping_vector fds_to_map; - const int ipcfd = channel->GetClientFileDescriptor(); - if (ipcfd > -1) { - fds_to_map.push_back(std::pair<int,int>(ipcfd, 3)); + int src_fd; + int dest_fd; + channel->GetClientFileDescriptorMapping(&src_fd, &dest_fd); + if (src_fd > -1) { + fds_to_map.push_back(std::pair<int,int>(src_fd, dest_fd)); } return MultiProcessTest::SpawnChild(procname, fds_to_map, false); diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc index 4410e2e..e54f6a6 100644 --- a/chrome/test/automation/automation_proxy.cc +++ b/chrome/test/automation/automation_proxy.cc @@ -13,7 +13,6 @@ #include "base/process_util.h" #include "base/ref_counted.h" #include "base/waitable_event.h" -#include "chrome/common/chrome_descriptors.h" #include "chrome/test/automation/automation_constants.h" #include "chrome/test/automation/automation_messages.h" #include "chrome/test/automation/browser_proxy.h" @@ -441,9 +440,10 @@ scoped_refptr<BrowserProxy> AutomationProxy::GetLastActiveBrowserWindow() { #if defined(OS_POSIX) base::file_handle_mapping_vector AutomationProxy::fds_to_map() const { base::file_handle_mapping_vector map; - const int ipcfd = channel_->GetClientFileDescriptor(); - if (ipcfd > -1) - map.push_back(std::make_pair(ipcfd, kPrimaryIPCChannel + 3)); + int src_fd = -1, dest_fd = -1; + channel_->GetClientFileDescriptorMapping(&src_fd, &dest_fd); + if (src_fd > -1) + map.push_back(std::make_pair(src_fd, dest_fd)); return map; } #endif // defined(OS_POSIX) diff --git a/chrome/test/chrome_process_util.cc b/chrome/test/chrome_process_util.cc index 4a5f5bb..296b291 100644 --- a/chrome/test/chrome_process_util.cc +++ b/chrome/test/chrome_process_util.cc @@ -5,7 +5,6 @@ #include "chrome/test/chrome_process_util.h" #include <vector> -#include <set> #include "base/process_util.h" #include "base/time.h" @@ -15,6 +14,26 @@ using base::Time; using base::TimeDelta; +namespace { + +class ChromeProcessFilter : public base::ProcessFilter { + public: + explicit ChromeProcessFilter(base::ProcessId browser_pid) + : browser_pid_(browser_pid) {} + + virtual bool Includes(base::ProcessId pid, base::ProcessId parent_pid) const { + // Match browser process itself and its children. + return browser_pid_ == pid || browser_pid_ == parent_pid; + } + + private: + base::ProcessId browser_pid_; + + DISALLOW_COPY_AND_ASSIGN(ChromeProcessFilter); +}; + +} // namespace + void TerminateAllChromeProcesses(const FilePath& data_dir) { // Total time the function will wait for chrome processes // to terminate after it told them to do so. @@ -51,24 +70,6 @@ void TerminateAllChromeProcesses(const FilePath& data_dir) { base::CloseProcessHandle(*it); } -class ChildProcessFilter : public base::ProcessFilter { - public: - explicit ChildProcessFilter(base::ProcessId parent_pid) - : parent_pids_(&parent_pid, (&parent_pid) + 1) {} - - explicit ChildProcessFilter(std::vector<base::ProcessId> parent_pids) - : parent_pids_(parent_pids.begin(), parent_pids.end()) {} - - virtual bool Includes(base::ProcessId pid, base::ProcessId parent_pid) const { - return parent_pids_.find(parent_pid) != parent_pids_.end(); - } - - private: - const std::set<base::ProcessId> parent_pids_; - - DISALLOW_COPY_AND_ASSIGN(ChildProcessFilter); -}; - ChromeProcessList GetRunningChromeProcesses(const FilePath& data_dir) { ChromeProcessList result; @@ -76,32 +77,37 @@ ChromeProcessList GetRunningChromeProcesses(const FilePath& data_dir) { if (browser_pid < 0) return result; - ChildProcessFilter filter(browser_pid); + // Normally, the browser is the parent process for all the renderers + base::ProcessId parent_pid = browser_pid; + +#if defined(OS_LINUX) + // But if the browser's parent is the same executable as the browser, + // then it's the zygote manager, and it's the parent for all the renderers. + base::ProcessId manager_pid = base::GetParentProcessId(browser_pid); + FilePath selfPath = base::GetProcessExecutablePath(browser_pid); + FilePath managerPath = base::GetProcessExecutablePath(manager_pid); + if (!selfPath.empty() && !managerPath.empty() && selfPath == managerPath) { + LOG(INFO) << "Zygote manager in use."; + parent_pid = manager_pid; + } +#endif + + ChromeProcessFilter filter(parent_pid); base::NamedProcessIterator it(chrome::kBrowserProcessExecutableName, &filter); const ProcessEntry* process_entry; while ((process_entry = it.NextProcessEntry())) { #if defined(OS_WIN) result.push_back(process_entry->th32ProcessID); +#elif defined(OS_LINUX) + // Don't count the zygote manager, that screws up unit tests, + // and it will exit cleanly on its own when first client exits. + if (process_entry->pid != manager_pid) + result.push_back(process_entry->pid); #elif defined(OS_POSIX) result.push_back(process_entry->pid); #endif } -#if defined(OS_LINUX) - // On Linux we might be running with a zygote process for the renderers. - // Because of that we sweep the list of processes again and pick those which - // are children of one of the processes that we've already seen. - { - ChildProcessFilter filter(result); - base::NamedProcessIterator it(chrome::kBrowserProcessExecutableName, - &filter); - while ((process_entry = it.NextProcessEntry())) - result.push_back(process_entry->pid); - } -#endif - - result.push_back(browser_pid); - return result; } |