blob: efa42bff6b5a7cfc0830403e569e37e800425488 [file] [log] [blame]
Peter Collingbourneb64d0b12015-06-15 21:08:47 +00001// RUN: %clang_safestack %s -pthread -o %t
Vlad Tsyrklevicha24ecc32018-08-09 22:56:41 +00002// RUN: %run %t 0
3// RUN: not --crash %run %t 1
Peter Collingbourneb64d0b12015-06-15 21:08:47 +00004
Vlad Tsyrklevicha24ecc32018-08-09 22:56:41 +00005// Test unsafe stack deallocation. Unsafe stacks are not deallocated immediately
6// at thread exit. They are deallocated by following exiting threads.
Peter Collingbourneb64d0b12015-06-15 21:08:47 +00007
8#include <stdlib.h>
9#include <string.h>
10#include <pthread.h>
11
12enum { kBufferSize = (1 << 15) };
13
Vlad Tsyrklevicha24ecc32018-08-09 22:56:41 +000014void *start(void *ptr)
Peter Collingbourneb64d0b12015-06-15 21:08:47 +000015{
16 char buffer[kBufferSize];
17 return buffer;
18}
19
20int main(int argc, char **argv)
21{
Vlad Tsyrklevicha24ecc32018-08-09 22:56:41 +000022 int arg = atoi(argv[1]);
Peter Collingbourneb64d0b12015-06-15 21:08:47 +000023
Vlad Tsyrklevicha24ecc32018-08-09 22:56:41 +000024 pthread_t t1, t2;
25 char *t1_buffer = NULL;
26
27 if (pthread_create(&t1, NULL, start, NULL))
Peter Collingbourneb64d0b12015-06-15 21:08:47 +000028 abort();
Vlad Tsyrklevicha24ecc32018-08-09 22:56:41 +000029 if (pthread_join(t1, &t1_buffer))
30 abort();
31
32 memset(t1_buffer, 0, kBufferSize);
33
34 if (arg == 0)
35 return 0;
36
37 if (pthread_create(&t2, NULL, start, NULL))
38 abort();
39 // Second thread destructor cleans up the first thread's stack.
40 if (pthread_join(t2, NULL))
Peter Collingbourneb64d0b12015-06-15 21:08:47 +000041 abort();
42
43 // should segfault here
Vlad Tsyrklevicha24ecc32018-08-09 22:56:41 +000044 memset(t1_buffer, 0, kBufferSize);
Peter Collingbourneb64d0b12015-06-15 21:08:47 +000045 return 0;
46}