[llvm] [llvm-profgen] Harden perf script invocation (PR #212253)
Sergey Shcherbinin via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 5 03:07:44 PDT 2026
https://github.com/SergeyShch01 updated https://github.com/llvm/llvm-project/pull/212253
>From 29d601579a29436affa2a0585eee4d5713c0d404 Mon Sep 17 00:00:00 2001
From: Sergey Shcherbinin <sscherbinin at nvidia.com>
Date: Mon, 27 Jul 2026 16:48:33 +0400
Subject: [PATCH 1/6] [llvm-profgen] Add --perf-binary to select the perf
executable
Allow selecting the perf binary used for --perfdata conversion instead of
always searching PATH. Also report perf invocation failures and clear
redirect files between the two perf script calls so error diagnostics and
tests are reliable.
Assisted by GPT-5
---
llvm/docs/CommandGuide/llvm-profgen.rst | 5 ++
.../tools/llvm-profgen/perf-binary-error.test | 48 ++++++++++++++
llvm/tools/llvm-profgen/PerfReader.cpp | 63 ++++++++++++++++---
3 files changed, 109 insertions(+), 7 deletions(-)
create mode 100644 llvm/test/tools/llvm-profgen/perf-binary-error.test
diff --git a/llvm/docs/CommandGuide/llvm-profgen.rst b/llvm/docs/CommandGuide/llvm-profgen.rst
index 006cdfecf4f88..2b4bfbbd53d3a 100644
--- a/llvm/docs/CommandGuide/llvm-profgen.rst
+++ b/llvm/docs/CommandGuide/llvm-profgen.rst
@@ -71,6 +71,11 @@ OPTIONS
Print mmap events.
+.. option:: --perf-binary=<filename>
+
+ Path to the ``perf`` executable used to convert ``--perfdata`` input. If this
+ option is omitted, ``llvm-profgen`` searches for ``perf`` in ``PATH``.
+
.. option:: --show-disassembly
Print disassembled code.
diff --git a/llvm/test/tools/llvm-profgen/perf-binary-error.test b/llvm/test/tools/llvm-profgen/perf-binary-error.test
new file mode 100644
index 0000000000000..298cdcf069bfc
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/perf-binary-error.test
@@ -0,0 +1,48 @@
+# REQUIRES: x86-registered-target
+
+# RUN: split-file %s %t
+# RUN: yaml2obj %t/binary.yaml -o %t/perf-binary-error.exe
+# RUN: touch %t/perf.data
+
+# RUN: not llvm-profgen --binary=%t/perf-binary-error.exe \
+# RUN: --perfdata=%t/perf.data --perf-binary yaml2obj --output=/dev/null \
+# RUN: 2>&1 | FileCheck %s --check-prefix=EXIT
+# RUN: not llvm-profgen --binary=%t/perf-binary-error.exe \
+# RUN: --perfdata=%t/perf.data --perf-binary=%t/missing-perf \
+# RUN: --output=/dev/null 2>&1 | FileCheck %s --check-prefix=EXEC
+
+# EXIT: error: Perf script failed with exit code 1
+# EXIT: yaml2obj
+# EXEC: error: Failed to execute perf script
+
+#--- binary.yaml
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ Offset: 0x1000
+ AddressAlign: 0x1
+ ## ret
+ Content: C3
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ Offset: 0
+ VAddr: 0
+ Align: 0x1000
+ FirstSec: .text
+ LastSec: .text
+Symbols:
+ - Name: foo
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1000
+ Size: 0x1
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index 5fb1c6d252915..8ae6a2d5453f3 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -18,6 +18,7 @@
#include "llvm/Support/Process.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#define DEBUG_TYPE "perf-reader"
@@ -69,6 +70,11 @@ cl::opt<bool> TimeProfGen("time-profgen", cl::desc("Time llvm-profgen phases"),
static const char *TimerGroupName = "profgen";
static const char *TimerGroupDesc = "llvm-profgen";
+static cl::opt<std::string> PerfPath("perf-binary",
+ cl::desc("Path to perf binary"),
+ cl::value_desc("filename"),
+ cl::cat(ProfGenCategory));
+
namespace sampleprof {
void VirtualUnwinder::unwindCall(UnwindState &State) {
@@ -462,11 +468,13 @@ PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary, bool SkipPID,
std::optional<int32_t> PIDFilter) {
StringRef PerfData = File.InputFilePath;
// Run perf script to retrieve PIDs matching binary we're interested in.
- auto PerfExecutable = sys::Process::FindInEnvPath("PATH", "perf");
+ auto PerfExecutable = PerfPath.getNumOccurrences()
+ ? std::optional<std::string>(PerfPath)
+ : sys::Process::FindInEnvPath("PATH", "perf");
if (!PerfExecutable) {
exitWithError("Perf not found.");
}
- std::string PerfPath = *PerfExecutable;
+ std::string PerfExecutablePath = *PerfExecutable;
SmallString<128> PerfTraceFile;
sys::fs::createUniquePath("perf-script-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.tmp",
PerfTraceFile, /*MakeAbsolute=*/true);
@@ -477,12 +485,53 @@ PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary, bool SkipPID,
PerfScriptReader::TempFileCleanups.emplace_back(PerfTraceFile);
PerfScriptReader::TempFileCleanups.emplace_back(ErrorFile);
+ auto RunPerfScript = [&](ArrayRef<StringRef> Args) {
+ // ExecuteAndWait does not truncate redirected output files on Unix. Remove
+ // both files so a shorter invocation cannot retain output from the
+ // previous perf script invocation.
+ for (StringRef Path : {StringRef(PerfTraceFile), StringRef(ErrorFile)}) {
+ if (std::error_code EC = sys::fs::remove(Path))
+ exitWithError(EC, Path);
+ }
+
+ std::string ExecutionError;
+ bool ExecutionFailed = false;
+ int ExitCode =
+ sys::ExecuteAndWait(PerfExecutablePath, Args, std::nullopt, Redirects,
+ /*SecondsToWait=*/0, /*MemoryLimit=*/0,
+ &ExecutionError, &ExecutionFailed);
+ if (!ExecutionFailed && ExitCode == 0)
+ return;
+
+ std::string Message;
+ raw_string_ostream OS(Message);
+ if (ExecutionFailed || ExitCode == -1)
+ OS << "Failed to execute perf script";
+ else if (ExitCode == -2)
+ OS << "Perf script terminated abnormally";
+ else
+ OS << "Perf script failed with exit code " << ExitCode;
+ if (!ExecutionError.empty())
+ OS << ": " << ExecutionError;
+
+ if (auto ErrorBuffer = MemoryBuffer::getFile(ErrorFile)) {
+ StringRef Stderr = ErrorBuffer.get()->getBuffer().trim();
+ if (!Stderr.empty())
+ OS << "\n" << Stderr;
+ }
+ exitWithError(OS.str());
+ };
+
std::string PIDs;
if (!SkipPID) {
- StringRef ScriptMMapArgs[] = {PerfPath, "script", "--show-mmap-events",
- "-F", "comm,pid", "-i",
+ StringRef ScriptMMapArgs[] = {PerfExecutablePath,
+ "script",
+ "--show-mmap-events",
+ "-F",
+ "comm,pid",
+ "-i",
PerfData};
- sys::ExecuteAndWait(PerfPath, ScriptMMapArgs, std::nullopt, Redirects);
+ RunPerfScript(ScriptMMapArgs);
// Collect the PIDs
TraceStream TraceIt(PerfTraceFile);
@@ -509,7 +558,7 @@ PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary, bool SkipPID,
// Run perf script again to retrieve events for PIDs collected above
SmallVector<StringRef, 8> ScriptSampleArgs;
- ScriptSampleArgs.push_back(PerfPath);
+ ScriptSampleArgs.push_back(PerfExecutablePath);
ScriptSampleArgs.push_back("script");
ScriptSampleArgs.push_back("--show-mmap-events");
ScriptSampleArgs.push_back("-F");
@@ -520,7 +569,7 @@ PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary, bool SkipPID,
ScriptSampleArgs.push_back("--pid");
ScriptSampleArgs.push_back(PIDs);
}
- sys::ExecuteAndWait(PerfPath, ScriptSampleArgs, std::nullopt, Redirects);
+ RunPerfScript(ScriptSampleArgs);
return {std::string(PerfTraceFile), InputFormat::PerfScript,
PerfContent::UnknownContent};
>From df7258efa7273c26ec19f1daf85f71c666c85e9a Mon Sep 17 00:00:00 2001
From: Sergey Shcherbinin <sscherbinin at nvidia.com>
Date: Mon, 27 Jul 2026 17:35:44 +0400
Subject: [PATCH 2/6] [llvm-profgen] Add perfdata redirect truncation test
Cover stale stdout/stderr between the two perf script invocations used for
--perfdata conversion, using an arch-neutral X86 fixture.
---
.../tools/llvm-profgen/perfdata-redirect.test | 126 ++++++++++++++++++
1 file changed, 126 insertions(+)
create mode 100644 llvm/test/tools/llvm-profgen/perfdata-redirect.test
diff --git a/llvm/test/tools/llvm-profgen/perfdata-redirect.test b/llvm/test/tools/llvm-profgen/perfdata-redirect.test
new file mode 100644
index 0000000000000..cfd124b696147
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/perfdata-redirect.test
@@ -0,0 +1,126 @@
+# REQUIRES: system-linux, x86-registered-target
+
+# RUN: split-file %s %t
+# RUN: yaml2obj %t/binary.yaml -o %t/perfdata-redirect.exe
+# RUN: touch %t/perf.data
+# RUN: chmod +x %t/mock-perf %t/mock-perf-fail
+# RUN: llvm-profgen --binary=%t/perfdata-redirect.exe \
+# RUN: --perfdata=%t/perf.data --perf-binary=%t/mock-perf \
+# RUN: --skip-symbolization --use-offset=0 --format=text --output=%t/profile
+# RUN: FileCheck %s --check-prefix=PROFILE --input-file=%t/profile
+# RUN: not llvm-profgen --binary=%t/perfdata-redirect.exe \
+# RUN: --perfdata=%t/perf.data --perf-binary=%t/mock-perf-fail \
+# RUN: --output=/dev/null 2>&1 \
+# RUN: | FileCheck %s --check-prefix=SECOND-ERROR
+
+## The first mock invocation deliberately writes the complete second output plus a
+## duplicate sample. Without truncating the shared redirect file, that stale
+## sample survives the second invocation and doubles every profile count.
+# PROFILE: 1
+# PROFILE-NEXT: 1008-100c:1
+# PROFILE-NEXT: 2
+# PROFILE-NEXT: 1000->1008:1
+# PROFILE-NEXT: 100c->1000:1
+
+## The first invocation also leaves a longer stderr message. Verify that an
+## error from the second invocation contains only its own stderr.
+# SECOND-ERROR: error: Perf script failed with exit code 7
+# SECOND-ERROR-NEXT: second invocation failed
+# SECOND-ERROR-NOT: STALE-FIRST-STDERR
+
+#--- mock-perf
+#!/bin/sh
+
+if [ "$1" != "script" ] || [ "$2" != "--show-mmap-events" ] || \
+ [ "$3" != "-F" ] || [ "$5" != "-i" ] || [ ! -f "$6" ]; then
+ echo "unexpected perf arguments: $*" >&2
+ exit 2
+fi
+
+emit_sample() {
+ printf '%s\n' 'PERF_RECORD_MMAP2 1/1: [0x700000000000(0x2000) @ 0 00:00 0 0]: r-xp /tmp/perfdata-redirect.exe'
+ printf '%s\n' '70000000100c 0x70000000100c/0x700000001000/P/-/-/0 0x700000001000/0x700000001008/P/-/-/0'
+}
+
+case "$4" in
+ comm,pid)
+ if [ "$#" -ne 6 ]; then
+ echo "unexpected mmap arguments: $*" >&2
+ exit 2
+ fi
+ emit_sample
+ printf '%s\n' '70000000100c 0x70000000100c/0x700000001000/P/-/-/0 0x700000001000/0x700000001008/P/-/-/0'
+ ;;
+ ip,brstack)
+ if [ "$#" -ne 8 ] || [ "$7" != "--pid" ] || [ "$8" != "1" ]; then
+ echo "unexpected sample arguments: $*" >&2
+ exit 2
+ fi
+ emit_sample
+ ;;
+ *)
+ echo "unexpected perf fields: $4" >&2
+ exit 2
+ ;;
+esac
+
+#--- mock-perf-fail
+#!/bin/sh
+
+if [ "$1" != "script" ] || [ "$2" != "--show-mmap-events" ] || \
+ [ "$3" != "-F" ] || [ "$5" != "-i" ] || [ ! -f "$6" ]; then
+ echo "unexpected perf arguments: $*" >&2
+ exit 2
+fi
+
+case "$4" in
+ comm,pid)
+ printf '%s\n' 'PERF_RECORD_MMAP2 1/1: [0x700000000000(0x2000) @ 0 00:00 0 0]: r-xp /tmp/perfdata-redirect.exe'
+ printf '%s\n' 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx STALE-FIRST-STDERR' >&2
+ ;;
+ ip,brstack)
+ printf '%s\n' 'second invocation failed' >&2
+ exit 7
+ ;;
+ *)
+ echo "unexpected perf fields: $4" >&2
+ exit 2
+ ;;
+esac
+
+#--- binary.yaml
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+ Entry: 0x1000
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ Offset: 0x1000
+ AddressAlign: 0x1
+ ## 1000: jmp 0x1008
+ ## 1002: nop*6
+ ## 1008: nop*4
+ ## 100c: jmp 0x1000
+ ## 100e: ret
+ Content: EB0690909090909090909090EBF2C3
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ Offset: 0
+ VAddr: 0
+ FileSize: 0x100F
+ MemSize: 0x100F
+ Align: 0x1000
+Symbols:
+ - Name: foo
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1000
+ Size: 0xF
>From 2033c33f6c938ed4f028be6db371b33742eba570 Mon Sep 17 00:00:00 2001
From: Sergey Shcherbinin <sscherbinin at nvidia.com>
Date: Mon, 27 Jul 2026 17:50:14 +0400
Subject: [PATCH 3/6] [llvm-profgen] Move perf harness tests under X86/
Place the new lit tests with the other X86 fixtures and rely on
X86/lit.local.cfg instead of an explicit x86-registered-target requirement.
---
llvm/test/tools/llvm-profgen/{ => X86}/perf-binary-error.test | 2 --
llvm/test/tools/llvm-profgen/{ => X86}/perfdata-redirect.test | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
rename llvm/test/tools/llvm-profgen/{ => X86}/perf-binary-error.test (97%)
rename llvm/test/tools/llvm-profgen/{ => X86}/perfdata-redirect.test (98%)
diff --git a/llvm/test/tools/llvm-profgen/perf-binary-error.test b/llvm/test/tools/llvm-profgen/X86/perf-binary-error.test
similarity index 97%
rename from llvm/test/tools/llvm-profgen/perf-binary-error.test
rename to llvm/test/tools/llvm-profgen/X86/perf-binary-error.test
index 298cdcf069bfc..b7465432c8a4f 100644
--- a/llvm/test/tools/llvm-profgen/perf-binary-error.test
+++ b/llvm/test/tools/llvm-profgen/X86/perf-binary-error.test
@@ -1,5 +1,3 @@
-# REQUIRES: x86-registered-target
-
# RUN: split-file %s %t
# RUN: yaml2obj %t/binary.yaml -o %t/perf-binary-error.exe
# RUN: touch %t/perf.data
diff --git a/llvm/test/tools/llvm-profgen/perfdata-redirect.test b/llvm/test/tools/llvm-profgen/X86/perfdata-redirect.test
similarity index 98%
rename from llvm/test/tools/llvm-profgen/perfdata-redirect.test
rename to llvm/test/tools/llvm-profgen/X86/perfdata-redirect.test
index cfd124b696147..27c8b3fad9771 100644
--- a/llvm/test/tools/llvm-profgen/perfdata-redirect.test
+++ b/llvm/test/tools/llvm-profgen/X86/perfdata-redirect.test
@@ -1,4 +1,4 @@
-# REQUIRES: system-linux, x86-registered-target
+# REQUIRES: system-linux
# RUN: split-file %s %t
# RUN: yaml2obj %t/binary.yaml -o %t/perfdata-redirect.exe
>From c1332a90896b5487bad6119a75391012db79fdec Mon Sep 17 00:00:00 2001
From: Sergey Shcherbinin <sscherbinin at nvidia.com>
Date: Fri, 31 Jul 2026 17:15:20 +0400
Subject: [PATCH 4/6] [llvm-profgen][test] Explain yaml2obj error fixture
Document why yaml2obj provides a stable nonzero-exit test input.
---
llvm/test/tools/llvm-profgen/X86/perf-binary-error.test | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/test/tools/llvm-profgen/X86/perf-binary-error.test b/llvm/test/tools/llvm-profgen/X86/perf-binary-error.test
index b7465432c8a4f..a6f98bc3459fa 100644
--- a/llvm/test/tools/llvm-profgen/X86/perf-binary-error.test
+++ b/llvm/test/tools/llvm-profgen/X86/perf-binary-error.test
@@ -2,6 +2,8 @@
# RUN: yaml2obj %t/binary.yaml -o %t/perf-binary-error.exe
# RUN: touch %t/perf.data
+## yaml2obj is consistently available in LLVM test environments and returns a
+## nonzero status when invoked with perf script arguments.
# RUN: not llvm-profgen --binary=%t/perf-binary-error.exe \
# RUN: --perfdata=%t/perf.data --perf-binary yaml2obj --output=/dev/null \
# RUN: 2>&1 | FileCheck %s --check-prefix=EXIT
>From 2177ca1a0189b7ee812eac9c9043c2beb914d645 Mon Sep 17 00:00:00 2001
From: Sergey Shcherbinin <sscherbinin at nvidia.com>
Date: Fri, 31 Jul 2026 19:31:05 +0400
Subject: [PATCH 5/6] [llvm-profgen] Retrigger CI after network timeout
>From 6f50893f5d2019a0a71c00412160b8350ecacba4 Mon Sep 17 00:00:00 2001
From: Sergey Shcherbinin <sscherbinin at nvidia.com>
Date: Wed, 5 Aug 2026 14:06:54 +0400
Subject: [PATCH 6/6] [llvm-profgen] Drop --perf-binary; select mock perf via
PATH
Remove the public option and keep PATH-based discovery so tests can
inject a mock perf without exposing a dedicated CLI switch.
---
llvm/docs/CommandGuide/llvm-profgen.rst | 5 ----
...-error.test => perf-invocation-error.test} | 30 ++++++++++++++-----
.../llvm-profgen/X86/perfdata-redirect.test | 17 ++++++-----
llvm/test/tools/llvm-profgen/lit.local.cfg | 3 ++
llvm/tools/llvm-profgen/PerfReader.cpp | 9 +-----
5 files changed, 35 insertions(+), 29 deletions(-)
rename llvm/test/tools/llvm-profgen/X86/{perf-binary-error.test => perf-invocation-error.test} (53%)
diff --git a/llvm/docs/CommandGuide/llvm-profgen.rst b/llvm/docs/CommandGuide/llvm-profgen.rst
index 2b4bfbbd53d3a..006cdfecf4f88 100644
--- a/llvm/docs/CommandGuide/llvm-profgen.rst
+++ b/llvm/docs/CommandGuide/llvm-profgen.rst
@@ -71,11 +71,6 @@ OPTIONS
Print mmap events.
-.. option:: --perf-binary=<filename>
-
- Path to the ``perf`` executable used to convert ``--perfdata`` input. If this
- option is omitted, ``llvm-profgen`` searches for ``perf`` in ``PATH``.
-
.. option:: --show-disassembly
Print disassembled code.
diff --git a/llvm/test/tools/llvm-profgen/X86/perf-binary-error.test b/llvm/test/tools/llvm-profgen/X86/perf-invocation-error.test
similarity index 53%
rename from llvm/test/tools/llvm-profgen/X86/perf-binary-error.test
rename to llvm/test/tools/llvm-profgen/X86/perf-invocation-error.test
index a6f98bc3459fa..8fa36b5a5b24b 100644
--- a/llvm/test/tools/llvm-profgen/X86/perf-binary-error.test
+++ b/llvm/test/tools/llvm-profgen/X86/perf-invocation-error.test
@@ -1,20 +1,34 @@
+# REQUIRES: system-linux
+
# RUN: split-file %s %t
-# RUN: yaml2obj %t/binary.yaml -o %t/perf-binary-error.exe
+# RUN: yaml2obj %t/binary.yaml -o %t/perf-invocation-error.exe
# RUN: touch %t/perf.data
+# RUN: chmod +x %t/exit/perf
-## yaml2obj is consistently available in LLVM test environments and returns a
-## nonzero status when invoked with perf script arguments.
-# RUN: not llvm-profgen --binary=%t/perf-binary-error.exe \
-# RUN: --perfdata=%t/perf.data --perf-binary yaml2obj --output=/dev/null \
+## Verify that a nonzero perf exit status and its stderr are reported.
+# RUN: not env PATH="%t/exit%{pathsep}%{PATH}" \
+# RUN: llvm-profgen --binary=%t/perf-invocation-error.exe \
+# RUN: --perfdata=%t/perf.data --output=/dev/null \
# RUN: 2>&1 | FileCheck %s --check-prefix=EXIT
-# RUN: not llvm-profgen --binary=%t/perf-binary-error.exe \
-# RUN: --perfdata=%t/perf.data --perf-binary=%t/missing-perf \
+## Use a PATH that contains only the non-executable mock, so discovery cannot
+## fall through to a system perf if lookup ever requires executability.
+# RUN: not env PATH="%t/exec" \
+# RUN: llvm-profgen --binary=%t/perf-invocation-error.exe \
+# RUN: --perfdata=%t/perf.data \
# RUN: --output=/dev/null 2>&1 | FileCheck %s --check-prefix=EXEC
# EXIT: error: Perf script failed with exit code 1
-# EXIT: yaml2obj
+# EXIT-NEXT: mock perf failed
# EXEC: error: Failed to execute perf script
+#--- exit/perf
+#!/bin/sh
+echo "mock perf failed" >&2
+exit 1
+
+#--- exec/perf
+This file is deliberately not executable.
+
#--- binary.yaml
--- !ELF
FileHeader:
diff --git a/llvm/test/tools/llvm-profgen/X86/perfdata-redirect.test b/llvm/test/tools/llvm-profgen/X86/perfdata-redirect.test
index 27c8b3fad9771..0a51303a94866 100644
--- a/llvm/test/tools/llvm-profgen/X86/perfdata-redirect.test
+++ b/llvm/test/tools/llvm-profgen/X86/perfdata-redirect.test
@@ -3,14 +3,15 @@
# RUN: split-file %s %t
# RUN: yaml2obj %t/binary.yaml -o %t/perfdata-redirect.exe
# RUN: touch %t/perf.data
-# RUN: chmod +x %t/mock-perf %t/mock-perf-fail
-# RUN: llvm-profgen --binary=%t/perfdata-redirect.exe \
-# RUN: --perfdata=%t/perf.data --perf-binary=%t/mock-perf \
+# RUN: chmod +x %t/success/perf %t/failure/perf
+# RUN: env PATH="%t/success%{pathsep}%{PATH}" \
+# RUN: llvm-profgen --binary=%t/perfdata-redirect.exe \
+# RUN: --perfdata=%t/perf.data \
# RUN: --skip-symbolization --use-offset=0 --format=text --output=%t/profile
# RUN: FileCheck %s --check-prefix=PROFILE --input-file=%t/profile
-# RUN: not llvm-profgen --binary=%t/perfdata-redirect.exe \
-# RUN: --perfdata=%t/perf.data --perf-binary=%t/mock-perf-fail \
-# RUN: --output=/dev/null 2>&1 \
+# RUN: not env PATH="%t/failure%{pathsep}%{PATH}" \
+# RUN: llvm-profgen --binary=%t/perfdata-redirect.exe \
+# RUN: --perfdata=%t/perf.data --output=/dev/null 2>&1 \
# RUN: | FileCheck %s --check-prefix=SECOND-ERROR
## The first mock invocation deliberately writes the complete second output plus a
@@ -28,7 +29,7 @@
# SECOND-ERROR-NEXT: second invocation failed
# SECOND-ERROR-NOT: STALE-FIRST-STDERR
-#--- mock-perf
+#--- success/perf
#!/bin/sh
if [ "$1" != "script" ] || [ "$2" != "--show-mmap-events" ] || \
@@ -64,7 +65,7 @@ case "$4" in
;;
esac
-#--- mock-perf-fail
+#--- failure/perf
#!/bin/sh
if [ "$1" != "script" ] || [ "$2" != "--show-mmap-events" ] || \
diff --git a/llvm/test/tools/llvm-profgen/lit.local.cfg b/llvm/test/tools/llvm-profgen/lit.local.cfg
index 8373a11e3f394..860e1e9557a7f 100644
--- a/llvm/test/tools/llvm-profgen/lit.local.cfg
+++ b/llvm/test/tools/llvm-profgen/lit.local.cfg
@@ -1 +1,4 @@
config.suffixes = [".test", ".ll", ".s", ".yaml"]
+
+# Allow tests to prepend a mock directory onto the real PATH.
+config.substitutions.append(("%{PATH}", config.environment["PATH"]))
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index 8ae6a2d5453f3..c4fc4fb25166f 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -70,11 +70,6 @@ cl::opt<bool> TimeProfGen("time-profgen", cl::desc("Time llvm-profgen phases"),
static const char *TimerGroupName = "profgen";
static const char *TimerGroupDesc = "llvm-profgen";
-static cl::opt<std::string> PerfPath("perf-binary",
- cl::desc("Path to perf binary"),
- cl::value_desc("filename"),
- cl::cat(ProfGenCategory));
-
namespace sampleprof {
void VirtualUnwinder::unwindCall(UnwindState &State) {
@@ -468,9 +463,7 @@ PerfScriptReader::convertPerfDataToTrace(ProfiledBinary *Binary, bool SkipPID,
std::optional<int32_t> PIDFilter) {
StringRef PerfData = File.InputFilePath;
// Run perf script to retrieve PIDs matching binary we're interested in.
- auto PerfExecutable = PerfPath.getNumOccurrences()
- ? std::optional<std::string>(PerfPath)
- : sys::Process::FindInEnvPath("PATH", "perf");
+ auto PerfExecutable = sys::Process::FindInEnvPath("PATH", "perf");
if (!PerfExecutable) {
exitWithError("Perf not found.");
}
More information about the llvm-commits
mailing list