[compiler-rt] [asan] Add test case for alignment of FakeStack frames for >4KB objects (PR #152889)
Thurston Dang via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 9 23:25:08 PDT 2025
https://github.com/thurstond updated https://github.com/llvm/llvm-project/pull/152889
>From b8dd31dd354eb469adcf836a3ca7f7fe1efac8eb Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Sun, 10 Aug 2025 05:00:22 +0000
Subject: [PATCH 1/3] [asan] Add test case for alignment of FakeStack frames
This test case demonstrates that ASan does not currently align FakeStack frames correctly.
(https://github.com/llvm/llvm-project/pull/152819 will fix it.)
---
.../asan/TestCases/fakestack_alignment.cpp | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)
create mode 100644 compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
diff --git a/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp b/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
new file mode 100644
index 0000000000000..597a486e26534
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
@@ -0,0 +1,74 @@
+// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 %s -o %t && %run %t 2>&1
+// XFAIL: *
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct alignas(4096) page {
+ int x;
+};
+
+struct alignas(16384) larry {
+ int x;
+};
+
+bool misaligned = false;
+
+void grandchild(void) {
+ larry l2;
+ uint alignment = (unsigned long)&l2 % alignof(larry);
+ if (alignment != 0)
+ misaligned = true;
+
+ printf ("Grandchild: address modulo alignment %u\n", alignment);
+}
+
+// Even if the FakeStack frame is aligned by chance to 16384, we can use an
+// intervening stack frame to knock it out of alignment.
+void child(void) {
+ page p1;
+ uint alignment = (unsigned long)&p1 % alignof(page);
+ printf ("Child: address modulo alignment is %u\n", alignment);
+ if (alignment != 0)
+ misaligned = true;
+
+ grandchild();
+}
+
+// Check whether the FakeStack frame is sufficiently aligned. Alignment can
+// happen by chance, so try this on many threads if you don't want
+void *Thread(void *unused) {
+ larry l1;
+ uint alignment = (unsigned long)&l1 % alignof(larry);
+ printf ("Thread: address modulo alignment is %u\n", alignment);
+ if (alignment != 0)
+ misaligned = true;
+
+ child();
+
+ return NULL;
+}
+
+int main(int argc, char **argv) {
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+
+ pthread_t t[10];
+ for (int i = 0; i < 10; i++) {
+ pthread_create(&t[i], &attr, Thread, 0);
+ }
+ pthread_attr_destroy(&attr);
+ for (int i = 0; i < 10; i++) {
+ pthread_join(t[i], 0);
+ }
+
+ if (misaligned) {
+ printf ("Test failed: not perfectly aligned\n");
+ exit(1);
+ }
+
+ return 0;
+}
>From 115b11b6cf2606396cfbb9b157e6a9bb43bff875 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Sun, 10 Aug 2025 06:07:55 +0000
Subject: [PATCH 2/3] clang-format
---
.../asan/TestCases/fakestack_alignment.cpp | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp b/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
index 597a486e26534..0b0dbd17571bb 100644
--- a/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
+++ b/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
@@ -8,11 +8,11 @@
#include <string.h>
struct alignas(4096) page {
- int x;
+ int x;
};
struct alignas(16384) larry {
- int x;
+ int x;
};
bool misaligned = false;
@@ -23,7 +23,7 @@ void grandchild(void) {
if (alignment != 0)
misaligned = true;
- printf ("Grandchild: address modulo alignment %u\n", alignment);
+ printf("Grandchild: address modulo alignment %u\n", alignment);
}
// Even if the FakeStack frame is aligned by chance to 16384, we can use an
@@ -31,7 +31,7 @@ void grandchild(void) {
void child(void) {
page p1;
uint alignment = (unsigned long)&p1 % alignof(page);
- printf ("Child: address modulo alignment is %u\n", alignment);
+ printf("Child: address modulo alignment is %u\n", alignment);
if (alignment != 0)
misaligned = true;
@@ -40,10 +40,10 @@ void child(void) {
// Check whether the FakeStack frame is sufficiently aligned. Alignment can
// happen by chance, so try this on many threads if you don't want
-void *Thread(void *unused) {
+void *Thread(void *unused) {
larry l1;
uint alignment = (unsigned long)&l1 % alignof(larry);
- printf ("Thread: address modulo alignment is %u\n", alignment);
+ printf("Thread: address modulo alignment is %u\n", alignment);
if (alignment != 0)
misaligned = true;
@@ -58,15 +58,15 @@ int main(int argc, char **argv) {
pthread_t t[10];
for (int i = 0; i < 10; i++) {
- pthread_create(&t[i], &attr, Thread, 0);
+ pthread_create(&t[i], &attr, Thread, 0);
}
pthread_attr_destroy(&attr);
for (int i = 0; i < 10; i++) {
- pthread_join(t[i], 0);
+ pthread_join(t[i], 0);
}
if (misaligned) {
- printf ("Test failed: not perfectly aligned\n");
+ printf("Test failed: not perfectly aligned\n");
exit(1);
}
>From ad9be29dfad441a0a3bc9b3730e8e53f4300be4b Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Sun, 10 Aug 2025 06:24:32 +0000
Subject: [PATCH 3/3] Simplify test case by removing useless steps
---
.../asan/TestCases/fakestack_alignment.cpp | 29 +++----------------
1 file changed, 4 insertions(+), 25 deletions(-)
diff --git a/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp b/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
index 0b0dbd17571bb..7c7105398d955 100644
--- a/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
+++ b/compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
@@ -17,29 +17,8 @@ struct alignas(16384) larry {
bool misaligned = false;
-void grandchild(void) {
- larry l2;
- uint alignment = (unsigned long)&l2 % alignof(larry);
- if (alignment != 0)
- misaligned = true;
-
- printf("Grandchild: address modulo alignment %u\n", alignment);
-}
-
-// Even if the FakeStack frame is aligned by chance to 16384, we can use an
-// intervening stack frame to knock it out of alignment.
-void child(void) {
- page p1;
- uint alignment = (unsigned long)&p1 % alignof(page);
- printf("Child: address modulo alignment is %u\n", alignment);
- if (alignment != 0)
- misaligned = true;
-
- grandchild();
-}
-
// Check whether the FakeStack frame is sufficiently aligned. Alignment can
-// happen by chance, so try this on many threads if you don't want
+// happen by chance, so try this on many threads.
void *Thread(void *unused) {
larry l1;
uint alignment = (unsigned long)&l1 % alignof(larry);
@@ -56,12 +35,12 @@ int main(int argc, char **argv) {
pthread_attr_t attr;
pthread_attr_init(&attr);
- pthread_t t[10];
- for (int i = 0; i < 10; i++) {
+ pthread_t t[32];
+ for (int i = 0; i < 32; i++) {
pthread_create(&t[i], &attr, Thread, 0);
}
pthread_attr_destroy(&attr);
- for (int i = 0; i < 10; i++) {
+ for (int i = 0; i < 32; i++) {
pthread_join(t[i], 0);
}
More information about the llvm-commits
mailing list