[GHC] #10531: modules that can be linked successfully when compiled with optimizations, fail to link with: multiple definition of `__stginit_ZCMain'

GHC ghc-devs at haskell.org
Mon Jun 15 21:01:36 UTC 2015


#10531: modules that can be linked successfully when compiled with optimizations,
fail to link with: multiple definition of `__stginit_ZCMain'
-------------------------------------+-------------------------------------
        Reporter:  imz               |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.6.1
      Resolution:                    |                Keywords:
Operating System:  Linux             |            Architecture:  x86_64
 Type of failure:  GHC rejects       |  (amd64)
  valid program                      |               Test Case:  attached
      Blocked By:                    |                Blocking:
 Related Tickets:  437               |  Differential Revisions:
-------------------------------------+-------------------------------------
Description changed by imz:

Old description:

> When compiling a set of 3 modules (in a certain order), linking of the
> final executable fails because there conflicting symbols in some of the
> `.o`.
>
> When doing the compilation in the same order, but with optimizations, it
> succeeds.
>
> The simple test case:
>
> A.hs:
>
> {{{#!hs
> module A where
> main :: IO ()
> main = putStrLn "A"
> }}}
>
> B.hs:
>
> {{{#!hs
> module B where
> import A()
> main :: IO ()
> main = putStrLn "B"
> }}}
>
> C.hs:
>
> {{{#!hs
> import B()
> main :: IO ()
> main = putStrLn "hi"
> }}}
>
> When I compile it with in the order specified by the attached `./bug-
> reproduce.sh` and `Makefile`, the following happens:
>
> {{{
> ./bug-reproduce.sh
> rm -fv a A.o A.hi
> removed 'a'
> removed 'A.o'
> removed 'A.hi'
> rm -fv b B.o B.hi
> removed 'b'
> removed 'B.o'
> removed 'B.hi'
> rm -fv c C.o C.hi
> removed 'c'
> removed 'C.o'
> removed 'C.hi'
> ghc -Wall  A.hs -main-is A.main -o a
> [1 of 1] Compiling A                ( A.hs, A.o )
> Linking a ...
> ghc -Wall  B.hs -main-is B.main -o b
> [1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
> [2 of 2] Compiling B                ( B.hs, B.o )
> Linking b ...
> ghc -Wall  C.hs -o c
> [2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
> [3 of 3] Compiling Main             ( C.hs, C.o )
> Linking c ...
> removed 'A.o'
> ghc -Wall  A.hs -main-is A.main -o a
> [1 of 1] Compiling A                ( A.hs, A.o )
> Linking a ...
> ghc -Wall  B.hs -main-is B.main -o b
> [2 of 2] Compiling B                ( B.hs, B.o ) [flags changed]
> Linking b ...
> ./A.o: In function `siv_closure':
> (.data+0x0): multiple definition of `__stginit_ZCMain'
> B.o:(.data+0x0): first defined here
> ./A.o: In function `ZCMain_main_srt':
> (.data+0x70): multiple definition of `ZCMain_main_closure'
> B.o:(.data+0x70): first defined here
> ./A.o:(.text+0xb8): multiple definition of `ZCMain_main_info'
> B.o:(.text+0xb8): first defined here
> collect2: error: ld returned 1 exit status
> make: *** [B.o] Error 1
> }}}
>
> But it succeeds if done as `./bug-reproduce.sh GHC_OPTS=-O1` (probably,
> the optimizations remove the conflicting symbols):
>
> {{{
> ./bug-reproduce.sh GHC_OPTS=-O1
> rm -fv a A.o A.hi
> removed 'a'
> removed 'A.o'
> removed 'A.hi'
> rm -fv b B.o B.hi
> removed 'b'
> removed 'B.o'
> removed 'B.hi'
> rm -fv c C.o C.hi
> removed 'c'
> removed 'C.o'
> removed 'C.hi'
> ghc -Wall -O1 A.hs -main-is A.main -o a
> [1 of 1] Compiling A                ( A.hs, A.o )
> Linking a ...
> ghc -Wall -O1 B.hs -main-is B.main -o b
> [1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
> [2 of 2] Compiling B                ( B.hs, B.o )
> Linking b ...
> ghc -Wall -O1 C.hs -o c
> [2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
> [3 of 3] Compiling Main             ( C.hs, C.o )
> Linking c ...
> removed 'A.o'
> ghc -Wall -O1 A.hs -main-is A.main -o a
> [1 of 1] Compiling A                ( A.hs, A.o )
> Linking a ...
> ghc -Wall -O1 B.hs -main-is B.main -o b
> [1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
> [2 of 2] Compiling B                ( B.hs, B.o ) [flags changed]
> Linking b ...
> ghc -Wall -O1 C.hs -o c
> [2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
> Linking c ...
> }}}
>
> Couldn't the compiler detect and handle such cases?

New description:

 When compiling a set of 3 modules (in a certain order), linking of the
 final executable fails because there are conflicting symbols in some of
 the `.o`.

 When doing the compilation in the same order, but with optimizations, it
 succeeds.

 The simple test case:

 A.hs:

 {{{#!hs
 module A where
 main :: IO ()
 main = putStrLn "A"
 }}}

 B.hs:

 {{{#!hs
 module B where
 import A()
 main :: IO ()
 main = putStrLn "B"
 }}}

 C.hs:

 {{{#!hs
 import B()
 main :: IO ()
 main = putStrLn "hi"
 }}}

 When I compile it with in the order specified by the attached `./bug-
 reproduce.sh` and `Makefile`, the following happens:

 {{{
 ./bug-reproduce.sh
 rm -fv a A.o A.hi
 removed 'a'
 removed 'A.o'
 removed 'A.hi'
 rm -fv b B.o B.hi
 removed 'b'
 removed 'B.o'
 removed 'B.hi'
 rm -fv c C.o C.hi
 removed 'c'
 removed 'C.o'
 removed 'C.hi'
 ghc -Wall  A.hs -main-is A.main -o a
 [1 of 1] Compiling A                ( A.hs, A.o )
 Linking a ...
 ghc -Wall  B.hs -main-is B.main -o b
 [1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
 [2 of 2] Compiling B                ( B.hs, B.o )
 Linking b ...
 ghc -Wall  C.hs -o c
 [2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
 [3 of 3] Compiling Main             ( C.hs, C.o )
 Linking c ...
 removed 'A.o'
 ghc -Wall  A.hs -main-is A.main -o a
 [1 of 1] Compiling A                ( A.hs, A.o )
 Linking a ...
 ghc -Wall  B.hs -main-is B.main -o b
 [2 of 2] Compiling B                ( B.hs, B.o ) [flags changed]
 Linking b ...
 ./A.o: In function `siv_closure':
 (.data+0x0): multiple definition of `__stginit_ZCMain'
 B.o:(.data+0x0): first defined here
 ./A.o: In function `ZCMain_main_srt':
 (.data+0x70): multiple definition of `ZCMain_main_closure'
 B.o:(.data+0x70): first defined here
 ./A.o:(.text+0xb8): multiple definition of `ZCMain_main_info'
 B.o:(.text+0xb8): first defined here
 collect2: error: ld returned 1 exit status
 make: *** [B.o] Error 1
 }}}

 But it succeeds if done as `./bug-reproduce.sh GHC_OPTS=-O1` (probably,
 the optimizations remove the conflicting symbols):

 {{{
 ./bug-reproduce.sh GHC_OPTS=-O1
 rm -fv a A.o A.hi
 removed 'a'
 removed 'A.o'
 removed 'A.hi'
 rm -fv b B.o B.hi
 removed 'b'
 removed 'B.o'
 removed 'B.hi'
 rm -fv c C.o C.hi
 removed 'c'
 removed 'C.o'
 removed 'C.hi'
 ghc -Wall -O1 A.hs -main-is A.main -o a
 [1 of 1] Compiling A                ( A.hs, A.o )
 Linking a ...
 ghc -Wall -O1 B.hs -main-is B.main -o b
 [1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
 [2 of 2] Compiling B                ( B.hs, B.o )
 Linking b ...
 ghc -Wall -O1 C.hs -o c
 [2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
 [3 of 3] Compiling Main             ( C.hs, C.o )
 Linking c ...
 removed 'A.o'
 ghc -Wall -O1 A.hs -main-is A.main -o a
 [1 of 1] Compiling A                ( A.hs, A.o )
 Linking a ...
 ghc -Wall -O1 B.hs -main-is B.main -o b
 [1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
 [2 of 2] Compiling B                ( B.hs, B.o ) [flags changed]
 Linking b ...
 ghc -Wall -O1 C.hs -o c
 [2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
 Linking c ...
 }}}

 Couldn't the compiler detect and handle such cases?

--

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10531#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list