Index: chrome/app/chrome_exe_main_win.cc |
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc |
index 2102ae1676d1a40c73f609b3226d11a70e7c7970..089ca1280dd418d1a16b0c454884e4823a4a378d 100644 |
--- a/chrome/app/chrome_exe_main_win.cc |
+++ b/chrome/app/chrome_exe_main_win.cc |
@@ -17,6 +17,8 @@ |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
#include "base/macros.h" |
+#include "base/strings/string16.h" |
+#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/time/time.h" |
#include "base/win/windows_version.h" |
@@ -26,10 +28,12 @@ |
#include "chrome/browser/policy/policy_path_parser.h" |
#include "chrome/common/chrome_paths_internal.h" |
#include "chrome/common/chrome_switches.h" |
+#include "chrome/installer/util/browser_distribution.h" |
#include "chrome_elf/chrome_elf_main.h" |
#include "components/crash/content/app/crash_reporter_client.h" |
#include "components/crash/content/app/crashpad.h" |
#include "components/startup_metric_utils/browser/startup_metric_utils.h" |
+#include "components/startup_metric_utils/common/pre_read_field_trial_utils_win.h" |
#include "content/public/common/content_switches.h" |
#include "content/public/common/result_codes.h" |
#include "third_party/crashpad/crashpad/handler/handler_main.h" |
@@ -152,15 +156,39 @@ int RunAsCrashpadHandler(const base::CommandLine& command_line) { |
scoped_ptr<char* []> argv_as_utf8(new char*[argv.size() + 1]); |
std::vector<std::string> storage; |
storage.reserve(argv.size()); |
+ |
+ size_t arg_append_index = 0; |
for (size_t i = 0; i < argv.size(); ++i) { |
+ // Remove arguments starting with '/' as they are not supported by crashpad. |
+ if (!argv[i].empty() && argv[i].front() == L'/') |
+ continue; |
+ |
storage.push_back(base::UTF16ToUTF8(argv[i])); |
- argv_as_utf8[i] = &storage[i][0]; |
+ argv_as_utf8[arg_append_index] = &storage[arg_append_index][0]; |
+ ++arg_append_index; |
} |
- argv_as_utf8[argv.size()] = nullptr; |
- return crashpad::HandlerMain(static_cast<int>(argv.size()), |
+ argv_as_utf8[arg_append_index] = nullptr; |
+ |
+ return crashpad::HandlerMain(static_cast<int>(storage.size()), |
argv_as_utf8.get()); |
} |
+// Returns true if |command_line| contains a /prefetch:# argument where # is in |
+// [1, 8]. |
+bool HasValidWindowsPrefetchArgument(const base::CommandLine& command_line) { |
+ const base::char16 kPrefetchArgumentPrefix[] = L"/prefetch:"; |
+ |
+ for (const auto& arg : command_line.argv()) { |
+ if (arg.size() == arraysize(kPrefetchArgumentPrefix) && |
+ base::StartsWith(arg, kPrefetchArgumentPrefix, |
+ base::CompareCase::SENSITIVE)) { |
+ return arg[arraysize(kPrefetchArgumentPrefix) - 1] >= L'1' && |
+ arg[arraysize(kPrefetchArgumentPrefix) - 1] <= L'8'; |
+ } |
+ } |
+ return false; |
+} |
+ |
} // namespace |
// This helper is looked up in the browser to retrieve the crash reports. See |
@@ -183,10 +211,22 @@ int main() { |
#endif |
// Initialize the CommandLine singleton from the environment. |
base::CommandLine::Init(0, nullptr); |
+ const base::CommandLine* command_line = |
+ base::CommandLine::ForCurrentProcess(); |
+ |
+ const std::string process_type = |
+ command_line->GetSwitchValueASCII(switches::kProcessType); |
+ |
+ startup_metric_utils::InitializePreReadOptions( |
+ BrowserDistribution::GetDistribution()->GetRegistryPath()); |
- std::string process_type = |
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
- switches::kProcessType); |
+ // Confirm that an explicit prefetch profile is used for all process types |
+ // except for the browser process. Any new process type will have to assign |
+ // itself a prefetch id. See kPrefetchArgument* constants in |
+ // content_switches.cc for details. |
+ DCHECK(!startup_metric_utils::GetPreReadOptions().use_prefetch_argument || |
+ process_type.empty() || |
+ HasValidWindowsPrefetchArgument(*command_line)); |
if (process_type == switches::kCrashpadHandler) |
return RunAsCrashpadHandler(*base::CommandLine::ForCurrentProcess()); |
@@ -210,7 +250,7 @@ int main() { |
if (base::win::GetVersion() >= base::win::VERSION_WIN7) |
EnableHighDPISupport(); |
- if (AttemptFastNotify(*base::CommandLine::ForCurrentProcess())) |
+ if (AttemptFastNotify(*command_line)) |
return 0; |
// Load and launch the chrome dll. *Everything* happens inside. |