Skip to content

Commit 49d3d11

Browse files
committed
inspector: split --cpu-prof-path to --cpu-prof-dir and --cpu-prof-name
To improve the integration of `--cpu-prof` with workers, this patch splits `--cpu-prof-path` into `--cpu-prof-dir` and `--cpu-prof-name`, so when a worker is launched from a thread that enables `--cpu-prof`, if the parent thread sets `--cpu-prof-dir`, then the profile of both thread would be generated to the specified directory. If they end up specifying the same `--cpu-prof-name` the behavior is undefined the last profile will overwritten the first one. PR-URL: #27306 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent a3d1922 commit 49d3d11

12 files changed

+231
-54
lines changed

doc/api/cli.md

+18-8
Original file line numberDiff line numberDiff line change
@@ -83,28 +83,38 @@ added: REPLACEME
8383
> Stability: 1 - Experimental
8484
8585
Starts the V8 CPU profiler on start up, and writes the CPU profile to disk
86-
before exit. If `--cpu-prof-path` is not specified, the profile will be
87-
written to `${cwd}/CPU.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.cpuprofile`.
86+
before exit.
87+
88+
If `--cpu-prof-dir` is not specified, the generated profile will be placed
89+
in the current working directory.
90+
91+
If `--cpu-prof-name` is not specified, the generated profile will be
92+
named `CPU.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.cpuprofile`.
8893

8994
```console
9095
$ node --cpu-prof index.js
9196
$ ls *.cpuprofile
9297
CPU.20190409.202950.15293.0.0.cpuprofile
9398
```
9499

95-
### `--cpu-prof-path`
100+
### `--cpu-prof-dir`
96101
<!-- YAML
97102
added: REPLACEME
98103
-->
99104

100105
> Stability: 1 - Experimental
101106
102-
Location where the CPU profile generated by `--cpu-prof`
103-
should be written to. When used alone, it implies `--cpu-prof`.
107+
Specify the directory where the CPU profiles generated by `--cpu-prof` will
108+
be placed.
104109

105-
```console
106-
$ node --cpu-prof-path /tmp/test.cpuprofile index.js
107-
```
110+
### `--cpu-prof-name`
111+
<!-- YAML
112+
added: REPLACEME
113+
-->
114+
115+
> Stability: 1 - Experimental
116+
117+
Specify the file name of the CPU profile generated by `--cpu-prof`.
108118

109119
### `--enable-fips`
110120
<!-- YAML

doc/node.1

+9-5
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,17 @@ Print source-able bash completion script for Node.js.
8181
.It Fl -cpu-prof
8282
Start the V8 CPU profiler on start up, and write the CPU profile to disk
8383
before exit. If
84-
.Fl -cpu-prof-path
85-
is not specified, the profile will be written to the current working directory.
84+
.Fl -cpu-prof-dir
85+
is not specified, the profile will be written to the current working directory
86+
with a generated file name.
8687
.
87-
.It Fl -cpu-prof-path
88-
Path the V8 CPU profile generated with
88+
.It Fl -cpu-prof-dir
89+
The directory where the CPU profiles generated by
8990
.Fl -cpu-prof
90-
will be written to. When used alone, it implies
91+
will be placed.
92+
.
93+
.It Fl -cpu-prof-name
94+
File name of the V8 CPU profile generated with
9195
.Fl -cpu-prof
9296
.
9397
.It Fl -enable-fips

src/env-inl.h

+17
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@
3838

3939
#include <utility>
4040

41+
#ifdef _WIN32
42+
/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
43+
#define CWD_BUFSIZE (MAX_PATH * 4)
44+
#else
45+
#include <climits> // PATH_MAX on Solaris.
46+
#define CWD_BUFSIZE (PATH_MAX)
47+
#endif
48+
4149
namespace node {
4250

4351
inline v8::Isolate* IsolateData::isolate() const {
@@ -678,6 +686,15 @@ inline void Environment::set_cpu_profile_path(const std::string& path) {
678686
inline const std::string& Environment::cpu_profile_path() const {
679687
return cpu_profile_path_;
680688
}
689+
690+
inline void Environment::set_cpu_prof_dir(const std::string& path) {
691+
cpu_prof_dir_ = path;
692+
}
693+
694+
inline const std::string& Environment::cpu_prof_dir() const {
695+
return cpu_prof_dir_;
696+
}
697+
681698
#endif // HAVE_INSPECTOR
682699

683700
inline std::shared_ptr<HostPort> Environment::inspector_host_port() {

src/env.cc

+18
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,24 @@ void Environment::stop_sub_worker_contexts() {
845845
}
846846
}
847847

848+
#if HAVE_INSPECTOR
849+
850+
void Environment::InitializeCPUProfDir(const std::string& dir) {
851+
if (!dir.empty()) {
852+
cpu_prof_dir_ = dir;
853+
return;
854+
}
855+
char cwd[CWD_BUFSIZE];
856+
size_t size = CWD_BUFSIZE;
857+
int err = uv_cwd(cwd, &size);
858+
// TODO(joyeecheung): fallback to exec path / argv[0]
859+
CHECK_EQ(err, 0);
860+
CHECK_GT(size, 0);
861+
cpu_prof_dir_ = cwd;
862+
}
863+
864+
#endif // HAVE_INSPECTOR
865+
848866
void MemoryTracker::TrackField(const char* edge_name,
849867
const CleanupHookCallback& value,
850868
const char* node_name) {

src/env.h

+6
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,11 @@ class Environment : public MemoryRetainer {
11371137

11381138
inline void set_cpu_profile_path(const std::string& path);
11391139
inline const std::string& cpu_profile_path() const;
1140+
1141+
inline void set_cpu_prof_dir(const std::string& path);
1142+
inline const std::string& cpu_prof_dir() const;
1143+
1144+
void InitializeCPUProfDir(const std::string& dir);
11401145
#endif // HAVE_INSPECTOR
11411146

11421147
private:
@@ -1173,6 +1178,7 @@ class Environment : public MemoryRetainer {
11731178
std::unique_ptr<profiler::V8CoverageConnection> coverage_connection_;
11741179
std::unique_ptr<profiler::V8CpuProfilerConnection> cpu_profiler_connection_;
11751180
std::string coverage_directory_;
1181+
std::string cpu_prof_dir_;
11761182
std::string cpu_profile_path_;
11771183
#endif // HAVE_INSPECTOR
11781184

src/inspector_profiler.cc

+5-11
Original file line numberDiff line numberDiff line change
@@ -318,19 +318,13 @@ void StartCoverageCollection(Environment* env) {
318318
env->coverage_connection()->Start();
319319
}
320320

321-
void StartCpuProfiling(Environment* env, const std::string& profile_path) {
322-
std::string path;
323-
if (profile_path.empty()) {
324-
char cwd[CWD_BUFSIZE];
325-
size_t size = CWD_BUFSIZE;
326-
int err = uv_cwd(cwd, &size);
327-
// TODO(joyeecheung): fallback to exec path / argv[0]
328-
CHECK_EQ(err, 0);
329-
CHECK_GT(size, 0);
321+
void StartCpuProfiling(Environment* env, const std::string& profile_name) {
322+
std::string path = env->cpu_prof_dir() + std::string(kPathSeparator);
323+
if (profile_name.empty()) {
330324
DiagnosticFilename filename(env, "CPU", "cpuprofile");
331-
path = cwd + std::string(kPathSeparator) + (*filename);
325+
path += *filename;
332326
} else {
333-
path = profile_path;
327+
path += profile_name;
334328
}
335329
env->set_cpu_profile_path(std::move(path));
336330
env->set_cpu_profiler_connection(

src/node.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ MaybeLocal<Value> RunBootstrapping(Environment* env) {
239239

240240
#if HAVE_INSPECTOR
241241
if (env->options()->cpu_prof) {
242-
profiler::StartCpuProfiling(env, env->options()->cpu_prof_path);
242+
env->InitializeCPUProfDir(env->options()->cpu_prof_dir);
243+
profiler::StartCpuProfiling(env, env->options()->cpu_prof_name);
243244
}
244245
#endif // HAVE_INSPECTOR
245246

src/node_options.cc

+18-6
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,15 @@ void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors) {
149149
}
150150

151151
#if HAVE_INSPECTOR
152+
if (!cpu_prof) {
153+
if (!cpu_prof_name.empty()) {
154+
errors->push_back("--cpu-prof-name must be used with --cpu-prof");
155+
}
156+
if (!cpu_prof_dir.empty()) {
157+
errors->push_back("--cpu-prof-dir must be used with --cpu-prof");
158+
}
159+
}
160+
152161
debug_options_.CheckOptions(errors);
153162
#endif // HAVE_INSPECTOR
154163
}
@@ -335,14 +344,17 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
335344
#if HAVE_INSPECTOR
336345
AddOption("--cpu-prof",
337346
"Start the V8 CPU profiler on start up, and write the CPU profile "
338-
"to disk before exit. If --cpu-prof-path is not specified, write "
347+
"to disk before exit. If --cpu-prof-dir is not specified, write "
339348
"the profile to the current working directory.",
340349
&EnvironmentOptions::cpu_prof);
341-
AddOption("--cpu-prof-path",
342-
"Path the V8 CPU profile generated with --cpu-prof will be "
343-
"written to.",
344-
&EnvironmentOptions::cpu_prof_path);
345-
Implies("--cpu-prof-path", "--cpu-prof");
350+
AddOption("--cpu-prof-name",
351+
"specified file name of the V8 CPU profile generated with "
352+
"--cpu-prof",
353+
&EnvironmentOptions::cpu_prof_name);
354+
AddOption("--cpu-prof-dir",
355+
"Directory where the V8 profiles generated by --cpu-prof will be "
356+
"placed. Does not affect --prof.",
357+
&EnvironmentOptions::cpu_prof_dir);
346358
#endif // HAVE_INSPECTOR
347359
AddOption("--redirect-warnings",
348360
"write warnings to file instead of stderr",

src/node_options.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ class EnvironmentOptions : public Options {
110110
bool preserve_symlinks_main = false;
111111
bool prof_process = false;
112112
#if HAVE_INSPECTOR
113-
std::string cpu_prof_path;
113+
std::string cpu_prof_dir;
114+
std::string cpu_prof_name;
114115
bool cpu_prof = false;
115116
#endif // HAVE_INSPECTOR
116117
std::string redirect_warnings;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
const { Worker } = require('worker_threads');
4+
const path = require('path');
5+
new Worker(path.join(__dirname, 'fibonacci.js'), {
6+
execArgv: ['--cpu-prof']
7+
});

test/fixtures/workload/fibonacci-worker.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,4 @@
22

33
const { Worker } = require('worker_threads');
44
const path = require('path');
5-
new Worker(path.join(__dirname, 'fibonacci.js'), {
6-
execArgv: ['--cpu-prof']
7-
});
5+
new Worker(path.join(__dirname, 'fibonacci.js'));

0 commit comments

Comments
 (0)