Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Profile] Disable continuous mode when reset to default.profraw due to malformed LLVM_PROFILE_FILE. #74879

Merged
merged 5 commits into from
Dec 11, 2023

Conversation

ZequanWu
Copy link
Contributor

@ZequanWu ZequanWu commented Dec 8, 2023

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.

@llvmbot llvmbot added compiler-rt PGO Profile Guided Optimizations labels Dec 8, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Dec 8, 2023

@llvm/pr-subscribers-pgo

Author: Zequan Wu (ZequanWu)

Changes

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 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.


Full diff: https://github.com/llvm/llvm-project/pull/74879.diff

4 Files Affected:

  • (modified) compiler-rt/lib/profile/InstrProfiling.h (+6)
  • (modified) compiler-rt/lib/profile/InstrProfilingBuffer.c (+4)
  • (modified) compiler-rt/lib/profile/InstrProfilingFile.c (+1)
  • (added) compiler-rt/test/profile/ContinuousSyncMode/reset-default-profile.c (+21)
diff --git a/compiler-rt/lib/profile/InstrProfiling.h b/compiler-rt/lib/profile/InstrProfiling.h
index c5b0b34f2d8af0..813545a29a8e86 100644
--- a/compiler-rt/lib/profile/InstrProfiling.h
+++ b/compiler-rt/lib/profile/InstrProfiling.h
@@ -54,6 +54,12 @@ int __llvm_profile_is_continuous_mode_enabled(void);
  */
 void __llvm_profile_enable_continuous_mode(void);
 
+/*!
+ * \brief Enable continuous mode.
+ *
+ */
+void __llvm_profile_disable_continuous_mode(void);
+
 /*!
  * \brief Set the page size.
  *
diff --git a/compiler-rt/lib/profile/InstrProfilingBuffer.c b/compiler-rt/lib/profile/InstrProfilingBuffer.c
index cd1f067bd188e4..5657bf5bacf225 100644
--- a/compiler-rt/lib/profile/InstrProfilingBuffer.c
+++ b/compiler-rt/lib/profile/InstrProfilingBuffer.c
@@ -33,6 +33,10 @@ COMPILER_RT_VISIBILITY void __llvm_profile_enable_continuous_mode(void) {
   ContinuouslySyncProfile = 1;
 }
 
+void __llvm_profile_disable_continuous_mode(void) {
+  ContinuouslySyncProfile = 0;
+}
+
 COMPILER_RT_VISIBILITY void __llvm_profile_set_page_size(unsigned PS) {
   PageSize = PS;
 }
diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c
index 1685b30b9492a6..4fea835f3332da 100644
--- a/compiler-rt/lib/profile/InstrProfilingFile.c
+++ b/compiler-rt/lib/profile/InstrProfilingFile.c
@@ -711,6 +711,7 @@ static void resetFilenameToDefault(void) {
   memset(&lprofCurFilename, 0, sizeof(lprofCurFilename));
   lprofCurFilename.FilenamePat = DefaultProfileName;
   lprofCurFilename.PNS = PNS_default;
+  __llvm_profile_disable_continuous_mode();
 }
 
 static unsigned getMergePoolSize(const char *FilenamePat, int *I) {
diff --git a/compiler-rt/test/profile/ContinuousSyncMode/reset-default-profile.c b/compiler-rt/test/profile/ContinuousSyncMode/reset-default-profile.c
new file mode 100644
index 00000000000000..f09ab40f4b0352
--- /dev/null
+++ b/compiler-rt/test/profile/ContinuousSyncMode/reset-default-profile.c
@@ -0,0 +1,21 @@
+// REQUIRES: darwin || linux
+
+// Test when LLVM_PROFILE_FILE is set incorrectly, it should fall backs to use default.profraw without runtime error.
+
+// Create & cd into a temporary directory.
+// RUN: rm -rf %t.dir && mkdir -p %t.dir && cd %t.dir
+// RUN: %clang -fprofile-instr-generate -fcoverage-mapping -mllvm -runtime-counter-relocation=true -o %t.exe %s
+// RUN: env LLVM_PROFILE_FILE="incorrect-profile-name%m%c%c.profraw" %run %t.exe
+// RUN: ls -l default.profraw | FileCheck %s
+
+// CHECK:     default.profraw
+// CEHCK-NOT: incorrect-profile-name.profraw
+
+#include <stdio.h>
+int f() { return 0; }
+
+int main(int argc, char **argv) {
+  FILE* File = fopen("default.profraw", "w");
+  f();
+  return 0;
+}

Copy link

github-actions bot commented Dec 8, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

@@ -54,6 +54,12 @@ int __llvm_profile_is_continuous_mode_enabled(void);
*/
void __llvm_profile_enable_continuous_mode(void);

/*!
* \brief Enable continuous mode.
Copy link
Contributor

@alanzhao1 alanzhao1 Dec 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: fix comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// RUN: ls -l default.profraw | FileCheck %s

// CHECK: default.profraw
// CEHCK-NOT: incorrect-profile-name.profraw
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: CHECK

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@aeubanks
Copy link
Contributor

aeubanks commented Dec 8, 2023

what about printing an error and immediately aborting when LLVM_PROFILE_FILE is invalid?

Copy link
Contributor

@david-xl david-xl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The disabling can be done earlier at around line 808.

@ZequanWu
Copy link
Contributor Author

ZequanWu commented Dec 8, 2023

what about printing an error and immediately aborting when LLVM_PROFILE_FILE is invalid?

I think this is better than falls back to default.profraw with a warning, which is hard to notice.
Or we can simply allow multiple %c and enable continuous mode as this shouldn't cause any ambiguity. But multiple %m might cause ambiguity because it can have %1m and %2m at the same time and cause ambiguity.

@ZequanWu
Copy link
Contributor Author

ZequanWu commented Dec 8, 2023

The disabling can be done earlier at around line 808.

Done.

@david-xl
Copy link
Contributor

david-xl commented Dec 8, 2023

what about printing an error and immediately aborting when LLVM_PROFILE_FILE is invalid?

I think this is better than falls back to default.profraw with a warning, which is hard to notice. Or we can simply allow multiple %c and enable continuous mode as this shouldn't cause any ambiguity. But multiple %m might cause ambiguity because it can have %1m and %2m at the same time and cause ambiguity.

Currently all parsing errors are treated as warnings. Perhaps a runtime option can be added in the future to turn them into hard errors.

@ZequanWu ZequanWu merged commit ace26b3 into llvm:main Dec 11, 2023
4 checks passed
@ZequanWu ZequanWu deleted the fix-profile-buserr branch December 11, 2023 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler-rt PGO Profile Guided Optimizations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants