]>
git.proxmox.com Git - rustc.git/blob - src/libcompiler_builtins/compiler-rt/test/asan/TestCases/Linux/swapcontext_test.cc
1 // Check that ASan plays well with easy cases of makecontext/swapcontext.
3 // RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
4 // RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
5 // RUN: %clangxx_asan -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
6 // RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
8 // This test is too sublte to try on non-x86 arch for now.
9 // REQUIRES: x86-target-arch
15 ucontext_t orig_context
;
16 ucontext_t child_context
;
18 const int kStackSize
= 1 << 20;
20 __attribute__((noinline
))
25 __attribute__((noinline
))
26 void ThrowAndCatch() {
30 printf("ThrowAndCatch: %d\n", a
);
34 void Child(int mode
) {
35 char x
[32] = {0}; // Stack gets poisoned.
36 printf("Child: %p\n", x
);
37 ThrowAndCatch(); // Simulate __asan_handle_no_return().
38 // (a) Do nothing, just return to parent function.
39 // (b) Jump into the original function. Stack remains poisoned unless we do
42 if (swapcontext(&child_context
, &orig_context
) < 0) {
43 perror("swapcontext");
49 int Run(int arg
, int mode
, char *child_stack
) {
50 printf("Child stack: %p\n", child_stack
);
51 // Setup child context.
52 getcontext(&child_context
);
53 child_context
.uc_stack
.ss_sp
= child_stack
;
54 child_context
.uc_stack
.ss_size
= kStackSize
/ 2;
56 child_context
.uc_link
= &orig_context
;
58 makecontext(&child_context
, (void (*)())Child
, 1, mode
);
59 if (swapcontext(&orig_context
, &child_context
) < 0) {
60 perror("swapcontext");
63 // Touch childs's stack to make sure it's unpoisoned.
64 for (int i
= 0; i
< kStackSize
; i
++) {
67 return child_stack
[arg
];
70 int main(int argc
, char **argv
) {
71 char stack
[kStackSize
+ 1];
72 // CHECK: WARNING: ASan doesn't fully support makecontext/swapcontext
74 ret
+= Run(argc
- 1, 0, stack
);
75 printf("Test1 passed\n");
76 // CHECK: Test1 passed
77 ret
+= Run(argc
- 1, 1, stack
);
78 printf("Test2 passed\n");
79 // CHECK: Test2 passed
80 char *heap
= new char[kStackSize
+ 1];
81 ret
+= Run(argc
- 1, 0, heap
);
82 printf("Test3 passed\n");
83 // CHECK: Test3 passed
84 ret
+= Run(argc
- 1, 1, heap
);
85 printf("Test4 passed\n");
86 // CHECK: Test4 passed