15b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//===-- tsan_platform_mac.cc ----------------------------------------------===//
25b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//
35b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//                     The LLVM Compiler Infrastructure
45b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//
55b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov// This file is distributed under the University of Illinois Open Source
65b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov// License. See LICENSE.TXT for details.
75b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//
85b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//===----------------------------------------------------------------------===//
95b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//
105b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov// This file is a part of ThreadSanitizer (TSan), a race detector.
115b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//
126fbecdd97512bd7d9ccef130e99650d446b50444Alexey Samsonov// Mac-specific code.
135b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov//===----------------------------------------------------------------------===//
145b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
1524e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#include "sanitizer_common/sanitizer_platform.h"
1630e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov#if SANITIZER_MAC
173f24d6386cea638f5d4bc1694d1de02917988bcdDmitry Vyukov
185b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include "sanitizer_common/sanitizer_common.h"
195b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include "sanitizer_common/sanitizer_libc.h"
205b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include "sanitizer_common/sanitizer_procmaps.h"
215b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include "tsan_platform.h"
225b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include "tsan_rtl.h"
235b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include "tsan_flags.h"
245b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
255b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <pthread.h>
265b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <signal.h>
275b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <stdio.h>
285b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <stdlib.h>
295b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <string.h>
305b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <stdarg.h>
315b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <sys/mman.h>
325b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <sys/syscall.h>
335b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <sys/time.h>
345b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <sys/types.h>
355b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <sys/resource.h>
365b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <sys/stat.h>
375b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <unistd.h>
385b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <errno.h>
395b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#include <sched.h>
405b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
415b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukovnamespace __tsan {
425b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesuptr GetShadowMemoryConsumption() {
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return 0;
455b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov}
465b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid FlushShadowMemory() {
485b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov}
495b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
505d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesvoid WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) {
515b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov}
525b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesuptr GetRSS() {
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return 0;
555b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov}
565b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
57a05fcc1e3e045097f2f1a20798cbe038bbb1d6a9Dmitry Vyukov#ifndef TSAN_GO
585b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukovvoid InitializeShadowMemory() {
595b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  uptr shadow = (uptr)MmapFixedNoReserve(kLinuxShadowBeg,
605b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov    kLinuxShadowEnd - kLinuxShadowBeg);
615b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  if (shadow != kLinuxShadowBeg) {
62b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov    Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");
63b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov    Printf("FATAL: Make sure to compile with -fPIE and "
64b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov           "to link with -pie.\n");
655b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov    Die();
665b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  }
675b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  DPrintf("kLinuxShadow %zx-%zx (%zuGB)\n",
685b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov      kLinuxShadowBeg, kLinuxShadowEnd,
695b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov      (kLinuxShadowEnd - kLinuxShadowBeg) >> 30);
705b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  DPrintf("kLinuxAppMem %zx-%zx (%zuGB)\n",
715b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov      kLinuxAppMemBeg, kLinuxAppMemEnd,
725b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov      (kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);
735b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov}
74a05fcc1e3e045097f2f1a20798cbe038bbb1d6a9Dmitry Vyukov#endif
755b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
765b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukovconst char *InitializePlatform() {
775b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  void *p = 0;
785b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  if (sizeof(p) == 8) {
795b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov    // Disable core dumps, dumping of 16TB usually takes a bit long.
805b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov    // The following magic is to prevent clang from replacing it with memset.
815b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov    volatile rlimit lim;
825b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov    lim.rlim_cur = 0;
835b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov    lim.rlim_max = 0;
845b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov    setrlimit(RLIMIT_CORE, (rlimit*)&lim);
855b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  }
865b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
87ce44055cdde85554aa9d18f8a7166bf5df6f9bb3Kostya Serebryany  return GetEnv(kTsanOptionsEnv);
885b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov}
895b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
905b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukovvoid FinalizePlatform() {
915b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov  fflush(0);
925b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov}
935b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef TSAN_GO
952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    void *abstime), void *c, void *m, void *abstime,
972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    void(*cleanup)(void *arg), void *arg) {
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // pthread_cleanup_push/pop are hardcore macros mess.
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  // We can't intercept nor call them w/o including pthread.h.
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  int res;
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  pthread_cleanup_push(cleanup, arg);
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  res = fn(c, m, abstime);
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  pthread_cleanup_pop(0);
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return res;
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1085b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov}  // namespace __tsan
1093f24d6386cea638f5d4bc1694d1de02917988bcdDmitry Vyukov
11030e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov#endif  // SANITIZER_MAC
111