| // Regression test 1: |
| // When the stack size is 1<<16, SizeRequiredForFlags(16) == 2KB. This forces |
| // FakeStack's GetFrame() out of alignment if the FakeStack isn't padded. |
| // RUN: %clangxx_asan -pthread -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: |
| // Check that the FakeStack frame is aligned, beyond the typical 4KB page |
| // alignment. Alignment can happen by chance, so try this on many threads. |
| // RUN: %clangxx_asan -pthread -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 -pthread -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 -pthread -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 -pthread -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 -pthread -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 -pthread -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 -pthread -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 -pthread -fsanitize-address-use-after-return=always -O0 -DALIGNMENT=16384 -DTHREAD_COUNT=32 -DTHREAD_STACK_SIZE=131072 %s -o %t && %run %t 2>&1 |
| |
| // UNSUPPORTED: android |
| |
| #include <assert.h> |
| #include <pthread.h> |
| #include <stdint.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; |
| uintptr_t alignment = (uintptr_t)&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; |
| } |