blob: b6f6e8b18550aeea097c579ba09179c34b4af18b [file] [log] [blame]
// Copyright 2018 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 "base/at_exit.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/debug/debugger.h"
#include "base/debug/stack_trace.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/process/launch.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "build/build_config.h"
#include "services/service_manager/public/cpp/service_executable/service_executable_environment.h"
#include "services/service_manager/public/cpp/service_executable/service_main.h"
#include "services/service_manager/public/mojom/service.mojom.h"
#if BUILDFLAG(IS_MAC)
#include "base/mac/bundle_locations.h"
#endif
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif
namespace {
void WaitForDebuggerIfNecessary() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(::switches::kWaitForDebugger)) {
std::vector<std::string> apps_to_debug = base::SplitString(
command_line->GetSwitchValueASCII(::switches::kWaitForDebugger), ",",
base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
std::string app = "launcher";
base::FilePath exe_path =
command_line->GetProgram().BaseName().RemoveExtension();
for (const auto& app_name : apps_to_debug) {
if (base::FilePath().AppendASCII(app_name) == exe_path) {
app = app_name;
break;
}
}
if (apps_to_debug.empty() || base::Contains(apps_to_debug, app)) {
#if BUILDFLAG(IS_WIN)
std::wstring appw = base::UTF8ToWide(app);
std::wstring message = base::UTF8ToWide(
base::StringPrintf("%s - %ld", app.c_str(), GetCurrentProcessId()));
MessageBox(NULL, message.c_str(), appw.c_str(), MB_OK | MB_SETFOREGROUND);
#else
LOG(ERROR) << app << " waiting for GDB. pid: " << getpid();
base::debug::WaitForDebugger(60, true);
#endif
}
}
}
} // namespace
int main(int argc, char** argv) {
base::AtExitManager at_exit;
base::CommandLine::Init(argc, argv);
#if !defined(OFFICIAL_BUILD) && BUILDFLAG(IS_WIN)
base::RouteStdioToConsole(false);
#endif
logging::LoggingSettings settings;
settings.logging_dest =
logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
logging::InitLogging(settings);
// To view log output with IDs and timestamps use "adb logcat -v threadtime".
logging::SetLogItems(true, // Process ID
true, // Thread ID
true, // Timestamp
true); // Tick count
base::i18n::InitializeICU();
#if !defined(OFFICIAL_BUILD)
// Initialize stack dumping before initializing sandbox to make sure symbol
// names in all loaded libraries will be cached.
base::debug::EnableInProcessStackDumping();
#endif
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
base::FeatureList::InitializeInstance(
command_line->GetSwitchValueASCII(switches::kEnableFeatures),
command_line->GetSwitchValueASCII(switches::kDisableFeatures));
WaitForDebuggerIfNecessary();
service_manager::ServiceExecutableEnvironment environment;
ServiceMain(environment.TakeServiceRequestFromCommandLine());
base::ThreadPoolInstance::Get()->Shutdown();
return 0;
}