Skip to content

[asan] Add test case for alignment of FakeStack frames #152889

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

Merged
merged 9 commits into from
Aug 11, 2025
68 changes: 68 additions & 0 deletions compiler-rt/test/asan/TestCases/fakestack_alignment.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Regression test 1:
// This deterministically fails: when the stack size is 1<<16, FakeStack's
// GetFrame() is out of alignment, because SizeRequiredForFlags(16) == 2K.
// 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

// Regression test 2:
// The FakeStack frame is not guaranteed to be aligned, but alignment can
// happen by chance, so try this on many threads.
// 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
// 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

// Extra tests:
// 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
// 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
// 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
// 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
// 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
// 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

// XFAIL: *

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct alignas(ALIGNMENT) big_object {
int x;
};

bool misaligned = false;

// Check whether the FakeStack frame is sufficiently aligned. Alignment can
// happen by chance, so try this on many threads.
void *Thread(void *unused) {
big_object x;
uint alignment = (unsigned long)&x % alignof(big_object);

if (alignment != 0)
misaligned = true;

return nullptr;
}

int main(int argc, char **argv) {
pthread_attr_t attr;
pthread_attr_init(&attr);
#ifdef THREAD_STACK_SIZE
pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
#endif

pthread_t threads[THREAD_COUNT];
for (pthread_t &t : threads)
pthread_create(&t, &attr, Thread, 0);

pthread_attr_destroy(&attr);

for (pthread_t &t : threads)
pthread_join(t, 0);

if (misaligned) {
printf("Test failed: not perfectly aligned\n");
exit(1);
}

return 0;
}
Loading