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

#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 Keywords: | Operating System: Linux Architecture: x86_64 | Type of failure: GHC rejects (amd64) | valid program Test Case: attached | Blocked By: Blocking: | Related Tickets: Differential Revisions: | -------------------------------------+------------------------------------- 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? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by ezyang): The manual suggests that recompilation checking doesn't really work with `-main-is`: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/options- phases.html (the problem being that when you build `B.hs` the second time, it needs to recompile `A.hs` with a DIFFERENT `-main-is` flag.) But it sort of looks like dterei tried to fix this in #437, so maybe this was intended to be fixed, and the manual wasn't updated? In any case, this looks like a fine bug to me. Once fixed the admonition from the manual should be removed. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by imz): One difference is that without `-O1` it doesn't recompile `A.hs` when compiling `B.hs`, whereas with `-O1` it does (although superficially there is no extra reason to do so in the second case, i.e., no change in flags which might cause this: `A.hs` has been compiled with `-O1` already in the second case; it could be understood if `-O1` always caused recompilation, no matter what the previous flags were): {{{ 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' }}} vs {{{ 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 ... }}} (success) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: -------------------------------------+------------------------------------- Changes (by imz): * related: => 437 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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

#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: -------------------------------------+------------------------------------- Comment (by imz): Strangely, this happens only on the second pass, after removing `A.o`. Although the sequence of actions is the same in the first pass, there are no errors in the first pass. (I've noticed a field named "Test Case" in the description. Should I write it according to https://ghc.haskell.org/trac/ghc/wiki/Building/RunningTests/Adding and request a pull? Or what am I supposed to submit a test-case? I'm not sure that the repeating the compilation commands can be described easily in that format...) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: -------------------------------------+------------------------------------- Changes (by rwbarton): * related: 437 => #437 Comment: So the problem here is that while the interface file contains a hash of flags like `-main-is`, that hash isn't incorporated into the top-level interface hash. When you remove `A.o` (but ''not'' `A.hi`) and then rebuild `a`, GHC builds a new `A.o` with the symbols like `ZCMain_main_info` but doesn't update the interface file `A.hi` on disk accordingly, because it thinks it hasn't changed (the interface hash didn't change because it doesn't include the flag hash). Then when building `b` GHC sees that the interface file claims that main was not A.main when A was built, so GHC sees no need to recompile A. Relevant code starts at https://github.com/ghc/ghc/blob/bac927b9770ff769128b66d13a3e72bf5a9bc514/com.... This looks like an easy fix except there are a few comments there I don't understand, like the one about two hashes being returned for the flag hash and the one that claims that the ABI hash depends on "flag abi hash". (Perhaps they apply to a version of the patch for #437 from before it was committed?) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: -------------------------------------+------------------------------------- Comment (by imz): But somehow if `-O1` is added everywhere, it sees the need to recompile A when building `b`. Isn't that a disturbing inconsistency? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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: -------------------------------------+------------------------------------- Comment (by rwbarton): With optimization enabled, another identifier `main4` appears in the interface file for A, but only when `-main-is A.main` (`ZCMain_main_info` is a jump to `main4`). So because of this change, a new interface file gets written out, which then has the correct flag hash as well. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#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 (Linking) | 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 Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by rimmington): * cc: rimmington (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10531#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC