https://bugs.llvm.org/show_bug.cgi?id=35547
Bug ID: 35547
Summary: [ThinLTO] multi-threaded use after free when handling
error
Product: new-bugs
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: new bugs
Assignee: unassignedb...@nondot.org
Reporter: russell_gal...@sn.scee.net
CC: llvm-bugs@lists.llvm.org
While investigating PR35472 we observed some crashes while handling that error.
Building clang and llvm-lto with ASan (r319883) shows that one thread is trying
to access command line options after they have been freed. Note that we do not
see the use-after-free with -threads=1.
$ cat a.cpp
struct Charlie {
__attribute__((__always_inline__)) ~Charlie() { Golf = 0; }
int Golf;
};
struct Delta {
Charlie Foxtrot;
};
struct Echo {
Charlie Foxtrot;
__attribute__((nodebug)) ~Echo() = default;
};
extern void Bravo();
void Bravo() {
Delta Hotel;
Echo India;
}
$ cat b.cpp
extern void Bravo();
extern void Alpha();
void Alpha() { Bravo(); }
$ clang++ -c a.cpp b.cpp --std=c++11 -O0 -g -flto=thin
$ llvm-lto -thinlto-action=run a.o b.o
ThinLTO: b.o: error: Invalid function metadata: outgoing forward refs
(Producer: 'LLVM6.0.0svn' Reader: 'LLVM 6.0.0svn')
LLVM ERROR: importFunctions failed
=================================================================
==10367==ERROR: AddressSanitizer: heap-use-after-free on address 0x624000004100
at pc 0x00000060388d bp 0x7ff7c62fd050 sp 0x7ff7c62fc800
READ of size 32 at 0x624000004100 thread T1
#0 0x60388c in __asan_memcpy
.../llvm/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23
#1 0x234da66 in llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo::OptionInfo(llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo&&) .../llvm/include/llvm/Support/CommandLine.h:740:9
#2 0x234d8ad in llvm::cl::parser<llvm::PassInfo const*>::OptionInfo*
std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo*>, llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo*>(std::move_iterator<llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo*>, std::move_iterator<llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo*>, llvm::cl::parser<llvm::PassInfo const*>::OptionInfo*)
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_uninitialized.h:75:3
#3 0x234d481 in
llvm::SmallVectorTemplateBase<llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo, false>::grow(unsigned long)
.../llvm/include/llvm/ADT/SmallVector.h:246:3
#4 0x234d144 in
llvm::SmallVectorTemplateBase<llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo, false>::push_back(llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo const&) .../llvm/include/llvm/ADT/SmallVector.h:214:13
#5 0x234ce8d in void llvm::cl::parser<llvm::PassInfo
const*>::addLiteralOption<llvm::PassInfo const*>(llvm::StringRef,
llvm::PassInfo const* const&, llvm::StringRef)
.../llvm/include/llvm/Support/CommandLine.h:789:12
#6 0x234c61b in llvm::PassNameParser::passRegistered(llvm::PassInfo const*)
.../llvm/include/llvm/IR/LegacyPassNameParser.h:76:5
#7 0x236b874 in llvm::PassRegistry::registerPass(llvm::PassInfo const&,
bool) .../llvm/lib/IR/PassRegistry.cpp:68:15
#8 0x379b512 in
initializeForceFunctionAttrsLegacyPassPassOnce(llvm::PassRegistry&)
.../llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp:118:1
#9 0x7ff7ca461a98 in __pthread_once_slow
(/lib/x86_64-linux-gnu/libpthread.so.0+0xea98)
#10 0x6d3b50 in void std::call_once<void* (&)(llvm::PassRegistry&),
std::reference_wrapper<llvm::PassRegistry> >(std::once_flag&, void*
(&)(llvm::PassRegistry&), std::reference_wrapper<llvm::PassRegistry>&&)
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/mutex:738:17
#11 0x379b452 in
llvm::initializeForceFunctionAttrsLegacyPassPass(llvm::PassRegistry&)
.../llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp:118:1
#12 0x379b53a in llvm::createForceFunctionAttrsLegacyPass()
.../llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp:122:14
#13 0x388d9e8 in
llvm::PassManagerBuilder::populateModulePassManager(llvm::legacy::PassManagerBase&)
.../llvm/lib/Transforms/IPO/PassManagerBuilder.cpp:401:11
#14 0x3890826 in
llvm::PassManagerBuilder::populateThinLTOPassManager(llvm::legacy::PassManagerBase&)
.../llvm/lib/Transforms/IPO/PassManagerBuilder.cpp:887:3
#15 0x244586b in (anonymous namespace)::optimizeModule(llvm::Module&,
llvm::TargetMachine&, unsigned int, bool)
.../llvm/lib/LTO/ThinLTOCodeGenerator.cpp:237:7
#16 0x2452b7f in (anonymous namespace)::ProcessThinLTOModule(llvm::Module&,
llvm::ModuleSummaryIndex&, llvm::StringMap<llvm::MemoryBufferRef,
llvm::MallocAllocator>&, llvm::TargetMachine&,
llvm::StringMap<std::map<unsigned long, unsigned int, std::less<unsigned long>,
std::allocator<std::pair<unsigned long const, unsigned int> > >,
llvm::MallocAllocator> const&, std::unordered_set<unsigned long,
std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<unsigned
long> > const&, llvm::DenseSet<unsigned long, llvm::DenseMapInfo<unsigned long>
> const&, llvm::DenseMap<unsigned long, llvm::GlobalValueSummary*,
llvm::DenseMapInfo<unsigned long>, llvm::detail::DenseMapPair<unsigned long,
llvm::GlobalValueSummary*> > const&, llvm::ThinLTOCodeGenerator::CachingOptions
const&, bool, llvm::StringRef, bool, unsigned int, unsigned int)
.../llvm/lib/LTO/ThinLTOCodeGenerator.cpp:468:3
#17 0x2450e2f in llvm::ThinLTOCodeGenerator::run()::$_5::operator()(int)
const .../llvm/lib/LTO/ThinLTOCodeGenerator.cpp:1011:29
#18 0x24504bf in void std::_Bind<llvm::ThinLTOCodeGenerator::run()::$_5
(int)>::__call<void, , 0ul>(std::tuple<>&&, std::_Index_tuple<0ul>)
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/functional:1073:11
#19 0x24503a2 in void std::_Bind<llvm::ThinLTOCodeGenerator::run()::$_5
(int)>::operator()<, void>()
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/functional:1131:17
#20 0x278f309 in
std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>,
std::__future_base::_Result_base::_Deleter>,
std::_Bind_simple<std::reference_wrapper<std::function<void ()> > ()>,
void>::operator()() const
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/future:1342:6
#21 0x278f1b9 in
std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> (),
std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>,
std::__future_base::_Result_base::_Deleter>,
std::_Bind_simple<std::reference_wrapper<std::function<void ()> > ()>, void>
>::_M_invoke(std::_Any_data const&)
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/functional:1856:9
#22 0x278f085 in
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>::operator()() const
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/functional:2267:14
#23 0x278e5c4 in
std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*)
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/future:527:27
#24 0x7ff7ca461a98 in __pthread_once_slow
(/lib/x86_64-linux-gnu/libpthread.so.0+0xea98)
#25 0x278e467 in void std::call_once<void
(std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void
(std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*, bool*),
std::__future_base::_State_baseV2*&&,
std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/mutex:738:17
#26 0x278de81 in
std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base,
std::__future_base::_Result_base::_Deleter> ()>, bool)
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/future:386:2
#27 0x278d0b0 in std::__future_base::_Task_state<std::function<void ()>,
std::allocator<int>, void ()>::_M_run()
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/future:1403:8
#28 0x2787364 in llvm::ThreadPool::ThreadPool(unsigned
int)::$_0::operator()() const .../llvm/lib/Support/ThreadPool.cpp:57:9
#29 0x7ff7c9631c7f (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb8c7f)
#30 0x7ff7ca45a6b9 in start_thread
(/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
#31 0x7ff7c90a03dc in clone
/build/glibc-bfm8X4/glibc-2.23/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:109
0x624000004100 is located 0 bytes inside of 7168-byte region
[0x624000004100,0x624000005d00)
freed by thread T2 here:
#0 0x604848 in __interceptor_cfree.localalias.0
.../llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:76
#1 0x234cbdf in llvm::cl::parser<llvm::PassInfo const*>::~parser()
.../llvm/include/llvm/Support/CommandLine.h:738:33
#2 0x234b9d1 in llvm::PassNameParser::~PassNameParser()
.../llvm/lib/IR/Pass.cpp:254:33
#3 0x22cfb92 in llvm::cl::list<llvm::PassInfo const*, bool,
llvm::PassNameParser>::~list()
.../llvm/include/llvm/Support/CommandLine.h:1475:7
#4 0x7ff7c8fd2ff7 in __run_exit_handlers
/build/glibc-bfm8X4/glibc-2.23/stdlib/exit.c:82
previously allocated by thread T0 here:
#0 0x604a08 in __interceptor_malloc
.../llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88
#1 0x234d43c in
llvm::SmallVectorTemplateBase<llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo, false>::grow(unsigned long)
.../llvm/include/llvm/ADT/SmallVector.h:241:32
#2 0x234d144 in
llvm::SmallVectorTemplateBase<llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo, false>::push_back(llvm::cl::parser<llvm::PassInfo
const*>::OptionInfo const&) .../llvm/include/llvm/ADT/SmallVector.h:214:13
#3 0x234ce8d in void llvm::cl::parser<llvm::PassInfo
const*>::addLiteralOption<llvm::PassInfo const*>(llvm::StringRef,
llvm::PassInfo const* const&, llvm::StringRef)
.../llvm/include/llvm/Support/CommandLine.h:789:12
#4 0x234c61b in llvm::PassNameParser::passRegistered(llvm::PassInfo const*)
.../llvm/include/llvm/IR/LegacyPassNameParser.h:76:5
#5 0x236b874 in llvm::PassRegistry::registerPass(llvm::PassInfo const&,
bool) .../llvm/lib/IR/PassRegistry.cpp:68:15
#6 0x447b0ff in
initializeMemoryDependenceWrapperPassPassOnce(llvm::PassRegistry&)
.../llvm/lib/Analysis/MemoryDependenceAnalysis.cpp:1728:1
#7 0x7ff7ca461a98 in __pthread_once_slow
(/lib/x86_64-linux-gnu/libpthread.so.0+0xea98)
Thread T1 created by T0 here:
#0 0x55a16d in pthread_create
.../llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:204
#1 0x7ff7c9631dc2 in
std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>, void
(*)()) (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb8dc2)
Thread T2 created by T0 here:
#0 0x55a16d in pthread_create
.../llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:204
#1 0x7ff7c9631dc2 in
std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>, void
(*)()) (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb8dc2)
SUMMARY: AddressSanitizer: heap-use-after-free
.../llvm/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23 in
__asan_memcpy
Shadow bytes around the buggy address:
0x0c487fff87d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c487fff87e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c487fff87f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c487fff8800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c487fff8810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c487fff8820:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c487fff8830: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c487fff8840: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c487fff8850: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c487fff8860: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c487fff8870: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
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
==10367==ABORTING
--
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs