diff options
Diffstat (limited to 'lib/sanitizer_common/sanitizer_common.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.cc | 156 |
1 files changed, 67 insertions, 89 deletions
diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc index 9b41a3aa0af9..79fcbb1183f9 100644 --- a/lib/sanitizer_common/sanitizer_common.cc +++ b/lib/sanitizer_common/sanitizer_common.cc @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common.h" +#include "sanitizer_allocator_interface.h" #include "sanitizer_allocator_internal.h" #include "sanitizer_flags.h" #include "sanitizer_libc.h" @@ -24,13 +25,7 @@ namespace __sanitizer { const char *SanitizerToolName = "SanitizerTool"; atomic_uint32_t current_verbosity; - -uptr GetPageSizeCached() { - static uptr PageSize; - if (!PageSize) - PageSize = GetPageSize(); - return PageSize; -} +uptr PageSizeCached; StaticSpinMutex report_file_mu; ReportFile report_file = {&report_file_mu, kStderrFd, "", "", 0}; @@ -105,64 +100,6 @@ uptr stoptheworld_tracer_pid = 0; // writing to the same log file. uptr stoptheworld_tracer_ppid = 0; -static const int kMaxNumOfInternalDieCallbacks = 5; -static DieCallbackType InternalDieCallbacks[kMaxNumOfInternalDieCallbacks]; - -bool AddDieCallback(DieCallbackType callback) { - for (int i = 0; i < kMaxNumOfInternalDieCallbacks; i++) { - if (InternalDieCallbacks[i] == nullptr) { - InternalDieCallbacks[i] = callback; - return true; - } - } - return false; -} - -bool RemoveDieCallback(DieCallbackType callback) { - for (int i = 0; i < kMaxNumOfInternalDieCallbacks; i++) { - if (InternalDieCallbacks[i] == callback) { - internal_memmove(&InternalDieCallbacks[i], &InternalDieCallbacks[i + 1], - sizeof(InternalDieCallbacks[0]) * - (kMaxNumOfInternalDieCallbacks - i - 1)); - InternalDieCallbacks[kMaxNumOfInternalDieCallbacks - 1] = nullptr; - return true; - } - } - return false; -} - -static DieCallbackType UserDieCallback; -void SetUserDieCallback(DieCallbackType callback) { - UserDieCallback = callback; -} - -void NORETURN Die() { - if (UserDieCallback) - UserDieCallback(); - for (int i = kMaxNumOfInternalDieCallbacks - 1; i >= 0; i--) { - if (InternalDieCallbacks[i]) - InternalDieCallbacks[i](); - } - if (common_flags()->abort_on_error) - Abort(); - internal__exit(common_flags()->exitcode); -} - -static CheckFailedCallbackType CheckFailedCallback; -void SetCheckFailedCallback(CheckFailedCallbackType callback) { - CheckFailedCallback = callback; -} - -void NORETURN CheckFailed(const char *file, int line, const char *cond, - u64 v1, u64 v2) { - if (CheckFailedCallback) { - CheckFailedCallback(file, line, cond, v1, v2); - } - Report("Sanitizer CHECK failed: %s:%d %s (%lld, %lld)\n", file, line, cond, - v1, v2); - Die(); -} - void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type, const char *mmap_type, error_t err, bool raw_report) { @@ -230,27 +167,6 @@ void SortArray(uptr *array, uptr size) { InternalSort<uptr*, UptrComparisonFunction>(&array, size, CompareLess); } -// We want to map a chunk of address space aligned to 'alignment'. -// We do it by maping a bit more and then unmaping redundant pieces. -// We probably can do it with fewer syscalls in some OS-dependent way. -void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) { -// uptr PageSize = GetPageSizeCached(); - CHECK(IsPowerOfTwo(size)); - CHECK(IsPowerOfTwo(alignment)); - uptr map_size = size + alignment; - uptr map_res = (uptr)MmapOrDie(map_size, mem_type); - uptr map_end = map_res + map_size; - uptr res = map_res; - if (res & (alignment - 1)) // Not aligned. - res = (map_res + alignment) & ~(alignment - 1); - uptr end = res + size; - if (res != map_res) - UnmapOrDie((void*)map_res, res - map_res); - if (end != map_end) - UnmapOrDie((void*)end, map_end - end); - return (void*)res; -} - const char *StripPathPrefix(const char *filepath, const char *strip_path_prefix) { if (!filepath) return nullptr; @@ -355,9 +271,8 @@ void LoadedModule::addAddressRange(uptr beg, uptr end, bool executable) { } bool LoadedModule::containsAddress(uptr address) const { - for (Iterator iter = ranges(); iter.hasNext();) { - const AddressRange *r = iter.next(); - if (r->beg <= address && address < r->end) + for (const AddressRange &r : ranges()) { + if (r.beg <= address && address < r.end) return true; } return false; @@ -424,6 +339,10 @@ bool TemplateMatch(const char *templ, const char *str) { static const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':'; char *FindPathToBinary(const char *name) { + if (FileExists(name)) { + return internal_strdup(name); + } + const char *path = GetEnv("PATH"); if (!path) return nullptr; @@ -488,6 +407,53 @@ uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len) { return name_len; } +void PrintCmdline() { + char **argv = GetArgv(); + if (!argv) return; + Printf("\nCommand: "); + for (uptr i = 0; argv[i]; ++i) + Printf("%s ", argv[i]); + Printf("\n\n"); +} + +// Malloc hooks. +static const int kMaxMallocFreeHooks = 5; +struct MallocFreeHook { + void (*malloc_hook)(const void *, uptr); + void (*free_hook)(const void *); +}; + +static MallocFreeHook MFHooks[kMaxMallocFreeHooks]; + +void RunMallocHooks(const void *ptr, uptr size) { + for (int i = 0; i < kMaxMallocFreeHooks; i++) { + auto hook = MFHooks[i].malloc_hook; + if (!hook) return; + hook(ptr, size); + } +} + +void RunFreeHooks(const void *ptr) { + for (int i = 0; i < kMaxMallocFreeHooks; i++) { + auto hook = MFHooks[i].free_hook; + if (!hook) return; + hook(ptr); + } +} + +static int InstallMallocFreeHooks(void (*malloc_hook)(const void *, uptr), + void (*free_hook)(const void *)) { + if (!malloc_hook || !free_hook) return 0; + for (int i = 0; i < kMaxMallocFreeHooks; i++) { + if (MFHooks[i].malloc_hook == nullptr) { + MFHooks[i].malloc_hook = malloc_hook; + MFHooks[i].free_hook = free_hook; + return i + 1; + } + } + return 0; +} + } // namespace __sanitizer using namespace __sanitizer; // NOLINT @@ -497,6 +463,11 @@ void __sanitizer_set_report_path(const char *path) { report_file.SetReportPath(path); } +void __sanitizer_set_report_fd(void *fd) { + report_file.fd = (fd_t)reinterpret_cast<uptr>(fd); + report_file.fd_pid = internal_getpid(); +} + void __sanitizer_report_error_summary(const char *error_summary) { Printf("%s\n", error_summary); } @@ -505,4 +476,11 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_set_death_callback(void (*callback)(void)) { SetUserDieCallback(callback); } + +SANITIZER_INTERFACE_ATTRIBUTE +int __sanitizer_install_malloc_and_free_hooks(void (*malloc_hook)(const void *, + uptr), + void (*free_hook)(const void *)) { + return InstallMallocFreeHooks(malloc_hook, free_hook); +} } // extern "C" |