Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce stats and stats_client libraries.
This is part of a new statistics gathering feature for the sanitizers. See clang/docs/SanitizerStats.rst for further info and docs. Differential Revision: http://reviews.llvm.org/D16176 llvm-svn: 257972
- Loading branch information
Showing
13 changed files
with
466 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
include_directories(..) | ||
|
||
add_custom_target(stats) | ||
|
||
if(APPLE) | ||
set(STATS_LIB_FLAVOR SHARED) | ||
else() | ||
set(STATS_LIB_FLAVOR STATIC) | ||
endif() | ||
|
||
add_compiler_rt_runtime(clang_rt.stats | ||
${STATS_LIB_FLAVOR} | ||
ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH} | ||
OS ${SANITIZER_COMMON_SUPPORTED_OS} | ||
SOURCES stats.cc | ||
OBJECT_LIBS RTSanitizerCommon | ||
RTSanitizerCommonLibc | ||
CFLAGS ${SANITIZER_COMMON_CFLAGS} | ||
PARENT_TARGET stats) | ||
|
||
add_compiler_rt_runtime(clang_rt.stats_client | ||
STATIC | ||
ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH} | ||
OS ${SANITIZER_COMMON_SUPPORTED_OS} | ||
SOURCES stats_client.cc | ||
CFLAGS ${SANITIZER_COMMON_CFLAGS} | ||
PARENT_TARGET stats) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
//===-- stats.cc ----------------------------------------------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Sanitizer statistics gathering. Manages statistics for a process and is | ||
// responsible for writing the report file. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "sanitizer_common/sanitizer_common.h" | ||
#include "sanitizer_common/sanitizer_internal_defs.h" | ||
#if SANITIZER_POSIX | ||
#include "sanitizer_common/sanitizer_posix.h" | ||
#endif | ||
#include "sanitizer_common/sanitizer_symbolizer.h" | ||
#include "stats/stats.h" | ||
#if SANITIZER_POSIX | ||
#include <signal.h> | ||
#endif | ||
|
||
using namespace __sanitizer; | ||
|
||
namespace { | ||
|
||
InternalMmapVectorNoCtor<StatModule **> modules; | ||
StaticSpinMutex modules_mutex; | ||
|
||
fd_t stats_fd; | ||
|
||
void WriteLE(fd_t fd, uptr val) { | ||
char chars[sizeof(uptr)]; | ||
for (unsigned i = 0; i != sizeof(uptr); ++i) { | ||
chars[i] = val >> (i * 8); | ||
} | ||
WriteToFile(fd, chars, sizeof(uptr)); | ||
} | ||
|
||
void OpenStatsFile(const char *path_env) { | ||
InternalScopedBuffer<char> path(kMaxPathLength); | ||
SubstituteForFlagValue(path_env, path.data(), kMaxPathLength); | ||
|
||
error_t err; | ||
stats_fd = OpenFile(path.data(), WrOnly, &err); | ||
if (stats_fd == kInvalidFd) { | ||
Report("stats: failed to open %s for writing (reason: %d)\n", path.data(), | ||
err); | ||
return; | ||
} | ||
char sizeof_uptr = sizeof(uptr); | ||
WriteToFile(stats_fd, &sizeof_uptr, 1); | ||
} | ||
|
||
void WriteModuleReport(StatModule **smodp) { | ||
CHECK(smodp); | ||
const char *path_env = GetEnv("SANITIZER_STATS_PATH"); | ||
if (!path_env || stats_fd == kInvalidFd) | ||
return; | ||
if (!stats_fd) | ||
OpenStatsFile(path_env); | ||
LoadedModule *mod = Symbolizer::GetOrInit()->FindModuleForAddress( | ||
reinterpret_cast<uptr>(smodp)); | ||
WriteToFile(stats_fd, mod->full_name(), | ||
internal_strlen(mod->full_name()) + 1); | ||
for (StatModule *smod = *smodp; smod; smod = smod->next) { | ||
for (u32 i = 0; i != smod->size; ++i) { | ||
StatInfo *s = &smod->infos[i]; | ||
if (!s->addr) | ||
continue; | ||
WriteLE(stats_fd, s->addr - mod->base_address()); | ||
WriteLE(stats_fd, s->data); | ||
} | ||
} | ||
WriteLE(stats_fd, 0); | ||
WriteLE(stats_fd, 0); | ||
} | ||
|
||
} // namespace | ||
|
||
extern "C" | ||
SANITIZER_INTERFACE_ATTRIBUTE | ||
unsigned __sanitizer_stats_register(StatModule **mod) { | ||
SpinMutexLock l(&modules_mutex); | ||
modules.push_back(mod); | ||
return modules.size() - 1; | ||
} | ||
|
||
extern "C" | ||
SANITIZER_INTERFACE_ATTRIBUTE | ||
void __sanitizer_stats_unregister(unsigned index) { | ||
SpinMutexLock l(&modules_mutex); | ||
WriteModuleReport(modules[index]); | ||
modules[index] = 0; | ||
} | ||
|
||
namespace { | ||
|
||
void WriteFullReport() { | ||
SpinMutexLock l(&modules_mutex); | ||
for (StatModule **mod : modules) { | ||
if (!mod) | ||
continue; | ||
WriteModuleReport(mod); | ||
} | ||
if (stats_fd != 0 && stats_fd != kInvalidFd) { | ||
CloseFile(stats_fd); | ||
stats_fd = kInvalidFd; | ||
} | ||
} | ||
|
||
#if SANITIZER_POSIX | ||
void USR2Handler(int sig) { | ||
WriteFullReport(); | ||
} | ||
#endif | ||
|
||
struct WriteReportOnExitOrSignal { | ||
WriteReportOnExitOrSignal() { | ||
#if SANITIZER_POSIX | ||
struct sigaction sigact; | ||
internal_memset(&sigact, 0, sizeof(sigact)); | ||
sigact.sa_handler = USR2Handler; | ||
internal_sigaction(SIGUSR2, &sigact, nullptr); | ||
#endif | ||
} | ||
|
||
~WriteReportOnExitOrSignal() { | ||
WriteFullReport(); | ||
} | ||
} wr; | ||
|
||
} // namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
//===-- stats.h -------------------------------------------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Data definitions for sanitizer statistics gathering. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef SANITIZER_STATS_STATS_H | ||
#define SANITIZER_STATS_STATS_H | ||
|
||
#include "sanitizer_common/sanitizer_internal_defs.h" | ||
|
||
namespace __sanitizer { | ||
|
||
// Number of bits in data that are used for the sanitizer kind. Needs to match | ||
// llvm::kSanitizerStatKindBits in | ||
// llvm/include/llvm/Transforms/Utils/SanitizerStats.h | ||
enum { kKindBits = 3 }; | ||
|
||
struct StatInfo { | ||
uptr addr; | ||
uptr data; | ||
}; | ||
|
||
struct StatModule { | ||
StatModule *next; | ||
u32 size; | ||
StatInfo infos[1]; | ||
}; | ||
|
||
inline uptr CountFromData(uptr data) { | ||
return data & ((1ull << (sizeof(uptr) * 8 - kKindBits)) - 1); | ||
} | ||
|
||
} | ||
|
||
#endif |
Oops, something went wrong.