69 lines · cpp
1// RUN: %clangxx_msan -O0 %s -o %t && %run %t2 3#include <assert.h>4#include <stdio.h>5#include <stdlib.h>6#include <ucontext.h>7#include <unistd.h>8 9#include <sanitizer/msan_interface.h>10 11namespace {12 13const int kStackSize = 1 << 20;14char fiber_stack[kStackSize] = {};15 16ucontext_t main_ctx;17ucontext_t fiber_ctx;18 19void fiber() {20 printf("%s: entering fiber\n", __FUNCTION__);21 22 // This fiber was switched into from main. Verify the details of main's stack23 // have been populated by MSAN.24 const void *previous_stack_bottom = nullptr;25 size_t previous_stack_size = 0;26 __msan_finish_switch_fiber(&previous_stack_bottom, &previous_stack_size);27 assert(previous_stack_bottom != nullptr);28 assert(previous_stack_size != 0);29 30 printf("%s: implicitly swapcontext to main\n", __FUNCTION__);31 __msan_start_switch_fiber(previous_stack_bottom, previous_stack_size);32}33 34} // namespace35 36// Set up a fiber, switch to it, and switch back, invoking __msan_*_switch_fiber37// functions along the way. At each step, validate the correct stack addresses and38// sizes are returned from those functions.39int main(int argc, char **argv) {40 if (getcontext(&fiber_ctx) == -1) {41 perror("getcontext");42 _exit(1);43 }44 fiber_ctx.uc_stack.ss_sp = fiber_stack;45 fiber_ctx.uc_stack.ss_size = sizeof(fiber_stack);46 fiber_ctx.uc_link = &main_ctx;47 makecontext(&fiber_ctx, fiber, 0);48 49 // Tell MSAN a fiber switch is about to occur, then perform the switch50 printf("%s: swapcontext to fiber\n", __FUNCTION__);51 __msan_start_switch_fiber(fiber_stack, kStackSize);52 if (swapcontext(&main_ctx, &fiber_ctx) == -1) {53 perror("swapcontext");54 _exit(1);55 }56 57 // The fiber switched to above now switched back here. Tell MSAN that switch58 // is complete and verify the fiber details return by MSAN are correct.59 const void *previous_stack_bottom = nullptr;60 size_t previous_stack_size = 0;61 __msan_finish_switch_fiber(&previous_stack_bottom, &previous_stack_size);62 assert(previous_stack_bottom == fiber_stack);63 assert(previous_stack_size == kStackSize);64 65 printf("%s: exiting\n", __FUNCTION__);66 67 return 0;68}69