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 "chrome/browser/profiling_host/profiling_process_host.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "base/path_service.h" | |
9 #include "base/process/launch.h" | |
10 #include "base/strings/string_number_conversions.h" | |
11 #include "base/strings/utf_string_conversions.h" | |
12 #include "chrome/common/chrome_switches.h" | |
13 #include "chrome/common/profiling/memlog_sender.h" | |
14 #include "content/public/common/content_switches.h" | |
15 | |
16 namespace profiling { | |
17 | |
18 namespace { | |
19 | |
20 ProfilingProcessHost* pph_singleton = nullptr; | |
awong
2017/06/29 18:39:31
prefix with a g_?
brettw
2017/06/29 19:31:12
This function is in an anon namespace so is file s
| |
21 | |
22 base::CommandLine MakeProfilingCommandLine(const std::string& pipe_id) { | |
23 // Program name. | |
24 base::FilePath child_path; | |
25 #if defined(OS_LINUX) | |
26 // Use /proc/self/exe rather than our known binary path so updates | |
27 // can't swap out the binary from underneath us. | |
28 // When running under Valgrind, forking /proc/self/exe ends up forking the | |
29 // Valgrind executable, which then crashes. However, it's almost safe to | |
30 // assume that the updates won't happen while testing with Valgrind tools. | |
31 if (!RunningOnValgrind()) | |
32 child_path = base::FilePath(base::kProcSelfExe); | |
33 #endif | |
34 if (child_path.empty()) | |
35 base::PathService::Get(base::FILE_EXE, &child_path); | |
36 base::CommandLine result(child_path); | |
37 | |
38 result.AppendSwitchASCII(switches::kProcessType, switches::kProfiling); | |
39 result.AppendSwitchASCII(switches::kMemlogPipe, pipe_id); | |
40 | |
41 #if defined(OS_WIN) | |
42 // Windows needs prefetch arguments. | |
43 result.AppendArg(switches::kPrefetchArgumentOther); | |
44 #endif | |
45 | |
46 return result; | |
47 } | |
48 | |
49 } // namespace | |
50 | |
51 ProfilingProcessHost::ProfilingProcessHost() { | |
52 pph_singleton = this; | |
53 } | |
54 | |
55 ProfilingProcessHost::~ProfilingProcessHost() { | |
56 pph_singleton = nullptr; | |
57 } | |
58 | |
59 // static | |
60 ProfilingProcessHost* ProfilingProcessHost::EnsureStarted() { | |
61 static ProfilingProcessHost host; | |
62 if (!host.process_.IsValid()) | |
63 host.Launch(); | |
64 return &host; | |
65 } | |
66 | |
67 // static | |
68 ProfilingProcessHost* ProfilingProcessHost::Get() { | |
awong
2017/06/29 18:39:31
Why bother with the Get() versus EnsureStarted()?
brettw
2017/06/29 19:31:11
Some code, like AddSwitchesToChildCmdLine, need to
| |
69 return pph_singleton; | |
70 } | |
71 | |
72 // static | |
73 void ProfilingProcessHost::AddSwitchesToChildCmdLine( | |
74 base::CommandLine* child_cmd_line) { | |
75 if (!pph_singleton) | |
awong
2017/06/29 18:39:31
Use Get() instead?
brettw
2017/06/29 19:31:12
Done.
| |
76 return; | |
77 child_cmd_line->AppendSwitchASCII(switches::kMemlogPipe, | |
78 pph_singleton->pipe_id_); | |
awong
2017/06/29 18:39:32
Use Get() instead?
| |
79 } | |
80 | |
81 void ProfilingProcessHost::Launch() { | |
82 base::Process process = base::Process::Current(); | |
83 pipe_id_ = base::IntToString(static_cast<int>(process.Pid())); | |
84 | |
85 base::CommandLine profiling_cmd = MakeProfilingCommandLine(pipe_id_); | |
awong
2017/06/29 18:39:32
Been meaning to ask... are there any security cons
brettw
2017/06/29 19:31:12
I don't know, I will make a note to ask.
| |
86 | |
87 base::LaunchOptions options; | |
88 process_ = base::LaunchProcess(profiling_cmd, options); | |
89 StartMemlogSender(pipe_id_); | |
90 } | |
91 | |
92 } // namespace profiling | |
OLD | NEW |