Opened 6 years ago

Closed 5 years ago

Last modified 4 years ago

#5373 closed bug (fixed)

-rtsopts is not respected with -dynamic on Windows

Reported by: simonmar Owned by: simonmar
Priority: high Milestone: 7.4.1
Component: Compiler Version: 7.0.4
Keywords: Cc: bill@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: T5373
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


This gives rise to a large number of test failures of the kind

=====> stableptr001(dyn) 1297 of 2878 [4, 54, 8]
cd ./lib/should_run && 'D:/slave/stable/builder/tempbuild/build/bindisttest/install dir/bin/ghc.exe' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-conf -rtsopts -o stableptr001 stableptr001.hs -O -dynamic >stableptr001.comp.stderr 2>&1
cd ./lib/should_run && ./stableptr001 +RTS -K8m -RTS </dev/null > 2>
Wrong exit code (expected 0 , actual 1 )
stableptr001.exe: Most RTS options are disabled. Link with -rtsopts to enable them.
*** unexpected failure for stableptr001(dyn)

The problem is that -rtsopts relies on compiling a small C file with a definition for rtsOptsEnabled, and linking this object into the executable, thereby overriding the default definition of rtsOptsEnabled in rts/hooks/RtsOptsEnabled.c. This works with static linking semantics and Unix dynamic linking semantics, but not Windows dynamic linking semantics. On Windows, the references to rtsOptsEnabled in the RTS are statically bound to the default definition.

I think we ought to be able to solve it by generating a constructor function to initialise rtsOptsEnabled, like this:

extern RtsOptsEnabledEnum  __attribute__((dllimport)) rtsOptsEnabled;

static void __attribute__((constructor)) init(void)
    rtsOptsEnabled = RtsOptsAll;

I tried this but didn't get it to work, so I'm leaving it for now.

Change History (9)

comment:1 Changed 5 years ago by btutt

Cc: bill@… added

comment:2 Changed 5 years ago by igloo

Owner: set to igloo

comment:3 Changed 5 years ago by igloo

Owner: igloo deleted

This also fails on OS X, and I've also failed to get it to work.

comment:4 Changed 5 years ago by igloo

Test Case: T5373

comment:5 Changed 5 years ago by simonmar

A solution probably exists along these lines: in the C file we generate at link time, also generate the C main function, which is currently:

int main(int argc, char *argv[])
    return hs_main(argc, argv, &ZCMain_main_closure);

but we could change the API of hs_main to take the RtsOptsEnabled flag (or use some other way of passing that flag to the RTS).

comment:6 Changed 5 years ago by simonmar

Owner: set to simonmar

comment:7 Changed 5 years ago by marlowsd@…

commit 1df28a805b465a28b61f4cfe4db28f247a183206

Author: Simon Marlow <>
Date:   Tue Nov 15 15:43:28 2011 +0000

    Generate the C main() function when linking a binary (fixes #5373)
    Rather than have main() be statically compiled as part of the RTS, we
    now generate it into the tiny C file that we compile when linking a
    The main motivation is that we want to pass the settings for the
    -rtsotps and -with-rtsopts flags into the RTS, rather than relying on
    fragile linking semantics to override the defaults, which don't work
    with DLLs on Windows (#5373).  In order to do this, we need to extend
    the API for initialising the RTS, so now we have:
    void hs_init_ghc (int *argc, char **argv[],   // program arguments
                      RtsConfig rts_config);      // RTS configuration
    hs_init_ghc() can optionally be used instead of hs_init(), and allows
    passing in configuration options for the RTS.  RtsConfig is a struct,
    which currently has two fields:
    typedef struct {
        RtsOptsEnabledEnum rts_opts_enabled;
        const char *rts_opts;
    } RtsConfig;
    but might have more in the future.  There is a default value for the
    struct, defaultRtsConfig, the idea being that you start with this and
    override individual fields as necessary.
    In fact, main() was in a separate static library, libHSrtsmain.a.
    That's now gone.

 compiler/main/DriverPipeline.hs |   49 ++++++++++++++++++++-------------------
 includes/Rts.h                  |    1 +
 includes/RtsAPI.h               |   48 ++++++++++++++++++++++++++++++++++----
 includes/RtsOpts.h              |   20 ----------------
 includes/rts/Main.h             |   21 ++++++++++++++++
 rts/Main.c                      |   24 -------------------
 rts/RtsFlags.c                  |   26 +++++++++++---------
 rts/RtsFlags.h                  |    4 ++-
 rts/RtsMain.c                   |   19 ++++++++------
 rts/RtsMain.h                   |   19 ---------------
 rts/RtsStartup.c                |   14 ++++++++++-
 rts/                      |   13 +---------
 rts/hooks/RtsOpts.c             |   14 -----------
 13 files changed, 132 insertions(+), 140 deletions(-)

comment:8 Changed 5 years ago by simonmar

Resolution: fixed
Status: newclosed

comment:9 Changed 4 years ago by marlowsd@…

commit 9a3c8bd700a63dadcf1e238408b490908cbf6765

Author: Simon Marlow <>
Date:   Thu Aug 23 09:49:12 2012 +0100

    Emit a warning for -rtsopts -shared, as well as -rtsopts -no-hs-main
    -rtsopts has no effect with -shared, so we should emit a warning.  See
     #5373 and #7177.

 compiler/main/DriverPipeline.hs |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)
Note: See TracTickets for help on using tickets.