Skip to content

Commit ace26b3

Browse files
authored
[Profile] Disable continuous mode when reset to default.profraw due to malformed LLVM_PROFILE_FILE. (#74879)
When LLVM_PROFILE_FILE is set incorrectly (e.g. multiple %c) and it falls back to use `default.profraw` name, but continuous mode is still set. This might cause signal bus in the following scenario. LLVM_PROFILE_FILE is set incorrectly (with "%c%c") for process A and B. Suppose A starts first and falls back to use `default.profraw` and mmaped its file content to memory. Later B starts and also falls back to use `default.profraw`, but it will truncate the file because online merging is disable when reseting to `default.profraw`. When A tries to update counter via mmaped memory, signal bus will occur. This fixes it by disabling continuous mode when reset to default.profraw.
1 parent b40c534 commit ace26b3

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

compiler-rt/lib/profile/InstrProfiling.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ int __llvm_profile_is_continuous_mode_enabled(void);
5454
*/
5555
void __llvm_profile_enable_continuous_mode(void);
5656

57+
/*!
58+
* \brief Disable continuous mode.
59+
*
60+
*/
61+
void __llvm_profile_disable_continuous_mode(void);
62+
5763
/*!
5864
* \brief Set the page size.
5965
*

compiler-rt/lib/profile/InstrProfilingBuffer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ COMPILER_RT_VISIBILITY void __llvm_profile_enable_continuous_mode(void) {
3333
ContinuouslySyncProfile = 1;
3434
}
3535

36+
void __llvm_profile_disable_continuous_mode(void) {
37+
ContinuouslySyncProfile = 0;
38+
}
39+
3640
COMPILER_RT_VISIBILITY void __llvm_profile_set_page_size(unsigned PS) {
3741
PageSize = PS;
3842
}

compiler-rt/lib/profile/InstrProfilingFile.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,7 @@ static int parseFilenamePattern(const char *FilenamePat,
806806
if (__llvm_profile_is_continuous_mode_enabled()) {
807807
PROF_WARN("%%c specifier can only be specified once in %s.\n",
808808
FilenamePat);
809+
__llvm_profile_disable_continuous_mode();
809810
return -1;
810811
}
811812
#if defined(__APPLE__) || defined(__ELF__) || defined(_WIN32)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// REQUIRES: darwin || linux
2+
3+
// Test when LLVM_PROFILE_FILE is set incorrectly, it should fall backs to use default.profraw without runtime error.
4+
5+
// Create & cd into a temporary directory.
6+
// RUN: rm -rf %t.dir && mkdir -p %t.dir && cd %t.dir
7+
// RUN: %clang -fprofile-instr-generate -fcoverage-mapping -mllvm -runtime-counter-relocation=true -o %t.exe %s
8+
// RUN: env LLVM_PROFILE_FILE="incorrect-profile-name%m%c%c.profraw" %run %t.exe
9+
// RUN: ls -l | FileCheck %s
10+
11+
// CHECK: default.profraw
12+
// CHECK-NOT: incorrect-profile-name.profraw
13+
14+
#include <stdio.h>
15+
int f() { return 0; }
16+
17+
int main(int argc, char **argv) {
18+
FILE *File = fopen("default.profraw", "w");
19+
f();
20+
return 0;
21+
}

0 commit comments

Comments
 (0)