brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.2 KiB · ddf35a2 Raw
106 lines · cpp
1// Test that chained origins are fork-safe.2// Run a number of threads that create new chained origins, then fork3// and verify that origin reads do not deadlock in the child process.4//5// RUN: %clangxx_dfsan %s -o %t6// RUN: %run %t 2>&1 | FileCheck %s7//8// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 %s -o %t9// RUN: env DFSAN_OPTIONS=store_context_size=1000,origin_history_size=0,origin_history_per_stack_limit=0 %run %t 2>&1 | FileCheck %s10 11#include <assert.h>12#include <errno.h>13#include <pthread.h>14#include <signal.h>15#include <stdio.h>16#include <stdlib.h>17#include <sys/time.h>18#include <sys/types.h>19#include <sys/wait.h>20#include <unistd.h>21 22#include <sanitizer/dfsan_interface.h>23 24int done;25 26void copy_labels_thread2() {27  volatile int x = 0;28  volatile int v = 0;29  dfsan_set_label(8, (void *)&x, sizeof(x));30  while (true) {31    v = x;32    x = v;33    if (__atomic_load_n(&done, __ATOMIC_RELAXED))34      return;35  }36}37 38void copy_labels_thread1(int level) {39  if (!level)40    copy_labels_thread2();41  else42    copy_labels_thread1(level - 1);43}44 45void *copy_labels_thread(void *id) {46  copy_labels_thread1((long)id);47  return 0;48}49 50// Run through stackdepot in the child process.51// If any of the hash table cells are locked, this may deadlock.52void child() {53  volatile int x = 0;54  volatile int v = 0;55  dfsan_set_label(16, (void *)&x, sizeof(x));56  for (int i = 0; i < 10000; ++i) {57    v = x;58    x = v;59  }60  write(2, "done\n", 5);61}62 63void test() {64  const int kThreads = 10;65  pthread_t t[kThreads];66  for (int i = 0; i < kThreads; ++i)67    pthread_create(&t[i], NULL, copy_labels_thread, (void *)(long)i);68  usleep(100000);69  pid_t pid = fork();70  if (pid) {71    // parent72    __atomic_store_n(&done, 1, __ATOMIC_RELAXED);73    pid_t p;74    while ((p = wait(NULL)) == -1) {75    }76  } else {77    // child78    child();79  }80}81 82int main() {83  const int kChildren = 20;84  for (int i = 0; i < kChildren; ++i) {85    pid_t pid = fork();86    assert(dfsan_get_label(pid) == 0);87    if (pid) {88      // parent89    } else {90      test();91      exit(0);92    }93  }94 95  for (int i = 0; i < kChildren; ++i) {96    pid_t p;97    while ((p = wait(NULL)) == -1) {98    }99  }100 101  return 0;102}103 104// Expect 20 (== kChildren) "done" messages.105// CHECK-COUNT-20: done106