[llvm] r320415 - ASAN: Provide reliable debug info for local variables at -O0.

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 11 12:43:22 PST 2017


Author: adrian
Date: Mon Dec 11 12:43:21 2017
New Revision: 320415

URL: http://llvm.org/viewvc/llvm-project?rev=320415&view=rev
Log:
ASAN: Provide reliable debug info for local variables at -O0.

The function stack poisioner conditionally stores local variables
either in an alloca or in malloc'ated memory, which has the
unfortunate side-effect, that the actual address of the variable is
only materialized when the variable is accessed, which means that
those variables are mostly invisible to the debugger even when
compiling without optimizations.

This patch stores the address of the local stack base into an alloca,
which can be referred to by the debug info and is available throughout
the function. This adds one extra pointer-sized alloca to each stack
frame (but mem2reg can optimize it away again when optimizations are
enabled, yielding roughly the same debug info quality as before in
optimized code).

rdar://problem/30433661

Differential Revision: https://reviews.llvm.org/D41034

Added:
    llvm/trunk/test/Instrumentation/AddressSanitizer/local_stack_base.ll
Modified:
    llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
    llvm/trunk/test/DebugInfo/Generic/block-asan.ll
    llvm/trunk/test/Instrumentation/AddressSanitizer/basic.ll
    llvm/trunk/test/Instrumentation/AddressSanitizer/debug_info.ll
    llvm/trunk/test/Instrumentation/AddressSanitizer/stack_layout.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=320415&r1=320414&r2=320415&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Mon Dec 11 12:43:21 2017
@@ -2869,8 +2869,12 @@ void FunctionStackPoisoner::processStati
 
   Value *FakeStack;
   Value *LocalStackBase;
+  Value *LocalStackBaseAlloca;
+  bool Deref;
 
   if (DoStackMalloc) {
+    LocalStackBaseAlloca =
+        IRB.CreateAlloca(IntptrTy, nullptr, "asan_local_stack_base");
     // void *FakeStack = __asan_option_detect_stack_use_after_return
     //     ? __asan_stack_malloc_N(LocalStackSize)
     //     : nullptr;
@@ -2901,25 +2905,31 @@ void FunctionStackPoisoner::processStati
     IRBIf.SetCurrentDebugLocation(EntryDebugLocation);
     Value *AllocaValue =
         DoDynamicAlloca ? createAllocaForLayout(IRBIf, L, true) : StaticAlloca;
+
     IRB.SetInsertPoint(InsBefore);
     IRB.SetCurrentDebugLocation(EntryDebugLocation);
     LocalStackBase = createPHI(IRB, NoFakeStack, AllocaValue, Term, FakeStack);
+    IRB.SetCurrentDebugLocation(EntryDebugLocation);
+    IRB.CreateStore(LocalStackBase, LocalStackBaseAlloca);
+    Deref = true;
   } else {
     // void *FakeStack = nullptr;
     // void *LocalStackBase = alloca(LocalStackSize);
     FakeStack = ConstantInt::get(IntptrTy, 0);
     LocalStackBase =
         DoDynamicAlloca ? createAllocaForLayout(IRB, L, true) : StaticAlloca;
+    LocalStackBaseAlloca = LocalStackBase;
+    Deref = false;
   }
 
   // Replace Alloca instructions with base+offset.
   for (const auto &Desc : SVD) {
     AllocaInst *AI = Desc.AI;
+    replaceDbgDeclareForAlloca(AI, LocalStackBaseAlloca, DIB, Deref,
+                               Desc.Offset, DIExpression::NoDeref);
     Value *NewAllocaPtr = IRB.CreateIntToPtr(
         IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset)),
         AI->getType());
-    replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB, DIExpression::NoDeref,
-                               0, DIExpression::NoDeref);
     AI->replaceAllUsesWith(NewAllocaPtr);
   }
 

Modified: llvm/trunk/test/DebugInfo/Generic/block-asan.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Generic/block-asan.ll?rev=320415&r1=320414&r2=320415&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/Generic/block-asan.ll (original)
+++ llvm/trunk/test/DebugInfo/Generic/block-asan.ll Mon Dec 11 12:43:21 2017
@@ -13,7 +13,7 @@
 
 ; Check that the location of the ASAN instrumented __block variable is
 ; correct.
-; CHECK: !DIExpression(DW_OP_plus_uconst, 8, DW_OP_deref, DW_OP_plus_uconst, 24)
+; CHECK: !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 32, DW_OP_plus_uconst, 8, DW_OP_deref, DW_OP_plus_uconst, 24)
 
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 

Modified: llvm/trunk/test/Instrumentation/AddressSanitizer/basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/basic.ll?rev=320415&r1=320414&r2=320415&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/basic.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/basic.ll Mon Dec 11 12:43:21 2017
@@ -91,6 +91,7 @@ entry:
 }
 
 ; CHECK-LABEL: define void @alloca_test()
+; CHECK: %asan_local_stack_base = alloca
 ; CHECK: = alloca
 ; CHECK-NOT: = alloca
 ; CHECK: ret void

Modified: llvm/trunk/test/Instrumentation/AddressSanitizer/debug_info.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/debug_info.ll?rev=320415&r1=320414&r2=320415&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/debug_info.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/debug_info.ll Mon Dec 11 12:43:21 2017
@@ -24,9 +24,9 @@ entry:
 ;   CHECK: entry:
 ; Verify that llvm.dbg.declare calls are in the entry basic block.
 ;   CHECK-NOT: %entry
-;   CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[ARG_ID:[0-9]+]], metadata !DIExpression())
+;   CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[ARG_ID:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 32))
 ;   CHECK-NOT: %entry
-;   CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[VAR_ID:[0-9]+]], metadata !DIExpression())
+;   CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[VAR_ID:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 48))
 
 declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
 

Added: llvm/trunk/test/Instrumentation/AddressSanitizer/local_stack_base.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/local_stack_base.ll?rev=320415&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/local_stack_base.ll (added)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/local_stack_base.ll Mon Dec 11 12:43:21 2017
@@ -0,0 +1,54 @@
+; RUN: opt -S -asan -asan-skip-promotable-allocas=0 %s -o - | FileCheck %s
+; Generated from:
+; int bar(int y) {
+;   return y + 2;
+; }
+
+source_filename = "/tmp/t.c"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.13.0"
+
+; Function Attrs: noinline nounwind optnone sanitize_address ssp uwtable
+define i32 @foo(i32 %i) #0 !dbg !8 {
+entry:
+  %i.addr = alloca i32, align 4
+  store i32 %i, i32* %i.addr, align 4
+  call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !12, metadata !DIExpression()), !dbg !13
+
+  ; CHECK: %asan_local_stack_base = alloca i64
+  ; CHECK: %[[ALLOCA:.*]] = ptrtoint i8* %MyAlloca to i64
+  ; CHECK: %[[PHI:.*]] = phi i64 {{.*}} %[[ALLOCA]],
+  ; CHECK: store i64 %[[PHI]], i64* %asan_local_stack_base, !dbg
+  ; CHECK: call void @llvm.dbg.declare(metadata i64* %asan_local_stack_base, metadata !13, metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 32)), !dbg !14
+  %0 = load i32, i32* %i.addr, align 4, !dbg !14
+  %add = add nsw i32 %0, 2, !dbg !15
+  ret i32 %add, !dbg !16
+}
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+attributes #0 = { noinline nounwind optnone sanitize_address ssp uwtable }
+attributes #1 = { nounwind readnone speculatable }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5, !6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 (trunk 320115) (llvm/trunk 320116)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "/tmp/t.c", directory: "/Data/llvm")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{i32 7, !"PIC Level", i32 2}
+!7 = !{!"clang version 6.0.0 (trunk 320115) (llvm/trunk 320116)"}
+!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
+!9 = !DISubroutineType(types: !10)
+!10 = !{!11, !11}
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !DILocalVariable(name: "i", arg: 1, scope: !8, file: !1, line: 1, type: !11)
+!13 = !DILocation(line: 1, column: 13, scope: !8)
+!14 = !DILocation(line: 2, column: 10, scope: !8)
+!15 = !DILocation(line: 2, column: 12, scope: !8)
+!16 = !DILocation(line: 2, column: 3, scope: !8)

Modified: llvm/trunk/test/Instrumentation/AddressSanitizer/stack_layout.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/stack_layout.ll?rev=320415&r1=320414&r2=320415&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/stack_layout.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/stack_layout.ll Mon Dec 11 12:43:21 2017
@@ -22,6 +22,7 @@ entry:
 ; CHECK-LABEL: Func1
 
 ; CHECK-STATIC: alloca [192 x i8]
+; CHECK-STATIC: %asan_local_stack_base = alloca i64
 ; CHECK-DYNAMIC: alloca i8, i64 192
 
 ; CHECK-NOT: alloca
@@ -43,6 +44,7 @@ entry:
 ; CHECK-LABEL: Func2
 
 ; CHECK-STATIC: alloca [864 x i8]
+; CHECK-STATIC: %asan_local_stack_base = alloca i64
 ; CHECK-DYNAMIC: alloca i8, i64 864
 
 ; CHECK-NOT: alloca
@@ -65,6 +67,7 @@ entry:
 ; CHECK-LABEL: Func3
 
 ; CHECK-STATIC: alloca [768 x i8]
+; CHECK-STATIC: %asan_local_stack_base = alloca i64
 ; CHECK-DYNAMIC: alloca i8, i64 768
 
 ; CHECK-NOT: alloca




More information about the llvm-commits mailing list