diff options
Diffstat (limited to 'libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc')
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc | 75 |
1 files changed, 59 insertions, 16 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc index 8e3a96f01e4..b4e42c72462 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc @@ -42,30 +42,49 @@ void FlushUnneededShadowMemory(uptr addr, uptr size) { madvise((void*)addr, size, MADV_DONTNEED); } -void DisableCoreDumper() { - struct rlimit nocore; - nocore.rlim_cur = 0; - nocore.rlim_max = 0; - setrlimit(RLIMIT_CORE, &nocore); +static rlim_t getlim(int res) { + rlimit rlim; + CHECK_EQ(0, getrlimit(res, &rlim)); + return rlim.rlim_cur; +} + +static void setlim(int res, rlim_t lim) { + // The following magic is to prevent clang from replacing it with memset. + volatile struct rlimit rlim; + rlim.rlim_cur = lim; + rlim.rlim_max = lim; + if (setrlimit(res, (struct rlimit*)&rlim)) { + Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno); + Die(); + } +} + +void DisableCoreDumperIfNecessary() { + if (common_flags()->disable_coredump) { + setlim(RLIMIT_CORE, 0); + } } bool StackSizeIsUnlimited() { - struct rlimit rlim; - CHECK_EQ(0, getrlimit(RLIMIT_STACK, &rlim)); - return ((uptr)rlim.rlim_cur == (uptr)-1); + rlim_t stack_size = getlim(RLIMIT_STACK); + return (stack_size == RLIM_INFINITY); } void SetStackSizeLimitInBytes(uptr limit) { - struct rlimit rlim; - rlim.rlim_cur = limit; - rlim.rlim_max = limit; - if (setrlimit(RLIMIT_STACK, &rlim)) { - Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno); - Die(); - } + setlim(RLIMIT_STACK, (rlim_t)limit); CHECK(!StackSizeIsUnlimited()); } +bool AddressSpaceIsUnlimited() { + rlim_t as_size = getlim(RLIMIT_AS); + return (as_size == RLIM_INFINITY); +} + +void SetAddressSpaceUnlimited() { + setlim(RLIMIT_AS, RLIM_INFINITY); + CHECK(AddressSpaceIsUnlimited()); +} + void SleepForSeconds(int seconds) { sleep(seconds); } @@ -127,7 +146,9 @@ static void MaybeInstallSigaction(int signum, struct sigaction sigact; internal_memset(&sigact, 0, sizeof(sigact)); sigact.sa_sigaction = (sa_sigaction_t)handler; - sigact.sa_flags = SA_SIGINFO; + // Do not block the signal from being received in that signal's handler. + // Clients are responsible for handling this correctly. + sigact.sa_flags = SA_SIGINFO | SA_NODEFER; if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK; CHECK_EQ(0, internal_sigaction(signum, &sigact, 0)); VReport(1, "Installed the sigaction for signal %d\n", signum); @@ -143,6 +164,28 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler) { } #endif // SANITIZER_GO +bool IsAccessibleMemoryRange(uptr beg, uptr size) { + uptr page_size = GetPageSizeCached(); + // Checking too large memory ranges is slow. + CHECK_LT(size, page_size * 10); + int sock_pair[2]; + if (pipe(sock_pair)) + return false; + uptr bytes_written = + internal_write(sock_pair[1], reinterpret_cast<void *>(beg), size); + int write_errno; + bool result; + if (internal_iserror(bytes_written, &write_errno)) { + CHECK_EQ(EFAULT, write_errno); + result = false; + } else { + result = (bytes_written == size); + } + internal_close(sock_pair[0]); + internal_close(sock_pair[1]); + return result; +} + } // namespace __sanitizer #endif // SANITIZER_POSIX |