[LLVMbugs] [Bug 6225] New: stack corruption with tail recursive calls

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Wed Feb 3 15:51:55 PST 2010


http://llvm.org/bugs/show_bug.cgi?id=6225

           Summary: stack corruption with tail recursive calls
           Product: new-bugs
           Version: 2.6
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: amanous at softlab.ntua.gr
                CC: llvmbugs at cs.uiuc.edu


Created an attachment (id=4170)
 --> (http://llvm.org/bugs/attachment.cgi?id=4170)
llvm program producing the bug

I have been using LLVM for quite some time now, for production of native
binaries for a compiler I am developing. The compiler works with continuations,
so I rely heavily on tail recursion (all my calls are "fastcc tail", the stack
never grows).

Lately I encountered a strange behavior. A binary produced by my compiler
finished computation and THEN segfaulted. The first thing that came to mind was
corruption of the return address, and after debugging with gdb it proved I was
correct.

After a lot of investigation of my entire compiler I traced the problem to the
llvm conversion. During a branching call, the llvm corrupted the return address
to the operating system, e.g. the contents of the location pointed by the stack
pointer when the program starts.

Attached is the smallest piece of code I could create that reproduces the bug.
I compile with :

llvm-as -f test.ll 
llc -tailcallopt -asm-verbose -march x86 -f test.bc
gcc -g -Wall -m32 -c test.s
gcc -g -m32 -o test  test.o

the binary "test" segfaults.

The interesting code fragment is:

----------------
define fastcc void @l186(%tupl_p %r1) noreturn nounwind {
entry:
   ...
  br i1 %cond, label %true, label %false

true:
  tail call fastcc void @l297(i32 %r10, i32 %r9, i32 %r8, i32 %r7, i32 %r6, i32
%r5, i32 %r3, i32 %r2) noreturn nounwind
  ret void

false:
  tail call fastcc void @l298(i32 %r10, i32 %r9, i32 %r4) noreturn nounwind
  ret void
}
----------------

Which gets translated to:

----------------


l186:
.LBB1_0:
        subl    $24, %esp
        pushl   %ebp
        pushl   %ebx
        pushl   %edi
        pushl   %esi
        subl    $36, %esp
        ....
.LBB1_1: # %true
        ...
        movl    %ecx, 76(%esp)
        ...
----------------


The "movl %ecx, 76(%esp)" instruction overwrites the return address of the
program irreversibly. When the computation finishes, it will jump to this
address, causing a segmentation fault.

I tried the same program with the trunk version (a few days ago) and I get the
same assembly translation (and segfault of course).


-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list