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
3 // found in the LICENSE file.
4
5 #include <stdint.h>
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/command_line.h"
10 #include "base/time/time.h"
11 #include "build/build_config.h"
12 #include "chrome/app/chrome_main_delegate.h"
13 #include "chrome/common/buildflags.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/profiler/main_thread_stack_sampling_profiler.h"
16 #include "content/public/app/content_main.h"
17 #include "content/public/common/content_switches.h"
18 #include "headless/public/headless_shell.h"
19 #include "ui/gfx/switches.h"
20
21 #if defined(OS_MAC)
22 #include "chrome/app/chrome_main_mac.h"
23 #endif
24
25 #if defined(OS_WIN)
26 #include <timeapi.h>
27
28 #include "base/base_switches.h"
29 #include "base/debug/dump_without_crashing.h"
30 #include "base/files/file_util.h"
31 #include "base/metrics/histogram_functions.h"
32 #include "base/win/win_util.h"
33 #include "chrome/chrome_elf/chrome_elf_main.h"
34 #include "chrome/common/chrome_constants.h"
35 #include "chrome/install_static/initialize_from_primary_module.h"
36 #include "chrome/install_static/install_details.h"
37
38 #define DLLEXPORT __declspec(dllexport)
39
40 // We use extern C for the prototype DLLEXPORT to avoid C++ name mangling.
41 extern "C" {
42 DLLEXPORT int __cdecl ChromeMain(HINSTANCE instance,
43 sandbox::SandboxInterfaceInfo* sandbox_info,
44 int64_t exe_entry_point_ticks,
45 base::PrefetchResultCode prefetch_result_code);
46 }
47 #elif defined(OS_POSIX)
48 extern "C" {
49 __attribute__((visibility("default")))
50 int ChromeMain(int argc, const char** argv);
51 }
52 #endif
53
54 #if defined(OS_WIN)
ChromeMain(HINSTANCE instance,sandbox::SandboxInterfaceInfo * sandbox_info,int64_t exe_entry_point_ticks,base::PrefetchResultCode prefetch_result_code)55 DLLEXPORT int __cdecl ChromeMain(
56 HINSTANCE instance,
57 sandbox::SandboxInterfaceInfo* sandbox_info,
58 int64_t exe_entry_point_ticks,
59 base::PrefetchResultCode prefetch_result_code) {
60 #elif defined(OS_POSIX)
61 int ChromeMain(int argc, const char** argv) {
62 int64_t exe_entry_point_ticks = 0;
63 #endif
64
65 #if defined(OS_WIN)
66 base::UmaHistogramEnumeration("Windows.ChromeDllPrefetchResult",
67 prefetch_result_code);
68 install_static::InitializeFromPrimaryModule();
69 #endif
70
71 ChromeMainDelegate chrome_main_delegate(
72 base::TimeTicks::FromInternalValue(exe_entry_point_ticks));
73 content::ContentMainParams params(&chrome_main_delegate);
74
75 #if defined(OS_WIN)
76 // The process should crash when going through abnormal termination, but we
77 // must be sure to reset this setting when ChromeMain returns normally.
78 auto crash_on_detach_resetter = base::ScopedClosureRunner(
79 base::BindOnce(&base::win::SetShouldCrashOnProcessDetach,
80 base::win::ShouldCrashOnProcessDetach()));
81 base::win::SetShouldCrashOnProcessDetach(true);
82 base::win::SetAbortBehaviorForCrashReporting();
83 params.instance = instance;
84 params.sandbox_info = sandbox_info;
85
86 // Pass chrome_elf's copy of DumpProcessWithoutCrash resolved via load-time
87 // dynamic linking.
88 base::debug::SetDumpWithoutCrashingFunction(&DumpProcessWithoutCrash);
89
90 // Verify that chrome_elf and this module (chrome.dll and chrome_child.dll)
91 // have the same version.
92 if (install_static::InstallDetails::Get().VersionMismatch())
93 base::debug::DumpWithoutCrashing();
94 #else
95 params.argc = argc;
96 params.argv = argv;
97 base::CommandLine::Init(params.argc, params.argv);
98 #endif // defined(OS_WIN)
99 base::CommandLine::Init(0, nullptr);
100 const base::CommandLine* command_line(base::CommandLine::ForCurrentProcess());
101 ALLOW_UNUSED_LOCAL(command_line);
102
103 #if defined(OS_WIN)
104 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
105 ::switches::kRaiseTimerFrequency)) {
106 // Raise the timer interrupt frequency and leave it raised.
107 timeBeginPeriod(1);
108 }
109 #endif
110
111 #if defined(OS_MAC)
112 SetUpBundleOverrides();
113 #endif
114
115 // Start the sampling profiler as early as possible - namely, once the command
116 // line data is available. Allocated as an object on the stack to ensure that
117 // the destructor runs on shutdown, which is important to avoid the profiler
118 // thread's destruction racing with main thread destruction.
119 MainThreadStackSamplingProfiler scoped_sampling_profiler;
120
121 // Chrome-specific process modes.
122 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD) || \
123 defined(OS_WIN)
124 if (command_line->HasSwitch(switches::kHeadless)) {
125 return headless::HeadlessShellMain(params);
126 }
127 #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD) ||
128 // defined(OS_WIN)
129
130 int rv = content::ContentMain(params);
131
132 return rv;
133 }
134