[sanitizer] Intercept backtrace, backtrace_symbols.

llvm-svn: 191516
This commit is contained in:
Evgeniy Stepanov 2013-09-27 12:40:23 +00:00
parent a515070eb3
commit 01781722b6
5 changed files with 63 additions and 1 deletions

View File

@ -0,0 +1,26 @@
// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t
#include <assert.h>
#include <execinfo.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
__attribute__((noinline))
void f() {
void *buf[10];
int sz = backtrace(buf, sizeof(buf) / sizeof(*buf));
assert(sz > 0);
for (int i = 0; i < sz; ++i)
if (!buf[i])
exit(1);
char **s = backtrace_symbols(buf, sz);
assert(s > 0);
for (int i = 0; i < sz; ++i)
printf("%d\n", strlen(s[i]));
}
int main(void) {
f();
return 0;
}

View File

@ -2114,6 +2114,36 @@ INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
#define INIT_SIGPROCMASK
#endif
#if SANITIZER_INTERCEPT_BACKTRACE
INTERCEPTOR(int, backtrace, void **buffer, int size) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
int res = REAL(backtrace)(buffer, size);
if (res && buffer)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
return res;
}
INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
if (buffer && size)
COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
char ** res = REAL(backtrace_symbols)(buffer, size);
if (res && size) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
for (int i = 0; i < size; ++i)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
}
return res;
}
#define INIT_BACKTRACE \
INTERCEPT_FUNCTION(backtrace); \
INTERCEPT_FUNCTION(backtrace_symbols);
#else
#define INIT_BACKTRACE
#endif
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCMP; \
INIT_STRNCMP; \
@ -2189,4 +2219,5 @@ INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
INIT_SIGTIMEDWAIT; \
INIT_SIGSETOPS; \
INIT_SIGPENDING; \
INIT_SIGPROCMASK;
INIT_SIGPROCMASK; \
INIT_BACKTRACE;

View File

@ -125,5 +125,6 @@
# define SANITIZER_INTERCEPT_SIGSETOPS SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_SIGPENDING SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_SIGPROCMASK SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_BACKTRACE SI_LINUX_NOT_ANDROID
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

View File

@ -369,6 +369,8 @@ void StatOutput(u64 *stat) {
name[StatInt_sigfillset] = " sigfillset ";
name[StatInt_sigpending] = " sigpending ";
name[StatInt_sigprocmask] = " sigprocmask ";
name[StatInt_backtrace] = " backtrace ";
name[StatInt_backtrace_symbols] = " backtrace_symbols ";
name[StatAnnotation] = "Dynamic annotations ";
name[StatAnnotateHappensBefore] = " HappensBefore ";

View File

@ -364,6 +364,8 @@ enum StatType {
StatInt_sigfillset,
StatInt_sigpending,
StatInt_sigprocmask,
StatInt_backtrace,
StatInt_backtrace_symbols,
// Dynamic annotations.
StatAnnotation,