| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright 2017 The Chromium Authors. All rights reserved. |  | 
|    2 // Use of this source code is governed by a BSD-style license that can be |  | 
|    3 // found in the LICENSE file. |  | 
|    4  |  | 
|    5 #include "services/service_manager/embedder/main.h" |  | 
|    6 #include "base/allocator/features.h" |  | 
|    7 #include "base/command_line.h" |  | 
|    8 #include "base/debug/activity_tracker.h" |  | 
|    9 #include "base/logging.h" |  | 
|   10 #include "base/memory/ptr_util.h" |  | 
|   11 #include "base/process/memory.h" |  | 
|   12 #include "mojo/edk/embedder/embedder.h" |  | 
|   13 #include "services/service_manager/embedder/main_delegate.h" |  | 
|   14 #include "services/service_manager/embedder/set_process_title.h" |  | 
|   15 #include "services/service_manager/embedder/shared_file_util.h" |  | 
|   16 #include "services/service_manager/embedder/switches.h" |  | 
|   17  |  | 
|   18 #if defined(OS_WIN) |  | 
|   19 #include "base/win/process_startup_helper.h" |  | 
|   20 #include "ui/base/win/atl_module.h" |  | 
|   21 #endif |  | 
|   22  |  | 
|   23 #if defined(OS_POSIX) && !defined(OS_ANDROID) |  | 
|   24 #include <locale.h> |  | 
|   25 #include <signal.h> |  | 
|   26  |  | 
|   27 #include "base/file_descriptor_store.h" |  | 
|   28 #include "base/posix/global_descriptors.h" |  | 
|   29 #endif |  | 
|   30  |  | 
|   31 #if defined(OS_MACOSX) |  | 
|   32 #include "base/mac/scoped_nsautorelease_pool.h" |  | 
|   33 #include "services/service_manager/embedder/mac_init.h" |  | 
|   34  |  | 
|   35 #if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) |  | 
|   36 #include "base/allocator/allocator_shim.h" |  | 
|   37 #endif |  | 
|   38 #endif  // defined(OS_MACOSX) |  | 
|   39  |  | 
|   40 namespace service_manager { |  | 
|   41  |  | 
|   42 namespace { |  | 
|   43  |  | 
|   44 // Maximum message size allowed to be read from a Mojo message pipe in any |  | 
|   45 // service manager embedder process. |  | 
|   46 constexpr size_t kMaximumMojoMessageSize = 128 * 1024 * 1024; |  | 
|   47  |  | 
|   48 #if defined(OS_POSIX) && !defined(OS_ANDROID) |  | 
|   49  |  | 
|   50 // Setup signal-handling state: resanitize most signals, ignore SIGPIPE. |  | 
|   51 void SetupSignalHandlers() { |  | 
|   52   // Sanitise our signal handling state. Signals that were ignored by our |  | 
|   53   // parent will also be ignored by us. We also inherit our parent's sigmask. |  | 
|   54   sigset_t empty_signal_set; |  | 
|   55   CHECK_EQ(0, sigemptyset(&empty_signal_set)); |  | 
|   56   CHECK_EQ(0, sigprocmask(SIG_SETMASK, &empty_signal_set, NULL)); |  | 
|   57  |  | 
|   58   struct sigaction sigact; |  | 
|   59   memset(&sigact, 0, sizeof(sigact)); |  | 
|   60   sigact.sa_handler = SIG_DFL; |  | 
|   61   static const int signals_to_reset[] = { |  | 
|   62       SIGHUP,  SIGINT,  SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV, |  | 
|   63       SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};  // SIGPIPE is set below. |  | 
|   64   for (unsigned i = 0; i < arraysize(signals_to_reset); i++) { |  | 
|   65     CHECK_EQ(0, sigaction(signals_to_reset[i], &sigact, NULL)); |  | 
|   66   } |  | 
|   67  |  | 
|   68   // Always ignore SIGPIPE.  We check the return value of write(). |  | 
|   69   CHECK_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN)); |  | 
|   70 } |  | 
|   71  |  | 
|   72 void PopulateFDsFromCommandLine() { |  | 
|   73   const std::string& shared_file_param = |  | 
|   74       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |  | 
|   75           switches::kSharedFiles); |  | 
|   76   if (shared_file_param.empty()) |  | 
|   77     return; |  | 
|   78  |  | 
|   79   base::Optional<std::map<int, std::string>> shared_file_descriptors = |  | 
|   80       service_manager::ParseSharedFileSwitchValue(shared_file_param); |  | 
|   81   if (!shared_file_descriptors) |  | 
|   82     return; |  | 
|   83  |  | 
|   84   for (const auto& descriptor : *shared_file_descriptors) { |  | 
|   85     base::MemoryMappedFile::Region region; |  | 
|   86     const std::string& key = descriptor.second; |  | 
|   87     base::ScopedFD fd = base::GlobalDescriptors::GetInstance()->TakeFD( |  | 
|   88         descriptor.first, ®ion); |  | 
|   89     base::FileDescriptorStore::GetInstance().Set(key, std::move(fd), region); |  | 
|   90   } |  | 
|   91 } |  | 
|   92  |  | 
|   93 #endif  // defined(OS_POSIX) && !defined(OS_ANDROID) |  | 
|   94  |  | 
|   95 }  // namespace |  | 
|   96  |  | 
|   97 MainParams::MainParams(MainDelegate* delegate) : delegate(delegate) {} |  | 
|   98  |  | 
|   99 MainParams::~MainParams() {} |  | 
|  100  |  | 
|  101 int Main(const MainParams& params) { |  | 
|  102   MainDelegate* delegate = params.delegate; |  | 
|  103   DCHECK(delegate); |  | 
|  104  |  | 
|  105 #if defined(OS_MACOSX) && BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) |  | 
|  106   base::allocator::InitializeAllocatorShim(); |  | 
|  107 #endif |  | 
|  108   base::EnableTerminationOnOutOfMemory(); |  | 
|  109  |  | 
|  110 #if defined(OS_WIN) |  | 
|  111   base::win::RegisterInvalidParamHandler(); |  | 
|  112   ui::win::CreateATLModuleIfNeeded(); |  | 
|  113 #endif  // defined(OS_WIN) |  | 
|  114  |  | 
|  115 // On Android setlocale() is not supported, and we don't override the signal |  | 
|  116 // handlers so we can get a stack trace when crashing. |  | 
|  117 #if defined(OS_POSIX) && !defined(OS_ANDROID) |  | 
|  118   // Set C library locale to make sure CommandLine can parse argument values in |  | 
|  119   // the correct encoding. |  | 
|  120   setlocale(LC_ALL, ""); |  | 
|  121  |  | 
|  122   SetupSignalHandlers(); |  | 
|  123 #endif |  | 
|  124  |  | 
|  125 #if !defined(OS_ANDROID) |  | 
|  126   // On Android, the command line is initialized when library is loaded. |  | 
|  127   int argc = 0; |  | 
|  128   const char** argv = nullptr; |  | 
|  129  |  | 
|  130 #if defined(OS_POSIX) |  | 
|  131   // argc/argv are ignored on Windows; see command_line.h for details. |  | 
|  132   argc = params.argc; |  | 
|  133   argv = params.argv; |  | 
|  134 #endif |  | 
|  135  |  | 
|  136   base::CommandLine::Init(argc, argv); |  | 
|  137  |  | 
|  138 #if defined(OS_POSIX) |  | 
|  139   PopulateFDsFromCommandLine(); |  | 
|  140 #endif |  | 
|  141  |  | 
|  142   base::EnableTerminationOnHeapCorruption(); |  | 
|  143  |  | 
|  144 #if defined(OS_WIN) |  | 
|  145   base::win::SetupCRT(*base::CommandLine::ForCurrentProcess()); |  | 
|  146 #endif |  | 
|  147  |  | 
|  148   SetProcessTitleFromCommandLine(argv); |  | 
|  149 #endif  // !defined(OS_ANDROID) |  | 
|  150  |  | 
|  151   MainDelegate::InitializeParams init_params; |  | 
|  152  |  | 
|  153 #if defined(OS_MACOSX) |  | 
|  154   // We need this pool for all the objects created before we get to the event |  | 
|  155   // loop, but we don't want to leave them hanging around until the app quits. |  | 
|  156   // Each "main" needs to flush this pool right before it goes into its main |  | 
|  157   // event loop to get rid of the cruft. |  | 
|  158   std::unique_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool = |  | 
|  159       base::MakeUnique<base::mac::ScopedNSAutoreleasePool>(); |  | 
|  160   init_params.autorelease_pool = autorelease_pool.get(); |  | 
|  161   InitializeMac(); |  | 
|  162 #endif |  | 
|  163  |  | 
|  164   mojo::edk::SetMaxMessageSize(kMaximumMojoMessageSize); |  | 
|  165   mojo::edk::Init(); |  | 
|  166  |  | 
|  167   base::debug::GlobalActivityTracker* tracker = |  | 
|  168       base::debug::GlobalActivityTracker::Get(); |  | 
|  169   int exit_code = delegate->Initialize(init_params); |  | 
|  170   if (exit_code >= 0) { |  | 
|  171     if (tracker) { |  | 
|  172       tracker->SetProcessPhase( |  | 
|  173           base::debug::GlobalActivityTracker::PROCESS_LAUNCH_FAILED); |  | 
|  174       tracker->process_data().SetInt("exit-code", exit_code); |  | 
|  175     } |  | 
|  176     return exit_code; |  | 
|  177   } |  | 
|  178  |  | 
|  179   exit_code = delegate->Run(); |  | 
|  180   if (tracker) { |  | 
|  181     if (exit_code == 0) { |  | 
|  182       tracker->SetProcessPhaseIfEnabled( |  | 
|  183           base::debug::GlobalActivityTracker::PROCESS_EXITED_CLEANLY); |  | 
|  184     } else { |  | 
|  185       tracker->SetProcessPhaseIfEnabled( |  | 
|  186           base::debug::GlobalActivityTracker::PROCESS_EXITED_WITH_CODE); |  | 
|  187       tracker->process_data().SetInt("exit-code", exit_code); |  | 
|  188     } |  | 
|  189   } |  | 
|  190  |  | 
|  191   delegate->ShutDown(); |  | 
|  192  |  | 
|  193   return exit_code; |  | 
|  194 } |  | 
|  195  |  | 
|  196 }  // namespace service_manager |  | 
| OLD | NEW |