Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure we have all required function prototypes before running the GC pass. #23621

Merged
merged 1 commit into from
Sep 8, 2017

Conversation

maleadt
Copy link
Member

@maleadt maleadt commented Sep 7, 2017

According to the LLVM docs this should happen in doInitialization, but eg.
in the case of stripDeadPrototypes (module pass) -> LowerGCFrame (function pass)
the pass manager initializes all module passes, including the function pass manager
which in turn initializes all function passes, before running any other pass.
This may result in cached prototypes pointing to invalid functions.

Alternatively, we could populate llvm.used with the prototypes and clean it afterwards.

… intrinsics.

According to the LLVM docs this should be done in doInitialization, but eg.
in the case of stripDeadPrototypes (module pass) -> LowerGCFrame (function pass)
the pass manager initializes all module passes, including the function pass manager
which in turn initializes all function passes, before running any other pass.
This may result in cached prototypes pointing to invalid functions.

Alternatively, we could populate llvm.used with the prototypes and clean it afterwards.
@maleadt maleadt added the GC Garbage collector label Sep 7, 2017
@maleadt maleadt requested a review from Keno September 7, 2017 18:39
@maleadt
Copy link
Member Author

maleadt commented Sep 7, 2017

$ rr record opt -load libjulia-debug.so -debug-pass=Structure -strip-dead-prototypes -LateLowerGCFrame vadd.ll >/dev/null
Pass Arguments:  -targetlibinfo -tti -strip-dead-prototypes -domtree -LateLowerGCFrame -verify -write-bitcode
Target Library Information
Target Transform Information
  ModulePass Manager
    Strip Unused Function Prototypes
    FunctionPass Manager
      Dominator Tree Construction
      Late Lower GCFrame Pass
      Module Verifier
    Bitcode Writer
=================================================================
==22315==ERROR: AddressSanitizer: heap-use-after-free on address 0x60f00000c368 at pc 0x7f483b038752 bp 0x7ffc319cef30 sp 0x7ffc319cef28
READ of size 8 at 0x60f00000c368 thread T0
    #0 0x7f483b038751 in getValueType deps/srccache/llvm-3.9.1/include/llvm/IR/GlobalValue.h:237:39
    #1 0x7f483b038751 in llvm::Function::getFunctionType() const deps/srccache/llvm-3.9.1/lib/IR/Function.cpp:235
    #2 0x7f48358a3470 in llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>::CreateCall(llvm::Function*, llvm::ArrayRef<llvm::Value*>, llvm::Twine const&, llvm::MDNode*) build/sanitize/usr/include/llvm/IR/IRBuilder.h:1572:31
    #3 0x7f4835a6fc60 in LateLowerGCFrame::CleanupIR(llvm::Function&) src/llvm-late-gc-lowering.cpp:1181:36
    #4 0x7f4835a76ae2 in LateLowerGCFrame::runOnFunction(llvm::Function&) src/llvm-late-gc-lowering.cpp:1495:5
    #5 0x7f483b0e9986 in llvm::FPPassManager::runOnFunction(llvm::Function&) deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1526:27
    #6 0x7f483b0e9e25 in llvm::FPPassManager::runOnModule(llvm::Module&) deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1547:16
    #7 0x7f483b0ea939 in runOnModule deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1603:27
    #8 0x7f483b0ea939 in llvm::legacy::PassManagerImpl::run(llvm::Module&) deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1706
    #9 0x5373e8 in main deps/srccache/llvm-3.9.1/tools/opt/opt.cpp:679:10
    #10 0x7f483921d4c9 in __libc_start_main (/usr/lib/libc.so.6+0x204c9)
    #11 0x448ba9 in _start (build/sanitize/usr/tools/opt+0x448ba9)

0x60f00000c368 is located 40 bytes inside of 168-byte region [0x60f00000c340,0x60f00000c3e8)
freed by thread T0 here:
    #0 0x516f5b in operator delete(void*) deps/srccache/llvm-3.9.1/projects/compiler-rt/lib/asan/asan_new_delete.cc:110:3
    #1 0x7f483c969c63 in stripDeadPrototypes(llvm::Module&) deps/srccache/llvm-3.9.1/lib/Transforms/IPO/StripDeadPrototypes.cpp:37:10
    #2 0x7f483c96a79d in (anonymous namespace)::StripDeadPrototypesLegacyPass::runOnModule(llvm::Module&) deps/srccache/llvm-3.9.1/lib/Transforms/IPO/StripDeadPrototypes.cpp:76:12
    #3 0x7f483b0ea939 in runOnModule deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1603:27
    #4 0x7f483b0ea939 in llvm::legacy::PassManagerImpl::run(llvm::Module&) deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1706
    #5 0x5373e8 in main deps/srccache/llvm-3.9.1/tools/opt/opt.cpp:679:10
    #6 0x7f483921d4c9 in __libc_start_main (/usr/lib/libc.so.6+0x204c9)

previously allocated by thread T0 here:
    #0 0x51695b in operator new(unsigned long) deps/srccache/llvm-3.9.1/projects/compiler-rt/lib/asan/asan_new_delete.cc:78:35
    #1 0x7f483b1819cc in llvm::User::operator new(unsigned long) deps/srccache/llvm-3.9.1/lib/IR/User.cpp:156:19
    #2 0x7f4835894fcf in llvm::Function::Create(llvm::FunctionType*, llvm::GlobalValue::LinkageTypes, llvm::Twine const&, llvm::Module*) build/sanitize/usr/include/llvm/IR/Function.h:111:12
    #3 0x7f4835a75d27 in LateLowerGCFrame::doInitialization(llvm::Module&) src/llvm-late-gc-lowering.cpp:1438:31
    #4 0x7f483b0e9f2c in llvm::FPPassManager::doInitialization(llvm::Module&) deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1556:41
    #5 0x7f483b0ea70a in runOnModule deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1588:41
    #6 0x7f483b0ea70a in llvm::legacy::PassManagerImpl::run(llvm::Module&) deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1706
    #7 0x5373e8 in main deps/srccache/llvm-3.9.1/tools/opt/opt.cpp:679:10
    #8 0x7f483921d4c9 in __libc_start_main (/usr/lib/libc.so.6+0x204c9)

SUMMARY: AddressSanitizer: heap-use-after-free deps/srccache/llvm-3.9.1/include/llvm/IR/GlobalValue.h:237:39 in getValueType
Shadow bytes around the buggy address:
  0x0c1e7fff9810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1e7fff9820: fa fa fa fa fa fa fa fa fa fa fa fa 00 00 00 00
  0x0c1e7fff9830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1e7fff9840: 00 fa fa fa fa fa fa fa fa fa fd fd fd fd fd fd
  0x0c1e7fff9850: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
=>0x0c1e7fff9860: fa fa fa fa fa fa fa fa fd fd fd fd fd[fd]fd fd
  0x0c1e7fff9870: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa
  0x0c1e7fff9880: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00
  0x0c1e7fff9890: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
  0x0c1e7fff98a0: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1e7fff98b0: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==22315==ABORTING
$ rr replay

(rr) break llvm-late-gc-lowering.cpp:1421
(rr) c
Breakpoint 1, LateLowerGCFrame::doInitialization (this=0x60f00000c520, M=...) at src/llvm-late-gc-lowering.cpp:1422
1422        ptls_getter = M.getFunction("jl_get_ptls_states");

(rr) bt
#0  LateLowerGCFrame::doInitialization (this=0x60f00000c520, M=...) at src/llvm-late-gc-lowering.cpp:1422
#1  0x00007f483b0e9f2d in doInitialization () at deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1556
#2  0x00007f483b0ea70b in runOnModule () at deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1588
#3  run () at deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1706
#4  0x00000000005373e9 in main () at deps/srccache/llvm-3.9.1/tools/opt/opt.cpp:679
(rr) break StripDeadPrototypes.cpp:37
Breakpoint 2 at 0x7f483c969c30: file deps/srccache/llvm-3.9.1/lib/Transforms/IPO/StripDeadPrototypes.cpp, line 37.

(rr) c
Breakpoint 2, stripDeadPrototypes () at deps/srccache/llvm-3.9.1/lib/Transforms/IPO/StripDeadPrototypes.cpp:37
37            F->eraseFromParent();

(rr) bt
#0  stripDeadPrototypes () at deps/srccache/llvm-3.9.1/lib/Transforms/IPO/StripDeadPrototypes.cpp:37
#1  0x00007f483c96a79e in (anonymous namespace)::StripDeadPrototypesLegacyPass::runOnModule(llvm::Module&) ()
#2  0x00007f483b0ea93a in runOnModule () at deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1603
#3  run () at deps/srccache/llvm-3.9.1/lib/IR/LegacyPassManager.cpp:1706
#4  0x00000000005373e9 in main () at deps/srccache/llvm-3.9.1/tools/opt/opt.cpp:679

@JeffBezanson JeffBezanson added the compiler:codegen Generation of LLVM IR and native code label Sep 7, 2017
@maleadt maleadt merged commit ca01a0b into master Sep 8, 2017
@maleadt maleadt deleted the tb/gcpass_defs branch September 8, 2017 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:codegen Generation of LLVM IR and native code GC Garbage collector
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants