forked from OSchip/llvm-project
				
			[ASan] add new ASan option 'strip_path_prefix' to remove useless prefices from filenames in stack traces
llvm-svn: 161321
This commit is contained in:
		
							parent
							
								
									8f6dd3537c
								
							
						
					
					
						commit
						0295edbfd5
					
				| 
						 | 
				
			
			@ -87,6 +87,8 @@ struct Flags {
 | 
			
		|||
  // By default, disable core dumper on 64-bit - it makes little sense
 | 
			
		||||
  // to dump 16T+ core.
 | 
			
		||||
  bool disable_core;
 | 
			
		||||
  // Strips this prefix from file paths in error reports.
 | 
			
		||||
  const char *strip_path_prefix;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Flags *flags();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ void Die() {
 | 
			
		|||
    while (1) { }
 | 
			
		||||
  }
 | 
			
		||||
  if (flags()->sleep_before_dying) {
 | 
			
		||||
    Report("Sleeping for %zd second(s)\n", flags()->sleep_before_dying);
 | 
			
		||||
    Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
 | 
			
		||||
    SleepForSeconds(flags()->sleep_before_dying);
 | 
			
		||||
  }
 | 
			
		||||
  if (flags()->unmap_shadow_on_exit)
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +96,7 @@ static void ParseFlagsFromString(Flags *f, const char *str) {
 | 
			
		|||
  ParseFlag(str, &f->abort_on_error, "abort_on_error");
 | 
			
		||||
  ParseFlag(str, &f->atexit, "atexit");
 | 
			
		||||
  ParseFlag(str, &f->disable_core, "disable_core");
 | 
			
		||||
  ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
| 
						 | 
				
			
			@ -128,6 +129,7 @@ void InitializeFlags(Flags *f, const char *env) {
 | 
			
		|||
  f->abort_on_error = false;
 | 
			
		||||
  f->atexit = false;
 | 
			
		||||
  f->disable_core = (__WORDSIZE == 64);
 | 
			
		||||
  f->strip_path_prefix = "";
 | 
			
		||||
 | 
			
		||||
  // Override from user-specified string.
 | 
			
		||||
  ParseFlagsFromString(f, __asan_default_options());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,13 @@ ASAN_USE_EXTERNAL_SYMBOLIZER(const void *pc, char *out, int out_size);
 | 
			
		|||
 | 
			
		||||
namespace __asan {
 | 
			
		||||
 | 
			
		||||
static const char *StripPathPrefix(const char *filepath) {
 | 
			
		||||
  const char *path_prefix = flags()->strip_path_prefix;
 | 
			
		||||
  if (filepath == internal_strstr(filepath, path_prefix))
 | 
			
		||||
    return filepath + internal_strlen(path_prefix);
 | 
			
		||||
  return filepath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ----------------------- AsanStackTrace ----------------------------- {{{1
 | 
			
		||||
// PCs in stack traces are actually the return addresses, that is,
 | 
			
		||||
// addresses of the next instructions after the call. That's why we
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +53,10 @@ void AsanStackTrace::PrintStack(uptr *addr, uptr size) {
 | 
			
		|||
      pc = patch_pc(pc);
 | 
			
		||||
    char buff[4096];
 | 
			
		||||
    ASAN_USE_EXTERNAL_SYMBOLIZER((void*)pc, buff, sizeof(buff));
 | 
			
		||||
    AsanPrintf("  #%zu 0x%zx %s\n", i, pc, buff);
 | 
			
		||||
    // We can't know anything about the string returned by external
 | 
			
		||||
    // symbolizer, but if it starts with filename, try to strip path prefix
 | 
			
		||||
    // from it.
 | 
			
		||||
    AsanPrintf("  #%zu 0x%zx %s\n", i, pc, StripPathPrefix(buff));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,9 +82,11 @@ void AsanStackTrace::PrintStack(uptr *addr, uptr size) {
 | 
			
		|||
          AsanPrintf(" in %s", info.function);
 | 
			
		||||
        }
 | 
			
		||||
        if (info.file) {
 | 
			
		||||
          AsanPrintf(" %s:%d:%d", info.file, info.line, info.column);
 | 
			
		||||
          AsanPrintf(" %s:%d:%d", StripPathPrefix(info.file), info.line,
 | 
			
		||||
                                  info.column);
 | 
			
		||||
        } else if (info.module) {
 | 
			
		||||
          AsanPrintf(" (%s+0x%zx)", info.module, info.module_offset);
 | 
			
		||||
          AsanPrintf(" (%s+0x%zx)", StripPathPrefix(info.module),
 | 
			
		||||
                                    info.module_offset);
 | 
			
		||||
        }
 | 
			
		||||
        AsanPrintf("\n");
 | 
			
		||||
        info.Clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -85,8 +97,8 @@ void AsanStackTrace::PrintStack(uptr *addr, uptr size) {
 | 
			
		|||
      char filename[4096];
 | 
			
		||||
      if (proc_maps.GetObjectNameAndOffset(pc, &offset,
 | 
			
		||||
                                           filename, sizeof(filename))) {
 | 
			
		||||
        AsanPrintf("    #%zu 0x%zx (%s+0x%zx)\n", frame_num, pc, filename,
 | 
			
		||||
                                                  offset);
 | 
			
		||||
        AsanPrintf("    #%zu 0x%zx (%s+0x%zx)\n",
 | 
			
		||||
                   frame_num, pc, StripPathPrefix(filename), offset);
 | 
			
		||||
      } else {
 | 
			
		||||
        AsanPrintf("    #%zu 0x%zx\n", frame_num, pc);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,13 @@ check_program a.out $C_TEST.c CHECKSLEEP
 | 
			
		|||
export ASAN_OPTIONS=""
 | 
			
		||||
rm ./a.out
 | 
			
		||||
 | 
			
		||||
echo "Checking strip_path_prefix option"
 | 
			
		||||
$CC -g -faddress-sanitizer -O2 $C_TEST.c
 | 
			
		||||
export ASAN_OPTIONS="strip_path_prefix='/'"
 | 
			
		||||
./a.out 2>&1 | $FILE_CHECK $C_TEST.c --check-prefix=CHECKSTRIP
 | 
			
		||||
export ASAN_OPTIONS=""
 | 
			
		||||
rm ./a.out
 | 
			
		||||
 | 
			
		||||
# FIXME: some tests do not need to be ran for all the combinations of arch
 | 
			
		||||
# and optimization mode.
 | 
			
		||||
for t in  *.cc; do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,3 +7,4 @@ int main() {
 | 
			
		|||
 | 
			
		||||
// CHECK: heap-use-after-free
 | 
			
		||||
// CHECKSLEEP: Sleeping for 1 second
 | 
			
		||||
// CHECKSTRIP-NOT: #0 0x{{.*}} ({{[/].*}})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue