forked from OSchip/llvm-project
				
			[sanitizer] Intercept backtrace, backtrace_symbols.
llvm-svn: 191516
This commit is contained in:
		
							parent
							
								
									a515070eb3
								
							
						
					
					
						commit
						01781722b6
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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                   ";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -364,6 +364,8 @@ enum StatType {
 | 
			
		|||
  StatInt_sigfillset,
 | 
			
		||||
  StatInt_sigpending,
 | 
			
		||||
  StatInt_sigprocmask,
 | 
			
		||||
  StatInt_backtrace,
 | 
			
		||||
  StatInt_backtrace_symbols,
 | 
			
		||||
 | 
			
		||||
  // Dynamic annotations.
 | 
			
		||||
  StatAnnotation,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue