brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · efaaef8 Raw
160 lines · cpp
1//===-- tsan_flags.cpp ----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer (TSan), a race detector.10//11//===----------------------------------------------------------------------===//12 13#include "tsan_flags.h"14 15#include "sanitizer_common/sanitizer_flag_parser.h"16#include "sanitizer_common/sanitizer_flags.h"17#include "sanitizer_common/sanitizer_libc.h"18#include "tsan_interface.h"19#include "tsan_mman.h"20#include "tsan_rtl.h"21#include "ubsan/ubsan_flags.h"22 23#if SANITIZER_APPLE && !SANITIZER_GO24namespace __sanitizer {25 26template <>27inline bool FlagHandler<LockDuringWriteSetting>::Parse(const char *value) {28  if (internal_strcmp(value, "on") == 0) {29    *t_ = kLockDuringAllWrites;30    return true;31  }32  if (internal_strcmp(value, "disable_for_current_process") == 0) {33    *t_ = kNoLockDuringWritesCurrentProcess;34    return true;35  }36  if (internal_strcmp(value, "disable_for_all_processes") == 0) {37    *t_ = kNoLockDuringWritesAllProcesses;38    return true;39  }40  Printf("ERROR: Invalid value for signal handler option: '%s'\n", value);41  return false;42}43 44template <>45inline bool FlagHandler<LockDuringWriteSetting>::Format(char *buffer,46                                                        uptr size) {47  switch (*t_) {48    case kLockDuringAllWrites:49      return FormatString(buffer, size, "on");50    case kNoLockDuringWritesCurrentProcess:51      return FormatString(buffer, size, "disable_for_current_process");52    case kNoLockDuringWritesAllProcesses:53      return FormatString(buffer, size, "disable_for_all_processes");54  }55}56 57}  // namespace __sanitizer58#endif  // SANITIZER_APPLE && !SANITIZER_GO59 60namespace __tsan {61 62// Can be overriden in frontend.63#ifdef TSAN_EXTERNAL_HOOKS64extern "C" const char *__tsan_default_options();65#else66SANITIZER_WEAK_DEFAULT_IMPL67const char *__tsan_default_options() {68  return "";69}70#endif71 72void Flags::SetDefaults() {73#define TSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;74#include "tsan_flags.inc"75#undef TSAN_FLAG76  // DDFlags77  second_deadlock_stack = false;78}79 80void RegisterTsanFlags(FlagParser *parser, Flags *f) {81#define TSAN_FLAG(Type, Name, DefaultValue, Description) \82  RegisterFlag(parser, #Name, Description, &f->Name);83#include "tsan_flags.inc"84#undef TSAN_FLAG85  // DDFlags86  RegisterFlag(parser, "second_deadlock_stack",87      "Report where each mutex is locked in deadlock reports",88      &f->second_deadlock_stack);89}90 91void InitializeFlags(Flags *f, const char *env, const char *env_option_name) {92  SetCommonFlagsDefaults();93  {94    // Override some common flags defaults.95    CommonFlags cf;96    cf.CopyFrom(*common_flags());97    cf.external_symbolizer_path = GetEnv("TSAN_SYMBOLIZER_PATH");98    cf.allow_addr2line = true;99    if (SANITIZER_GO) {100      // Does not work as expected for Go: runtime handles SIGABRT and crashes.101      cf.abort_on_error = false;102      // Go does not have mutexes.103      cf.detect_deadlocks = false;104    }105    cf.print_suppressions = false;106    cf.stack_trace_format = "    #%n %f %S %M";107    cf.exitcode = 66;108    cf.intercept_tls_get_addr = true;109    OverrideCommonFlags(cf);110  }111 112  f->SetDefaults();113 114  FlagParser parser;115  RegisterTsanFlags(&parser, f);116  RegisterCommonFlags(&parser);117 118#if TSAN_CONTAINS_UBSAN119  __ubsan::Flags *uf = __ubsan::flags();120  uf->SetDefaults();121 122  FlagParser ubsan_parser;123  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);124  RegisterCommonFlags(&ubsan_parser);125#endif126 127  // Let a frontend override.128  parser.ParseString(__tsan_default_options());129#if TSAN_CONTAINS_UBSAN130  const char *ubsan_default_options = __ubsan_default_options();131  ubsan_parser.ParseString(ubsan_default_options);132#endif133  // Override from command line.134  parser.ParseString(env, env_option_name);135#if TSAN_CONTAINS_UBSAN136  ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");137#endif138 139  // Check flags.140  if (!f->report_bugs) {141    f->report_thread_leaks = false;142    f->report_destroy_locked = false;143    f->report_signal_unsafe = false;144  }145 146  InitializeCommonFlags();147 148  if (Verbosity()) ReportUnrecognizedFlags();149 150  if (common_flags()->help) parser.PrintFlagDescriptions();151 152  if (f->io_sync < 0 || f->io_sync > 2) {153    Printf("ThreadSanitizer: incorrect value for io_sync"154           " (must be [0..2])\n");155    Die();156  }157}158 159}  // namespace __tsan160