Opened 2 years ago

Closed 2 years ago

#5594 closed bug (fixed)

stdout is not flushed using custom main

Reported by: handonson Owned by: simonmar
Priority: high Milestone: 7.4.1
Component: Compiler Version: 7.0.4
Keywords: Cc:
Operating System: Linux Architecture: x86
Type of failure: Incorrect result at runtime Difficulty:
Test Case: Blocked By:
Blocking: Related Tickets:

Description

According to the using your own main() guide, Prepare two files.

main.c:

#include <stdio.h>
#include "HsFFI.h"

#ifdef __GLASGOW_HASKELL__
#include "Vomit_stub.h"
#endif

int main(int argc, char *argv[])
{
    int i;

    hs_init(&argc, &argv);

    vomit();

    hs_exit();
    return 0;
}

Vomit.hs:

{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE OverloadedStrings #-}

module Vomit where

import Data.ByteString
import Data.ByteString.Char8 ()
import Prelude hiding (putStr)

foreign export ccall vomit :: IO ()
vomit = putStr "Wrrreerrerek\n"

Compile the code:

$ ghc -c Vomit.hs
$ ghc --make -no-hs-main -optc-O main.c Vomit -o main

Run:

$ ./main
Wrrreerrerek
$

Looks fine. However:

$ ./main > output.txt
$ cat output.txt
$

output.txt is empty.

It seems when the output is done by some Haskell code called by a C code, and the stdout is redirected to a file, the output is not properly flushed. Changing Vomit.hs to:

{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE OverloadedStrings #-}

module Vomit where

import Data.ByteString
import Data.ByteString.Char8 ()
import Prelude hiding (putStr)

import System.IO (hFlush, stdout)

foreign export ccall vomit :: IO ()
vomit = putStr "Wrrreerrerek\n" >> hFlush stdout

which manually flushes stdout, fixes the behavior.

Since hs_exit() on the C side is supposed to terminate the RTS and flush all output, this seems to be a bug.

Tested with GHC 7.0.4 on Debian GNU/Linux for x86.

Change History (3)

comment:1 Changed 2 years ago by simonmar

  • Milestone set to 7.4.1
  • Owner set to simonmar
  • Priority changed from normal to high

comment:2 Changed 2 years ago by marlowsd@…

commit 2babc2a527533a67a59cb62782e80292f689fa10

Author: Simon Marlow <marlowsd@gmail.com>
Date:   Mon Nov 7 15:24:00 2011 +0000

    Flush stdout and stderr during hs_exit() (#5594)
    
    Ensures that these handles are flushed even when the RTS is being used
    as a library, with no main.
    
    Needs a corresponding change to libraries/base.

 rts/Prelude.h    |    2 ++
 rts/RtsStartup.c |   15 +++++++++++++++
 2 files changed, 17 insertions(+), 0 deletions(-)

comment:3 Changed 2 years ago by simonmar

  • Resolution set to fixed
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.