sanitizer_posix.cc revision 24e13723f8477d8c42ab8b2a7f4f69fc089842f1
11f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===-- sanitizer_posix.cc ------------------------------------------------===//
21f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//
31f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//                     The LLVM Compiler Infrastructure
41f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//
51f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// This file is distributed under the University of Illinois Open Source
61f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// License. See LICENSE.TXT for details.
71f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//
81f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===----------------------------------------------------------------------===//
91f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//
101f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// This file is shared between AddressSanitizer and ThreadSanitizer
111f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// run-time libraries and implements POSIX-specific functions from
121f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// sanitizer_libc.h.
131f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===----------------------------------------------------------------------===//
1424e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov
1524e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#include "sanitizer_platform.h"
1624e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if SANITIZER_LINUX || SANITIZER_MAC
171f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
18230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_common.h"
191f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include "sanitizer_libc.h"
20be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include "sanitizer_procmaps.h"
211f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
220aa04b3f432bc55e7c116d5280685ee3f243be8eKostya Serebryany#include <errno.h>
23fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov#include <pthread.h>
241f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include <stdarg.h>
251f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include <stdio.h>
26fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov#include <stdlib.h>
270aa04b3f432bc55e7c116d5280685ee3f243be8eKostya Serebryany#include <string.h>
28230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <sys/mman.h>
29be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include <sys/resource.h>
30be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include <sys/time.h>
31230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <sys/types.h>
32230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <unistd.h>
331f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
341f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovnamespace __sanitizer {
351f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
36be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov// ------------- sanitizer_common.h
37f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryanyuptr GetPageSize() {
38f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  return sysconf(_SC_PAGESIZE);
39f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany}
40f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany
41f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryanyuptr GetMmapGranularity() {
42f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  return GetPageSize();
43f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany}
44be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov
45230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovint GetPid() {
46230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  return getpid();
47230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
48230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
490fa691b7ec97d8c3948a637d6263822ed4e738f7Alexey Samsonovu32 GetUid() {
500fa691b7ec97d8c3948a637d6263822ed4e738f7Alexey Samsonov  return getuid();
510fa691b7ec97d8c3948a637d6263822ed4e738f7Alexey Samsonov}
520fa691b7ec97d8c3948a637d6263822ed4e738f7Alexey Samsonov
53fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovuptr GetThreadSelf() {
54fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  return (uptr)pthread_self();
55fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
56fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
57a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonovvoid *MmapOrDie(uptr size, const char *mem_type) {
58f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  size = RoundUpTo(size, GetPageSizeCached());
59230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  void *res = internal_mmap(0, size,
60230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov                            PROT_READ | PROT_WRITE,
61230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov                            MAP_PRIVATE | MAP_ANON, -1, 0);
62230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  if (res == (void*)-1) {
63e8216fd93f6f8980965197a1779b6f54441255caKostya Serebryany    static int recursion_count;
64e8216fd93f6f8980965197a1779b6f54441255caKostya Serebryany    if (recursion_count) {
65e8216fd93f6f8980965197a1779b6f54441255caKostya Serebryany      // The Report() and CHECK calls below may call mmap recursively and fail.
66e8216fd93f6f8980965197a1779b6f54441255caKostya Serebryany      // If we went into recursion, just die.
67c8490e2a09cd415cc58fc8f3b63bebddce61c82dDmitry Vyukov      RawWrite("ERROR: Failed to mmap\n");
68e8216fd93f6f8980965197a1779b6f54441255caKostya Serebryany      Die();
69e8216fd93f6f8980965197a1779b6f54441255caKostya Serebryany    }
70e8216fd93f6f8980965197a1779b6f54441255caKostya Serebryany    recursion_count++;
71a8d37a05f05341c60fe4508d79286a1b17aa3dc2Alexander Potapenko    Report("ERROR: %s failed to allocate 0x%zx (%zd) bytes of %s: %d\n",
72a8d37a05f05341c60fe4508d79286a1b17aa3dc2Alexander Potapenko           SanitizerToolName, size, size, mem_type, errno);
730aa04b3f432bc55e7c116d5280685ee3f243be8eKostya Serebryany    DumpProcessMap();
74a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov    CHECK("unable to mmap" && 0);
75230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  }
76230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  return res;
77230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
78230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
79230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovvoid UnmapOrDie(void *addr, uptr size) {
80230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  if (!addr || !size) return;
81230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  int res = internal_munmap(addr, size);
82230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  if (res != 0) {
83859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany    Report("ERROR: %s failed to deallocate 0x%zx (%zd) bytes at address %p\n",
84859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany           SanitizerToolName, size, size, addr);
85a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov    CHECK("unable to unmap" && 0);
86230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  }
87230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
88230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
89f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *MmapFixedNoReserve(uptr fixed_addr, uptr size) {
90f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  uptr PageSize = GetPageSizeCached();
91f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  void *p = internal_mmap((void*)(fixed_addr & ~(PageSize - 1)),
92f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany      RoundUpTo(size, PageSize),
936b641c5e63be45a03f96346886d27c4b4135ddafDmitry Vyukov      PROT_READ | PROT_WRITE,
946b641c5e63be45a03f96346886d27c4b4135ddafDmitry Vyukov      MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
956b641c5e63be45a03f96346886d27c4b4135ddafDmitry Vyukov      -1, 0);
966b641c5e63be45a03f96346886d27c4b4135ddafDmitry Vyukov  if (p == (void*)-1)
97859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany    Report("ERROR: "
98859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany           "%s failed to allocate 0x%zx (%zd) bytes at address %p (%d)\n",
99859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany           SanitizerToolName, size, size, fixed_addr, errno);
100785a7c07c9bd2d4463b30a8539a716f020139551Dmitry Vyukov  return p;
101f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov}
102f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov
1039bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryanyvoid *MmapFixedOrDie(uptr fixed_addr, uptr size) {
1049bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany  uptr PageSize = GetPageSizeCached();
1059bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany  void *p = internal_mmap((void*)(fixed_addr & ~(PageSize - 1)),
1069bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany      RoundUpTo(size, PageSize),
1079bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany      PROT_READ | PROT_WRITE,
1089bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany      MAP_PRIVATE | MAP_ANON | MAP_FIXED,
1099bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany      -1, 0);
1109bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany  if (p == (void*)-1) {
111859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany    Report("ERROR:"
112859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany           " %s failed to allocate 0x%zx (%zd) bytes at address %p (%d)\n",
113859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany           SanitizerToolName, size, size, fixed_addr, errno);
1149bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany    CHECK("unable to mmap" && 0);
1159bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany  }
1169bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany  return p;
1179bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany}
1189bfe78f7d4f9af3cdacb4d34bd7b4fead27dcda5Kostya Serebryany
119f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *Mprotect(uptr fixed_addr, uptr size) {
120f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov  return internal_mmap((void*)fixed_addr, size,
121f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov                       PROT_NONE,
122f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov                       MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
12384902c716abf9ba0dc6e7b1cd0522759f29b3179Alexey Samsonov                       -1, 0);
124f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov}
125f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov
126a54aec8ca2e372b1a841d605d53cab5e336aeb03Kostya Serebryanyvoid FlushUnneededShadowMemory(uptr addr, uptr size) {
127a54aec8ca2e372b1a841d605d53cab5e336aeb03Kostya Serebryany  madvise((void*)addr, size, MADV_DONTNEED);
128a54aec8ca2e372b1a841d605d53cab5e336aeb03Kostya Serebryany}
129a54aec8ca2e372b1a841d605d53cab5e336aeb03Kostya Serebryany
130a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonovvoid *MapFileToMemory(const char *file_name, uptr *buff_size) {
131ee7cc4454421a176d23442382afd9a01d36e7ad4Alexey Samsonov  fd_t fd = OpenFile(file_name, false);
132a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  CHECK_NE(fd, kInvalidFd);
133a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  uptr fsize = internal_filesize(fd);
134a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  CHECK_NE(fsize, (uptr)-1);
135a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  CHECK_GT(fsize, 0);
136f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  *buff_size = RoundUpTo(fsize, GetPageSizeCached());
137a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  void *map = internal_mmap(0, *buff_size, PROT_READ, MAP_PRIVATE, fd, 0);
138a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov  return (map == MAP_FAILED) ? 0 : map;
139a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov}
140a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov
141a68633fb76208137ccb807914df52758ee5ca6f0Alexey Samsonov
142dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonovstatic inline bool IntervalsAreSeparate(uptr start1, uptr end1,
143dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov                                        uptr start2, uptr end2) {
144dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  CHECK(start1 <= end1);
145dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  CHECK(start2 <= end2);
146dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  return (end1 < start2) || (end2 < start1);
147dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov}
148dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov
149dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// FIXME: this is thread-unsafe, but should not cause problems most of the time.
150dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// When the shadow is mapped only a single thread usually exists (plus maybe
151dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// several worker threads on Mac, which aren't expected to map big chunks of
152dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// memory).
153dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonovbool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
154e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov  MemoryMappingLayout procmaps;
155dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  uptr start, end;
156dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  while (procmaps.Next(&start, &end,
15745717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov                       /*offset*/0, /*filename*/0, /*filename_size*/0,
15845717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov                       /*protection*/0)) {
159dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov    if (!IntervalsAreSeparate(start, end, range_start, range_end))
160dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov      return false;
161dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  }
162dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  return true;
163dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov}
164dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov
165be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DumpProcessMap() {
166e1f5dac9296df08ff83ae5fca51ce4da995b55cfAlexey Samsonov  MemoryMappingLayout proc_maps;
167be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  uptr start, end;
168be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  const sptr kBufSize = 4095;
169b84ee029ada36949c30c57c5f701191783990574Alexey Samsonov  char *filename = (char*)MmapOrDie(kBufSize, __FUNCTION__);
170be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  Report("Process memory map follows:\n");
171be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  while (proc_maps.Next(&start, &end, /* file_offset */0,
17245717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov                        filename, kBufSize, /* protection */0)) {
173be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov    Printf("\t%p-%p\t%s\n", (void*)start, (void*)end, filename);
174be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  }
175be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  Report("End of process memory map.\n");
176b84ee029ada36949c30c57c5f701191783990574Alexey Samsonov  UnmapOrDie(filename, kBufSize);
177be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov}
178be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov
1790969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovconst char *GetPwd() {
1800969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov  return GetEnv("PWD");
1810969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov}
1820969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov
183be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DisableCoreDumper() {
184be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  struct rlimit nocore;
185be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  nocore.rlim_cur = 0;
186be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  nocore.rlim_max = 0;
187be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov  setrlimit(RLIMIT_CORE, &nocore);
188be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov}
189be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov
190d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonovbool StackSizeIsUnlimited() {
191d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov  struct rlimit rlim;
192d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov  CHECK_EQ(0, getrlimit(RLIMIT_STACK, &rlim));
193d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov  return (rlim.rlim_cur == (uptr)-1);
194d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov}
195d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov
196d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonovvoid SetStackSizeLimitInBytes(uptr limit) {
197d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov  struct rlimit rlim;
198d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov  rlim.rlim_cur = limit;
199d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov  rlim.rlim_max = limit;
200d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov  if (setrlimit(RLIMIT_STACK, &rlim)) {
201859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany    Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno);
202d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov    Die();
203d698edc4f74a17048eef3342a9fa42b3ebba802aDmitry Vyukov  }
204d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov  CHECK(!StackSizeIsUnlimited());
205d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov}
206d7e5bb4043adf4756e6f8cfe0f5a3165b185474dAlexey Samsonov
207fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid SleepForSeconds(int seconds) {
208fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  sleep(seconds);
209fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
210fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
2110969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovvoid SleepForMillis(int millis) {
2120969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov  usleep(millis * 1000);
2130969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov}
2140969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov
215fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Abort() {
216fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  abort();
217fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
218fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
219fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovint Atexit(void (*function)(void)) {
220b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#ifndef SANITIZER_GO
221fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov  return atexit(function);
222b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#else
223b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  return 0;
224b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#endif
225fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov}
226fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov
22784d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonovint internal_isatty(fd_t fd) {
22884d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  return isatty(fd);
22984d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov}
23084d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov
2311f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov}  // namespace __sanitizer
2321f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
2331f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#endif  // __linux__ || __APPLE_
234