tsan_flags.cc revision adfb65039646774f0f063b538f8fb0aec021f42b
17ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===-- tsan_flags.cc -------------------------------------------*- C++ -*-===// 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 147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_flags.h" 157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_rtl.h" 167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_mman.h" 177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanynamespace __tsan { 197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void Flag(const char *env, bool *flag, const char *name); 217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void Flag(const char *env, int *flag, const char *name); 227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void Flag(const char *env, const char **flag, const char *name); 237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 247ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyFlags *flags() { 257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return &CTX()->flags; 267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// Can be overriden in frontend. 297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid WEAK OverrideFlags(Flags *f) { 307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany (void)f; 317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid InitializeFlags(Flags *f, const char *env) { 347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany internal_memset(f, 0, sizeof(*f)); 357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // Default values. 377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->enable_annotations = true; 387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->suppress_equal_stacks = true; 397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->suppress_equal_addresses = true; 407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->report_thread_leaks = true; 417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->report_signal_unsafe = true; 427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->force_seq_cst_atomics = false; 43b7b6b1cd9df0c954b1f890fcebf373db984923b3Dmitry Vyukov f->strip_path_prefix = ""; 44b7b6b1cd9df0c954b1f890fcebf373db984923b3Dmitry Vyukov f->suppressions = ""; 457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->exitcode = 66; 467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->log_fileno = 2; 477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->atexit_sleep_ms = 1000; 487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f->verbosity = 0; 4926127735454fddae3495794f38189d57dde6510fDmitry Vyukov f->profile_memory = ""; 50adfb65039646774f0f063b538f8fb0aec021f42bDmitry Vyukov f->flush_memory_ms = 0; 51adfb65039646774f0f063b538f8fb0aec021f42bDmitry Vyukov f->stop_on_start = false; 527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // Let a frontend override. 547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany OverrideFlags(f); 557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // Override from command line. 577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->enable_annotations, "enable_annotations"); 587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->suppress_equal_stacks, "suppress_equal_stacks"); 597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->suppress_equal_addresses, "suppress_equal_addresses"); 607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->report_thread_leaks, "report_thread_leaks"); 617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->report_signal_unsafe, "report_signal_unsafe"); 627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->force_seq_cst_atomics, "force_seq_cst_atomics"); 637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->strip_path_prefix, "strip_path_prefix"); 647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->suppressions, "suppressions"); 657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->exitcode, "exitcode"); 667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->log_fileno, "log_fileno"); 677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->atexit_sleep_ms, "atexit_sleep_ms"); 687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Flag(env, &f->verbosity, "verbosity"); 6926127735454fddae3495794f38189d57dde6510fDmitry Vyukov Flag(env, &f->profile_memory, "profile_memory"); 70adfb65039646774f0f063b538f8fb0aec021f42bDmitry Vyukov Flag(env, &f->flush_memory_ms, "flush_memory_ms"); 71adfb65039646774f0f063b538f8fb0aec021f42bDmitry Vyukov Flag(env, &f->stop_on_start, "stop_on_start"); 727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const char *GetFlagValue(const char *env, const char *name, 757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char **end) { 767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (env == 0) 777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return *end = 0; 787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *pos = internal_strstr(env, name); 797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pos == 0) 807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return *end = 0; 817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pos += internal_strlen(name); 827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pos[0] != '=') 837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return *end = pos; 847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pos += 1; 857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pos[0] == '"') { 867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pos += 1; 877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *end = internal_strchr(pos, '"'); 887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } else if (pos[0] == '\'') { 897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pos += 1; 907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *end = internal_strchr(pos, '\''); 917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } else { 927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *end = internal_strchr(pos, ' '); 937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (*end == 0) 957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *end = pos + internal_strlen(pos); 967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return pos; 977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void Flag(const char *env, bool *flag, const char *name) { 1007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *end = 0; 1017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *val = GetFlagValue(env, name, &end); 1027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (val == 0) 1037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 1047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int len = end - val; 1057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (len == 1 && val[0] == '0') 1067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *flag = false; 1077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany else if (len == 1 && val[0] == '1') 1087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *flag = true; 1097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 1107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void Flag(const char *env, int *flag, const char *name) { 1127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *end = 0; 1137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *val = GetFlagValue(env, name, &end); 1147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (val == 0) 1157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 1167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany bool minus = false; 1177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (val != end && val[0] == '-') { 1187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany minus = true; 1197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany val += 1; 1207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 1217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int v = 0; 1227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany for (; val != end; val++) { 1237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (val[0] < '0' || val[0] > '9') 1247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany break; 1257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany v = v * 10 + val[0] - '0'; 1267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 1277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (minus) 1287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany v = -v; 1297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *flag = v; 1307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 1317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void Flag(const char *env, const char **flag, const char *name) { 1337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *end = 0; 1347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *val = GetFlagValue(env, name, &end); 1357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (val == 0) 1367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 1377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int len = end - val; 1387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany char *f = (char*)internal_alloc(MBlockFlag, len + 1); 1397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany internal_memcpy(f, val, len); 1407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f[len] = 0; 1417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *flag = f; 1427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 1437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} // namespace __tsan 145