Skip to content

Commit e36bd61

Browse files
authored
[asan] Add test case for alignment of FakeStack frames (#152889)
This test case demonstrates that ASan does not currently align FakeStack frames correctly: - for 4KB objects on a 64KB stack, alignment is deterministically incorrect - for objects larger than 4KB, even with large stack sizes, alignment is not guaranteed #152819 will fix it.
1 parent ea14834 commit e36bd61

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Regression test 1:
2+
// This deterministically fails: when the stack size is 1<<16, FakeStack's
3+
// GetFrame() is out of alignment, because SizeRequiredForFlags(16) == 2K.
4+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=4096 -DTHREAD_COUNT=1 -DTHREAD_STACK_SIZE=65536 %s -o %t && %run %t 2>&1
5+
6+
// Regression test 2:
7+
// The FakeStack frame is not guaranteed to be aligned, but alignment can
8+
// happen by chance, so try this on many threads.
9+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=8192 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=131072 %s -o %t && %run %t 2>&1
10+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=16384 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=131072 %s -o %t && %run %t 2>&1
11+
12+
// Extra tests:
13+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=4096 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=65536 %s -o %t && %run %t 2>&1
14+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=8192 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=65536 %s -o %t && %run %t 2>&1
15+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=16384 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=65536 %s -o %t && %run %t 2>&1
16+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=4096 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=131072 %s -o %t && %run %t 2>&1
17+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=8192 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=131072 %s -o %t && %run %t 2>&1
18+
// RUN: %clangxx_asan -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=16384 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=131072 %s -o %t && %run %t 2>&1
19+
20+
// XFAIL: *
21+
22+
#include <assert.h>
23+
#include <pthread.h>
24+
#include <stdio.h>
25+
#include <stdlib.h>
26+
#include <string.h>
27+
28+
struct alignas(ALIGNMENT) big_object {
29+
int x;
30+
};
31+
32+
bool misaligned = false;
33+
34+
// Check whether the FakeStack frame is sufficiently aligned. Alignment can
35+
// happen by chance, so try this on many threads.
36+
void *Thread(void *unused) {
37+
big_object x;
38+
uint alignment = (unsigned long)&x % alignof(big_object);
39+
40+
if (alignment != 0)
41+
misaligned = true;
42+
43+
return nullptr;
44+
}
45+
46+
int main(int argc, char **argv) {
47+
pthread_attr_t attr;
48+
pthread_attr_init(&attr);
49+
#ifdef THREAD_STACK_SIZE
50+
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
51+
#endif
52+
53+
pthread_t threads[THREAD_COUNT];
54+
for (pthread_t &t : threads)
55+
pthread_create(&t, &attr, Thread, 0);
56+
57+
pthread_attr_destroy(&attr);
58+
59+
for (pthread_t &t : threads)
60+
pthread_join(t, 0);
61+
62+
if (misaligned) {
63+
printf("Test failed: not perfectly aligned\n");
64+
exit(1);
65+
}
66+
67+
return 0;
68+
}

0 commit comments

Comments
 (0)