1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- tsan_flags.cc -----------------------------------------------------===//
27ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
37ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//                     The LLVM Compiler Infrastructure
47ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
57ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is distributed under the University of Illinois Open Source
67ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// License. See LICENSE.TXT for details.
77ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
87ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===//
97ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector.
117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===//
137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
14f3be7069465c15b4c3f6719423d6075b0cf5a871Alexey Samsonov#include "sanitizer_common/sanitizer_flags.h"
15230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h"
167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_flags.h"
177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_rtl.h"
187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_mman.h"
197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanynamespace __tsan {
217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
227ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyFlags *flags() {
232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return &ctx->flags;
247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// Can be overriden in frontend.
2787dbdf5fd6cb9f1b90a0a97b7675bd8cad8a0264Dmitry Vyukov#ifdef TSAN_EXTERNAL_HOOKS
28f719b92eb175f34387ef05d1c4fc1d035b94e621Dmitry Vyukovextern "C" const char* __tsan_default_options();
2987dbdf5fd6cb9f1b90a0a97b7675bd8cad8a0264Dmitry Vyukov#else
302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesextern "C" SANITIZER_INTERFACE_ATTRIBUTE
312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesconst char *WEAK __tsan_default_options() {
32f719b92eb175f34387ef05d1c4fc1d035b94e621Dmitry Vyukov  return "";
33f719b92eb175f34387ef05d1c4fc1d035b94e621Dmitry Vyukov}
3487dbdf5fd6cb9f1b90a0a97b7675bd8cad8a0264Dmitry Vyukov#endif
357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
36f719b92eb175f34387ef05d1c4fc1d035b94e621Dmitry Vyukovstatic void ParseFlags(Flags *f, const char *env) {
372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->enable_annotations, "enable_annotations", "");
382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->suppress_equal_stacks, "suppress_equal_stacks", "");
392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->suppress_equal_addresses, "suppress_equal_addresses", "");
402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->suppress_java, "suppress_java", "");
412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->report_bugs, "report_bugs", "");
422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->report_thread_leaks, "report_thread_leaks", "");
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->report_destroy_locked, "report_destroy_locked", "");
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->report_mutex_bugs, "report_mutex_bugs", "");
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->report_signal_unsafe, "report_signal_unsafe", "");
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->report_atomic_races, "report_atomic_races", "");
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->force_seq_cst_atomics, "force_seq_cst_atomics", "");
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->suppressions, "suppressions", "");
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->print_suppressions, "print_suppressions", "");
502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->print_benign, "print_benign", "");
512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->exitcode, "exitcode", "");
522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->halt_on_error, "halt_on_error", "");
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->atexit_sleep_ms, "atexit_sleep_ms", "");
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->profile_memory, "profile_memory", "");
552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->flush_memory_ms, "flush_memory_ms", "");
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->flush_symbolizer_ms, "flush_symbolizer_ms", "");
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->memory_limit_mb, "memory_limit_mb", "");
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->stop_on_start, "stop_on_start", "");
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->running_on_valgrind, "running_on_valgrind", "");
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->history_size, "history_size", "");
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->io_sync, "io_sync", "");
622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->die_after_fork, "die_after_fork", "");
632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // DDFlags
652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack", "");
66f719b92eb175f34387ef05d1c4fc1d035b94e621Dmitry Vyukov}
67f719b92eb175f34387ef05d1c4fc1d035b94e621Dmitry Vyukov
687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid InitializeFlags(Flags *f, const char *env) {
69d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov  internal_memset(f, 0, sizeof(*f));
707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  // Default values.
727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  f->enable_annotations = true;
737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  f->suppress_equal_stacks = true;
747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  f->suppress_equal_addresses = true;
75543b94a5cd102c0795b44d78234d5458eed2c75eDmitry Vyukov  f->suppress_java = false;
768a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov  f->report_bugs = true;
777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  f->report_thread_leaks = true;
78fd513907acd3e2eaa02070edaa24df66648dc2acDmitry Vyukov  f->report_destroy_locked = true;
792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  f->report_mutex_bugs = true;
807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  f->report_signal_unsafe = true;
81ddbe2be9dc8b8eb7d40017c077e8392daf708510Dmitry Vyukov  f->report_atomic_races = true;
827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  f->force_seq_cst_atomics = false;
83b7b6b1cd9df0c954b1f890fcebf373db984923b3Dmitry Vyukov  f->suppressions = "";
84f754eb501d6bd163fff6747716b7703fe45be4b8Dmitry Vyukov  f->print_suppressions = false;
850fd908cf5a555483633e2d9703932bde18009682Dmitry Vyukov  f->print_benign = false;
867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  f->exitcode = 66;
87dbac0a4a41f405d10e3dcad3597fe08986605289Dmitry Vyukov  f->halt_on_error = false;
887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  f->atexit_sleep_ms = 1000;
8926127735454fddae3495794f38189d57dde6510fDmitry Vyukov  f->profile_memory = "";
90adfb65039646774f0f063b538f8fb0aec021f42bDmitry Vyukov  f->flush_memory_ms = 0;
91f63dde3594da0dba4c8039f0cb3a4196a76f1affDmitry Vyukov  f->flush_symbolizer_ms = 5000;
9292b54796149a8b5995fa49c43f43b709b83c5644Dmitry Vyukov  f->memory_limit_mb = 0;
93adfb65039646774f0f063b538f8fb0aec021f42bDmitry Vyukov  f->stop_on_start = false;
9424567d409cca096b950574fa4b19aa4c2c67a1f0Dmitry Vyukov  f->running_on_valgrind = false;
953fb70e333087ffac19517ad6559fcba9e43ac5caDmitry Vyukov  f->history_size = kGoMode ? 1 : 2;  // There are a lot of goroutines in Go.
96e3178e8fab67e77165978006928228f9be2ce30dDmitry Vyukov  f->io_sync = 1;
972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  f->die_after_fork = true;
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // DDFlags
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  f->second_deadlock_stack = false;
10124567d409cca096b950574fa4b19aa4c2c67a1f0Dmitry Vyukov
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SetCommonFlagsDefaults(f);
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Override some common flags defaults.
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  f->allow_addr2line = true;
1055d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  f->detect_deadlocks = true;
1066866dba92ac842fc513ba339ba849a953ffb7507Dmitry Vyukov
1077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  // Let a frontend override.
108f719b92eb175f34387ef05d1c4fc1d035b94e621Dmitry Vyukov  ParseFlags(f, __tsan_default_options());
1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseCommonFlagsFromString(f, __tsan_default_options());
1107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  // Override from command line.
111f719b92eb175f34387ef05d1c4fc1d035b94e621Dmitry Vyukov  ParseFlags(f, env);
1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ParseCommonFlagsFromString(f, env);
1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // Copy back to common flags.
1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  *common_flags() = *f;
1168a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov
11755c7947a742aa72530eef52d902e60e5571ac3cfAlexey Samsonov  // Sanity check.
1188a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov  if (!f->report_bugs) {
1198a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov    f->report_thread_leaks = false;
1208a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov    f->report_destroy_locked = false;
1218a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov    f->report_signal_unsafe = false;
1228a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov  }
123d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov
1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (f->help) PrintFlagDescriptions();
1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
126d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov  if (f->history_size < 0 || f->history_size > 7) {
127d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov    Printf("ThreadSanitizer: incorrect value for history_size"
128d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov           " (must be [0..7])\n");
129d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov    Die();
130d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov  }
131e3178e8fab67e77165978006928228f9be2ce30dDmitry Vyukov
132e3178e8fab67e77165978006928228f9be2ce30dDmitry Vyukov  if (f->io_sync < 0 || f->io_sync > 2) {
133e3178e8fab67e77165978006928228f9be2ce30dDmitry Vyukov    Printf("ThreadSanitizer: incorrect value for io_sync"
134e3178e8fab67e77165978006928228f9be2ce30dDmitry Vyukov           " (must be [0..2])\n");
135e3178e8fab67e77165978006928228f9be2ce30dDmitry Vyukov    Die();
136e3178e8fab67e77165978006928228f9be2ce30dDmitry Vyukov  }
1377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}  // namespace __tsan
140