Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#211 closed defect (fixed)

Segfault in printf called via llvm.

Reported by: erikd Owned by: erikd
Priority: normal Milestone:
Component: Unknown Version: 0.1.2
Keywords: Cc:

Description

This code

{-# OPTIONS -no-implicit-prelude #-}
import Base

foreign import "printf"
 printf :: String#{read} -> Int#

data List a = Nil | Cons a (List a)

map f Nil		= Nil
map f (Cons x xs)	= Cons (f x) (map f xs)

main ()
 = do	map (\x -> printf "beep!"#) (Cons 1 (Cons 2 (Cons 3 (Cons 4 (Cons 5 Nil)))))
	()

works correctly compling via C but segfaults compiling via LLVM with:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7638754 in __fprintf (stream=0x4019c0, format=0x4019c0 "beep!\n") at fprintf.c:28

It seems the format string is being passed for the stream as well. Not sure if this is an LLVM linking issues or a problem with strong vs weak aliases in GNU libc.

Interestingly, if I change the printf call to puts, the LLVM backend does the right thing.

Change History (4)

comment:1 Changed 9 years ago by erikd

  • Owner set to erikd
  • Status changed from new to assigned

comment:2 Changed 9 years ago by erikd

For foreign import-ed functions, the LLVM backend assumes that the type of the function in the foreign import statement is correct. In this test (simplified to the following):

foreign import "printf"
    printf :: String#{read} -> Int32#

printFunc x = printf "beep!\n"#

the LLVM backend assumes that the type of printf is actually (in LLVM code):

i32 @printf(i8*)

but calling it like that causes the segfault.

If instead, the backend special cases printf to have the type:

i32 @printf(i8*, ...)

which specifies it as a varargs functions there is no segfault.

Last edited 9 years ago by erikd (previous) (diff)

comment:3 Changed 9 years ago by erikd

  • Resolution set to fixed
  • Status changed from assigned to closed

Decided to special case all vararg functions for now.

Fixed in:

Mon Jan  3 09:06:11 EST 2011  Erik de Castro Lopo <erikd@mega-nerd.com>
  * LLVM : Special case vararg functions like printf/snprintf.

comment:4 Changed 8 years ago by benl

  • Milestone 0.1.3 deleted

Milestone 0.1.3 deleted

Note: See TracTickets for help on using tickets.