LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 1202 - llc deadlock via memory corruption from TargetData::setAlignment
Summary: llc deadlock via memory corruption from TargetData::setAlignment
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Core LLVM classes (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Reid Spencer
URL:
Keywords: compile-fail
Depends on: 1203
Blocks:
  Show dependency tree
 
Reported: 2007-02-15 10:51 PST by Reid Spencer
Modified: 2010-02-22 12:42 PST (History)
2 users (show)

See Also:
Fixed By Commit(s):


Attachments
Output from the test script showing the errors (4.50 KB, text/plain)
2007-02-15 10:52 PST, Reid Spencer
Details
Valgrind output showing TargetData errors. (57.33 KB, text/plain)
2007-02-15 10:55 PST, Reid Spencer
Details
Input bytecode for llc that causes the problem. (322 bytes, application/octet-stream)
2007-02-15 10:56 PST, Reid Spencer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Reid Spencer 2007-02-15 10:51:01 PST
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
Comment 1 Reid Spencer 2007-02-15 10:52:56 PST
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.
Comment 2 Reid Spencer 2007-02-15 10:55:46 PST
Created attachment 664 [details]
Valgrind output showing TargetData errors.
Comment 3 Reid Spencer 2007-02-15 10:56:20 PST
Created attachment 665 [details]
Input bytecode for llc that causes the problem.
Comment 4 Reid Spencer 2007-02-15 11:00:23 PST
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)
Comment 5 Reid Spencer 2007-02-15 11:07:45 PST
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 :)
Comment 6 Reid Spencer 2007-02-15 12:37:40 PST
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.
Comment 7 Reid Spencer 2007-02-15 12:38:09 PST
Mine.
Comment 8 Reid Spencer 2007-02-15 12:41:33 PST
The TargetData fix exposed the BitVector problem. This bug can't be resolved
until bug 1203 is fixed.
Comment 9 Reid Spencer 2007-02-15 12:59:56 PST
Bug 1203 has now been fixed and it resolves this one too.