brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 21743bf Raw
131 lines · cpp
1// RUN: %clangxx_asan -g %if !MSVC %{ -Wno-deprecated-declarations %} %s -o %t2// RUN: %env_asan_opts=exitcode=42 %run %t | FileCheck %s3 4// Android doesn't have spawn.h or posix_spawn.5// UNSUPPORTED: android6 7// CHECK: got expected 42 exit code8 9#include <stdlib.h>10#include <stdio.h>11 12#ifdef _WIN3213#include <windows.h>14 15int spawn_child(char **argv) {16  // Set an environment variable to tell the child process to interrupt17  // itself.18  if (!SetEnvironmentVariableW(L"CRASH_FOR_TEST", L"1")) {19    printf("SetEnvironmentVariableW failed (0x%8lx).\n", GetLastError());20    fflush(stdout);21    exit(1);22  }23 24  STARTUPINFOW si;25  memset(&si, 0, sizeof(si));26  si.cb = sizeof(si);27 28  PROCESS_INFORMATION pi;29  memset(&pi, 0, sizeof(pi));30 31  if (!CreateProcessW(nullptr,           // No module name (use command line)32                      GetCommandLineW(), // Command line33                      nullptr,           // Process handle not inheritable34                      nullptr,           // Thread handle not inheritable35                      TRUE,              // Set handle inheritance to TRUE36                      0,                 // No flags37                      nullptr,           // Use parent's environment block38                      nullptr,           // Use parent's starting directory39                      &si, &pi)) {40    printf("CreateProcess failed (0x%08lx).\n", GetLastError());41    fflush(stdout);42    exit(1);43  }44 45  WaitForSingleObject(pi.hProcess, INFINITE);46 47  DWORD exit_code;48  if (!GetExitCodeProcess(pi.hProcess, &exit_code)) {49    printf("GetExitCodeProcess failed (0x%08lx).\n", GetLastError());50    fflush(stdout);51    exit(1);52  }53 54  CloseHandle(pi.hProcess);55  CloseHandle(pi.hThread);56 57  return exit_code;58}59#else60#include <spawn.h>61#include <errno.h>62#include <sys/wait.h>63 64#if defined(__APPLE__)65#include <TargetConditionals.h>66#endif67 68#if defined(__APPLE__) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)69#define USE_NSGETENVIRON 170#else71#define USE_NSGETENVIRON 072#endif73 74#if !USE_NSGETENVIRON75extern char **environ;76#else77#include <crt_externs.h> // _NSGetEnviron78#endif79 80int spawn_child(char **argv) {81  setenv("CRASH_FOR_TEST", "1", 1);82 83#if !USE_NSGETENVIRON84  char **envp = environ;85#else86  char **envp = *_NSGetEnviron();87#endif88 89  pid_t pid;90  int err = posix_spawn(&pid, argv[0], nullptr, nullptr, argv, envp);91  if (err) {92    printf("posix_spawn failed: %d\n", err);93    fflush(stdout);94    exit(1);95  }96 97  // Wait until the child exits.98  int status;99  pid_t wait_result_pid;100  do {101    wait_result_pid = waitpid(pid, &status, 0);102  } while (wait_result_pid == -1 && errno == EINTR);103 104  if (wait_result_pid != pid || !WIFEXITED(status)) {105    printf("error in waitpid\n");106    fflush(stdout);107    exit(1);108  }109 110  // Return the exit status.111  return WEXITSTATUS(status);112}113#endif114 115int main(int argc, char **argv) {116  int r = 0;117  if (getenv("CRASH_FOR_TEST")) {118    // Generate an asan report to test ASAN_OPTIONS=exitcode=42119    int *p = new int;120    delete p;121    r = *p;122  } else {123    int exit_code = spawn_child(argv);124    if (exit_code == 42) {125      printf("got expected 42 exit code\n");126      fflush(stdout);127    }128  }129  return r;130}131