My nightly test last night was stalled by the PassManager incurring an exception in operator delete that caused an abort that went into a deadlock. The test case is llvm/test/CFrontend/2004-02-13-IllegalVararg.c.tr which is: // RUN: %llvmgcc -xc %s -c -o - | llc #include <stdarg.h> float test(int X, ...) { va_list ap; float F; va_start(ap, X); F = va_arg(ap, float); return F; } During compilation of this, llvm-gcc warned about the following: /proj/llvm/nightly/build/llvm/test/CFrontend/2004-02-13-IllegalVararg.c.tr: In function 'test': /proj/llvm/nightly/build/llvm/test/CFrontend/2004-02-13-IllegalVararg.c.tr:9: warning: 'float' is promoted to 'double' when passed through '...' /proj/llvm/nightly/build/llvm/test/CFrontend/2004-02-13-IllegalVararg.c.tr:9: warning: (so you should pass 'double' not 'float' to 'va_arg') /proj/llvm/nightly/build/llvm/test/CFrontend/2004-02-13-IllegalVararg.c.tr:9: note: if this code is reached, the program will abort When llc tried to compile llvm-gcc's output, the program goes into a deadlock when PMTopLevelMgr's map is destructed. During destruction of one of the map's nodes the libc free() method generated this error: *** glibc detected *** llc: double free or corruption (!prev): 0x098e3938 *** The stack looks like this: #0 0x00bfd402 in __kernel_vsyscall () #1 0x003cecce in __lll_mutex_lock_wait () from /lib/libc.so.6 #2 0x003614e8 in _L_lock_43 () from /lib/libc.so.6 #3 0x0035b35d in ptmalloc_lock_all () from /lib/libc.so.6 #4 0x003849e0 in fork () from /lib/libc.so.6 #5 0x0059bad0 in fork () from /lib/libpthread.so.0 #6 0x0888b952 in (anonymous namespace)::PrintStackTrace () at Unix/Signals.inc:78 #7 0x0888bc3e in (anonymous namespace)::SignalHandler (Sig=6) at Unix/Signals.inc:139 #8 <signal handler called> #9 0x00bfd402 in __kernel_vsyscall () #10 0x00321ee9 in raise () from /lib/libc.so.6 #11 0x003234f1 in abort () from /lib/libc.so.6 #12 0x0035653b in __libc_message () from /lib/libc.so.6 #13 0x0035da68 in _int_free () from /lib/libc.so.6 #14 0x00360f6f in free () from /lib/libc.so.6 #15 0x001bf3e1 in operator delete (ptr=0x98e3938) at ../../../../svn-4.0.3/libstdc++-v3/libsupc++/del_op.cc:49 #16 0x088276eb in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<llvm::Pass* const, llvm::Pass*> > >::deallocate (this=0x98e2550, __p=0x98e3938) at /proj/install/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../../include/c++/4.0.3/ext/new_allocator.h:94 #17 0x08827710 in std::_Rb_tree<llvm::Pass*, std::pair<llvm::Pass* const, llvm::Pass*>, std::_Select1st<std::pair<llvm::Pass* const, llvm::Pass*> >, std::less<llvm::Pass*>, std::allocator<std::pair<llvm::Pass* const, llvm::Pass*> > >::_M_put_node (this=0x98e2550, __p=0x98e3938) at /proj/install/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_tree.h:360 #18 0x08827760 in std::_Rb_tree<llvm::Pass*, std::pair<llvm::Pass* const, llvm::Pass*>, std::_Select1st<std::pair<llvm::Pass* const, llvm::Pass*> >, std::less<llvm::Pass*>, std::allocator<std::pair<llvm::Pass* const, llvm::Pass*> > >::destroy_node (this=0x98e2550, __p=0x98e3938) at /proj/install/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_tree.h:390 #19 0x088277a8 in std::_Rb_tree<llvm::Pass*, std::pair<llvm::Pass* const, llvm::Pass*>, std::_Select1st<std::pair<llvm::Pass* const, llvm::Pass*> >, std::less<llvm::Pass*>, std::allocator<std::pair<llvm::Pass* const, llvm::Pass*> > >::_M_erase (this=0x98e2550, __x=0x98e3938) at /proj/install/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_tree.h:1097 #20 0x08827788 in std::_Rb_tree<llvm::Pass*, std::pair<llvm::Pass* const, llvm::Pass*>, std::_Select1st<std::pair<llvm::Pass* const, llvm::Pass*> >, std::less<llvm::Pass*>, std::allocator<std::pair<llvm::Pass* const, llvm::Pass*> > >::_M_erase (this=0x98e2550, __x=0x98e2120) at /proj/install/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_tree.h:1095 #21 0x088277d6 in ~_Rb_tree (this=0x98e2550) at /proj/install/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_tree.h:571 #22 0x088277f5 in ~map (this=0x98e2550) at /proj/install/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_map.h:92 #23 0x0882158e in ~PMTopLevelManager (this=0x98e250c) at PassManager.cpp:498 #24 0x0882926e in ~FunctionPassManagerImpl (this=0x98e24b8) at PassManager.cpp:116 #25 0x0881f7ff in ~FunctionPassManager (this=0xbff8e224) at PassManager.cpp:867 #26 0x083b3083 in main (argc=1, argv=0xbff8e314) at llc.cpp:292 As this occurs on destruction, llc managed to produce this output anyway: .text .align 16 .globl test .type test,@function test: subl $24, %esp movl 28(%esp), %eax movl %eax, 20(%esp) leal 32(%esp), %eax movl %eax, 8(%esp) movss 0, %xmm0 movss %xmm0, 4(%esp) movss %xmm0, 12(%esp) movss %xmm0, 16(%esp) .LBB1_1: #return movss 16(%esp), %xmm0 movss %xmm0, (%esp) flds (%esp) addl $24, %esp ret .size test, .-test
Created attachment 663 [details] Output from the test script showing the errors This provides the complete text of the test case's output. I will try to get valgrind output on this as well.
Created attachment 664 [details] Valgrind output showing TargetData errors.
Created attachment 665 [details] Input bytecode for llc that causes the problem.
valgrind shows seven of these errors: 1 errors in context 1 of 7: Conditional jump or move depends on uninitialised value(s) at 0x87B8596: llvm::TargetData::setAlignment(llvm::AlignTypeEnum, unsigned char, unsigned char, short) (TargetData.cpp:248) by 0x87B8798: llvm::TargetData::init(std::string const&) (TargetData.cpp:188) by 0x84344C6: llvm::TargetData::TargetData(std::string const&) (TargetData.h:122) by 0x8513F27: llvm::X86TargetMachine::X86TargetMachine(llvm::Module const&, std::string const&, bool) (X86TargetMachine.cpp:116) by 0x851420A: llvm::X86_32TargetMachine::X86_32TargetMachine(llvm::Module const&, std::string const&) (X86TargetMachine.cpp:99) by 0x85AB8CC: llvm::RegisterTarget<llvm::X86_32TargetMachine>::Allocator(llvm::Module const&, std::string const&) (TargetMachineRegistry.h:89) by 0x83B284A: main (llc.cpp:215)
Scott, This bug was almost certainly due to your TargetData patch last night. The setAlignment method is being called in "init", probably before member vars that setAlignment uses are given values. That's about as far as I got in my analysis. I've assigned this PR to you. Could you please investigate the details and fix TargetData? That should fix this test case too. Thanks, Reid. P.S. You need to register an email account with LLVM Bugzilla :)
There appear to be multiple issues. The TargetData problem was taken care of with this patch: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070212/044580.html which makes sure to check for a found entry in the Alignments vector before overwriting it. There also seems to be a memory overwrite error in the New BitVector class. I'll attach the valgrind output for that shortly.
Mine.
The TargetData fix exposed the BitVector problem. This bug can't be resolved until bug 1203 is fixed.
Bug 1203 has now been fixed and it resolves this one too.