diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-06-03 12:15:43 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2014-06-03 12:15:43 +0000 |
commit | bb2fc7e4bbe354f16a39b47c5fca77da0198acc9 (patch) | |
tree | 6966ae92cb7a88c96734c4d9be8744a75b57c283 /compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc | |
parent | 114a2bc9d25de52a1beacd18aff3a07929c64910 (diff) | |
download | bcm5719-llvm-bb2fc7e4bbe354f16a39b47c5fca77da0198acc9.tar.gz bcm5719-llvm-bb2fc7e4bbe354f16a39b47c5fca77da0198acc9.zip |
[sancov] Fix map update logic on Android.
dlopen()/dlclose() are not interceptable on Android,
so we update .sancov.map in module constructor callbacks.
llvm-svn: 210098
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc')
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc | 59 |
1 files changed, 31 insertions, 28 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc index e814c2e5e29..b3c8dc8916a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_mapping_libcdep.cc @@ -37,22 +37,16 @@ namespace __sanitizer { static const uptr kMaxNumberOfModules = 1 << 14; +static char *last_mapping; +static StaticSpinMutex mapping_mu; + void CovUpdateMapping() { if (!common_flags()->coverage || !common_flags()->coverage_direct) return; - int err; - InternalScopedString tmp_path(64 + - internal_strlen(common_flags()->coverage_dir)); - uptr res = internal_snprintf((char *)tmp_path.data(), tmp_path.size(), - "%s/%zd.sancov.map.tmp", common_flags()->coverage_dir, - internal_getpid()); - CHECK_LE(res, tmp_path.size()); - uptr map_fd = OpenFile(tmp_path.data(), true); - if (internal_iserror(map_fd)) { - Report(" Coverage: failed to open %s for writing\n", tmp_path.data()); - Die(); - } + SpinMutexLock l(&mapping_mu); + const uptr kMaxTextSize = 64 * 1024; + InternalScopedString text(kMaxTextSize); InternalScopedBuffer<char> modules_data(kMaxNumberOfModules * sizeof(LoadedModule)); LoadedModule *modules = (LoadedModule *)modules_data.data(); @@ -60,31 +54,40 @@ void CovUpdateMapping() { int n_modules = GetListOfModules(modules, kMaxNumberOfModules, /* filter */ 0); - InternalScopedString line(4096); - line.append("%d\n", sizeof(uptr) * 8); - res = internal_write(map_fd, line.data(), line.length()); - if (internal_iserror(res, &err)) { - Printf("sancov.map write failed: %d\n", err); - Die(); - } - line.clear(); - + text.append("%d\n", sizeof(uptr) * 8); for (int i = 0; i < n_modules; ++i) { char *module_name = StripModuleName(modules[i].full_name()); for (unsigned j = 0; j < modules[i].n_ranges(); ++j) { - line.append("%zx %zx %zx %s\n", modules[i].address_range_start(j), + text.append("%zx %zx %zx %s\n", modules[i].address_range_start(j), modules[i].address_range_end(j), modules[i].base_address(), module_name); - res = internal_write(map_fd, line.data(), line.length()); - if (internal_iserror(res, &err)) { - Printf("sancov.map write failed: %d\n", err); - Die(); - } - line.clear(); } InternalFree(module_name); } + // Do not write mapping if it is the same as the one we've wrote last time. + if (last_mapping && (internal_strcmp(last_mapping, text.data()) == 0)) return; + if (!last_mapping) last_mapping = (char *)InternalAlloc(kMaxTextSize); + internal_strncpy(last_mapping, text.data(), kMaxTextSize); + + int err; + InternalScopedString tmp_path(64 + + internal_strlen(common_flags()->coverage_dir)); + uptr res = internal_snprintf((char *)tmp_path.data(), tmp_path.size(), + "%s/%zd.sancov.map.tmp", common_flags()->coverage_dir, + internal_getpid()); + CHECK_LE(res, tmp_path.size()); + uptr map_fd = OpenFile(tmp_path.data(), true); + if (internal_iserror(map_fd)) { + Report(" Coverage: failed to open %s for writing\n", tmp_path.data()); + Die(); + } + + res = internal_write(map_fd, text.data(), text.length()); + if (internal_iserror(res, &err)) { + Printf("sancov.map write failed: %d\n", err); + Die(); + } internal_close(map_fd); InternalScopedString path(64 + internal_strlen(common_flags()->coverage_dir)); |