From ead4d7a75aed5357bdab32dc7054774543d39298 Mon Sep 17 00:00:00 2001 From: haramjeong <04harams77@gmail.com> Date: Tue, 15 Jul 2025 00:00:02 +0900 Subject: [PATCH 01/11] cli: support `${pid}` placeholder in --cpu-prof-name --- doc/api/cli.md | 10 ++++++---- src/inspector_profiler.cc | 13 ++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 74863327c73746..1a2288fb2bfc5e 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -540,14 +540,16 @@ $ ls *.cpuprofile CPU.20190409.202950.15293.0.0.cpuprofile ``` -If `--cpu-prof-name` is specified, the provided value will be used as-is; patterns such as -`${hhmmss}` or `${pid}` are not supported. +If `--cpu-prof-name` is specified, the provided value is used as a template +for the file name. Some placeholders are supported and will be substituted +at runtime: + +- `${pid}` — the current process ID ```console $ node --cpu-prof --cpu-prof-name 'CPU.${pid}.cpuprofile' index.js $ ls *.cpuprofile -'CPU.${pid}.cpuprofile' -``` +CPU.15293.cpuprofile ### `--cpu-prof-dir` diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index f09dd04ccd7f6e..d275b41d958a2f 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -9,6 +9,8 @@ #include "node_internals.h" #include "util-inl.h" #include "v8-inspector.h" +#include +#include #include #include @@ -465,6 +467,14 @@ static void EndStartedProfilers(Environment* env) { } } +std::string ReplacePlaceholders(const std::string& pattern) { + std::string result = pattern; + std::string pid_str = std::to_string(getpid()); + result = std::regex_replace(result, std::regex("\\$\\{pid\\}"), pid_str); + // TODO: Add more placeholders as needed. + return result; +} + void StartProfilers(Environment* env) { AtExit(env, [](void* env) { EndStartedProfilers(static_cast(env)); @@ -486,7 +496,8 @@ void StartProfilers(Environment* env) { DiagnosticFilename filename(env, "CPU", "cpuprofile"); env->set_cpu_prof_name(*filename); } else { - env->set_cpu_prof_name(env->options()->cpu_prof_name); + std::string resolved_name = ReplacePlaceholders(env->options()->cpu_prof_name); + env->set_cpu_prof_name(resolved_name); } CHECK_NULL(env->cpu_profiler_connection()); env->set_cpu_profiler_connection( From 9916afdc8c2386fc7d622894a3c77882ca0d7925 Mon Sep 17 00:00:00 2001 From: haramjeong <04harams77@gmail.com> Date: Tue, 15 Jul 2025 01:35:06 +0900 Subject: [PATCH 02/11] replaced and includes with "uv.h" for consistency --- doc/api/cli.md | 4 ++-- src/inspector_profiler.cc | 25 ++++++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 1a2288fb2bfc5e..10ed548f9501ab 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -544,7 +544,7 @@ If `--cpu-prof-name` is specified, the provided value is used as a template for the file name. Some placeholders are supported and will be substituted at runtime: -- `${pid}` — the current process ID +* `${pid}` — the current process ID ```console $ node --cpu-prof --cpu-prof-name 'CPU.${pid}.cpuprofile' index.js @@ -661,7 +661,7 @@ For example, the following script will not emit ```mjs import sys from 'node:sys'; -``` +```` ```cjs const sys = require('node:sys'); diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index d275b41d958a2f..d629975a36998f 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -1,4 +1,5 @@ #include "inspector_profiler.h" +#include "uv.h" #include "base_object-inl.h" #include "debug_utils-inl.h" #include "diagnosticfilename-inl.h" @@ -9,8 +10,6 @@ #include "node_internals.h" #include "util-inl.h" #include "v8-inspector.h" -#include -#include #include #include @@ -467,11 +466,22 @@ static void EndStartedProfilers(Environment* env) { } } -std::string ReplacePlaceholders(const std::string& pattern) { +static std::string ReplacePlaceholders(const std::string& pattern) { std::string result = pattern; - std::string pid_str = std::to_string(getpid()); - result = std::regex_replace(result, std::regex("\\$\\{pid\\}"), pid_str); - // TODO: Add more placeholders as needed. + + static const std::unordered_map> kPlaceholderMap = { + { "${pid}", []() { return std::to_string(uv_os_getpid()); } }, + // TODO(haramj): Add more placeholders as needed. + }; + + for (const auto& [placeholder, getter] : kPlaceholderMap) { + size_t pos = 0; + while ((pos = result.find(placeholder, pos)) != std::string::npos) { + result.replace(pos, placeholder.length(), getter()); + pos += getter().length(); + } + } + return result; } @@ -496,7 +506,8 @@ void StartProfilers(Environment* env) { DiagnosticFilename filename(env, "CPU", "cpuprofile"); env->set_cpu_prof_name(*filename); } else { - std::string resolved_name = ReplacePlaceholders(env->options()->cpu_prof_name); + std::string resolved_name = + ReplacePlaceholders(env->options()->cpu_prof_name); env->set_cpu_prof_name(resolved_name); } CHECK_NULL(env->cpu_profiler_connection()); From b366703b4ebc52be0e0fbda3162cb3ce96f372c4 Mon Sep 17 00:00:00 2001 From: haramjeong <04harams77@gmail.com> Date: Tue, 15 Jul 2025 01:39:32 +0900 Subject: [PATCH 03/11] doc: fix broken link reference for --diagnostic-dir option --- doc/api/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 10ed548f9501ab..e5f780721e0092 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -3980,7 +3980,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12 [`--allow-worker`]: #--allow-worker [`--build-snapshot`]: #--build-snapshot [`--cpu-prof-dir`]: #--cpu-prof-dir -[`--diagnostic-dir`]: #--diagnostic-dirdirectory +[`--diagnostic-dir`]: #--diagnostic-dir [`--disable-sigusr1`]: #--disable-sigusr1 [`--env-file-if-exists`]: #--env-file-if-existsconfig [`--env-file`]: #--env-fileconfig From 323e9535f4ef978208d1dd3647aceae88713c835 Mon Sep 17 00:00:00 2001 From: haramjeong <04harams77@gmail.com> Date: Tue, 15 Jul 2025 08:52:27 +0900 Subject: [PATCH 04/11] Revert "doc: fix broken link reference for --diagnostic-dir option" This reverts commit 3b529fcc570546ebb1ee8a804f5a434a12dc86b1. --- doc/api/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index e5f780721e0092..10ed548f9501ab 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -3980,7 +3980,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12 [`--allow-worker`]: #--allow-worker [`--build-snapshot`]: #--build-snapshot [`--cpu-prof-dir`]: #--cpu-prof-dir -[`--diagnostic-dir`]: #--diagnostic-dir +[`--diagnostic-dir`]: #--diagnostic-dirdirectory [`--disable-sigusr1`]: #--disable-sigusr1 [`--env-file-if-exists`]: #--env-file-if-existsconfig [`--env-file`]: #--env-fileconfig From 89d051b3579a0f3ac84cbf816d3467a9532a6765 Mon Sep 17 00:00:00 2001 From: haramjeong <04harams77@gmail.com> Date: Tue, 15 Jul 2025 08:56:46 +0900 Subject: [PATCH 05/11] src: make format-cpp-build --- src/inspector_profiler.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index d629975a36998f..f73491342de0b5 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -1,5 +1,4 @@ #include "inspector_profiler.h" -#include "uv.h" #include "base_object-inl.h" #include "debug_utils-inl.h" #include "diagnosticfilename-inl.h" @@ -9,6 +8,7 @@ #include "node_file.h" #include "node_internals.h" #include "util-inl.h" +#include "uv.h" #include "v8-inspector.h" #include @@ -469,10 +469,11 @@ static void EndStartedProfilers(Environment* env) { static std::string ReplacePlaceholders(const std::string& pattern) { std::string result = pattern; - static const std::unordered_map> kPlaceholderMap = { - { "${pid}", []() { return std::to_string(uv_os_getpid()); } }, - // TODO(haramj): Add more placeholders as needed. - }; + static const std::unordered_map> + kPlaceholderMap = { + {"${pid}", []() { return std::to_string(uv_os_getpid()); }}, + // TODO(haramj): Add more placeholders as needed. + }; for (const auto& [placeholder, getter] : kPlaceholderMap) { size_t pos = 0; From 384830f6c96d50c59d9de5293d4bdab02892c097 Mon Sep 17 00:00:00 2001 From: Haram Jeong <91401364+haramj@users.noreply.github.com> Date: Wed, 16 Jul 2025 18:51:02 +0900 Subject: [PATCH 06/11] Update doc/api/cli.md Co-authored-by: Chengzhong Wu --- doc/api/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 10ed548f9501ab..fad2d4c6908a88 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -661,7 +661,7 @@ For example, the following script will not emit ```mjs import sys from 'node:sys'; -```` +``` ```cjs const sys = require('node:sys'); From 7b0a2caf44e1ff74fc537bc928e090c403dd3c75 Mon Sep 17 00:00:00 2001 From: Haram Jeong <91401364+haramj@users.noreply.github.com> Date: Wed, 16 Jul 2025 18:51:12 +0900 Subject: [PATCH 07/11] Update doc/api/cli.md Co-authored-by: Chengzhong Wu --- doc/api/cli.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/api/cli.md b/doc/api/cli.md index fad2d4c6908a88..f85d4c2d14557b 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -550,6 +550,7 @@ at runtime: $ node --cpu-prof --cpu-prof-name 'CPU.${pid}.cpuprofile' index.js $ ls *.cpuprofile CPU.15293.cpuprofile +``` ### `--cpu-prof-dir` From 09a2458bde1c393535736d95fea6cf143f6d0533 Mon Sep 17 00:00:00 2001 From: haramjeong <04harams77@gmail.com> Date: Wed, 16 Jul 2025 21:16:37 +0900 Subject: [PATCH 08/11] test: add ${pid} placeholder test for --cpu-prof-name --- src/inspector_profiler.cc | 5 ++-- test/sequential/test-cpu-prof-name.js | 35 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index f73491342de0b5..dd57c779595c80 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -478,8 +478,9 @@ static std::string ReplacePlaceholders(const std::string& pattern) { for (const auto& [placeholder, getter] : kPlaceholderMap) { size_t pos = 0; while ((pos = result.find(placeholder, pos)) != std::string::npos) { - result.replace(pos, placeholder.length(), getter()); - pos += getter().length(); + const std::string value = getter(); + result.replace(pos, placeholder.length(), value); + pos += value.length(); } } diff --git a/test/sequential/test-cpu-prof-name.js b/test/sequential/test-cpu-prof-name.js index 3f1c6945c5436f..f40e639e92f624 100644 --- a/test/sequential/test-cpu-prof-name.js +++ b/test/sequential/test-cpu-prof-name.js @@ -8,6 +8,8 @@ const fixtures = require('../common/fixtures'); common.skipIfInspectorDisabled(); const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); const { spawnSync } = require('child_process'); const tmpdir = require('../common/tmpdir'); @@ -41,3 +43,36 @@ const { assert.deepStrictEqual(profiles, [file]); verifyFrames(output, file, 'fibonacci.js'); } + +// --cpu-prof-name with ${pid} placeholder +{ + tmpdir.refresh(); + // eslint-disable-next-line no-template-curly-in-string + const profName = 'CPU.${pid}.cpuprofile'; + const dir = tmpdir.path; + + const output = spawnSync(process.execPath, [ + '--cpu-prof', + '--cpu-prof-interval', + kCpuProfInterval, + '--cpu-prof-name', + profName, + fixtures.path('workload', 'fibonacci.js'), + ], { + cwd: dir, + env + }); + + if (output.status !== 0) { + console.error(output.stderr.toString()); + } + + assert.strictEqual(output.status, 0); + + const expectedFile = path.join(dir, `CPU.${output.pid}.cpuprofile`); + assert.ok(fs.existsSync(expectedFile), `Expected file ${expectedFile} not found.`); + + verifyFrames(output, expectedFile, 'fibonacci.js'); + + fs.unlinkSync(expectedFile); +} From 29dd75fb363da88fbd8950d4b4c8191af6131d1c Mon Sep 17 00:00:00 2001 From: Haram Jeong <91401364+haramj@users.noreply.github.com> Date: Sun, 20 Jul 2025 18:15:09 +0900 Subject: [PATCH 09/11] Update doc/api/cli.md Co-authored-by: Daeyeon Jeong --- doc/api/cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index f85d4c2d14557b..70a0b58742d1c1 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -541,8 +541,8 @@ CPU.20190409.202950.15293.0.0.cpuprofile ``` If `--cpu-prof-name` is specified, the provided value is used as a template -for the file name. Some placeholders are supported and will be substituted -at runtime: +for the file name. The following placeholder is supported and will be +substituted at runtime: * `${pid}` — the current process ID From 284e777a6dc0dbe4f1333974a7930dd16412af2d Mon Sep 17 00:00:00 2001 From: Jeong Haram <91401364+haramj@users.noreply.github.com> Date: Sun, 20 Jul 2025 09:28:40 +0000 Subject: [PATCH 10/11] doc: fix trailing whitespace --- doc/api/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 70a0b58742d1c1..9f61f5f7cc93b8 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -541,7 +541,7 @@ CPU.20190409.202950.15293.0.0.cpuprofile ``` If `--cpu-prof-name` is specified, the provided value is used as a template -for the file name. The following placeholder is supported and will be +for the file name. The following placeholder is supported and will be substituted at runtime: * `${pid}` — the current process ID From 3795a98eb67035e8c8cfe3f79fb0e3c93cc2b6ef Mon Sep 17 00:00:00 2001 From: Jeong Haram <91401364+haramj@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:00:02 +0000 Subject: [PATCH 11/11] trigger CI rerun