[GHC] #10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X

#10322: In ghci object code loader, linking against the previous temp dylib is not
enough on OS X
-------------------------------------+-------------------------------------
Reporter: rwbarton | Owner:
Type: bug | Status: new
Priority: high | Milestone: 7.10.2
Component: Compiler | Version: 7.10.1
Keywords: | Operating System: MacOS X
Architecture: | Type of failure: None/Unknown
Unknown/Multiple | Blocked By:
Test Case: | Related Tickets:
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
joelteon encountered this issue in a rather complicated program, and we
worked out the cause over IRC.
Suppose that ghci needs to sequentially load three modules A, B and C,
where B refers to symbols from A and C refers to symbols from both A and
B. (For example modules B, C and another module D all contain Template
Haskell that refers to the previous module(s).) The object code linker
currently works like this:
- Link the module `A.o` into a dylib `ghc_1.dylib`
- Link the module `B.o` against `ghc_1.dylib` into a new dylib
`ghc_2.dylib`
- Link the module `C.o` against `ghc_2.dylib` into a new dylib
`ghc_3.dylib`
As a result, `ghc_2.dylib` ends up with a NEEDED (or whatever it's called
in Mach-O) entry for `ghc_1.dylib`, and `ghc_3.dylib` ends up with a
NEEDED entry for `ghc_2.dylib`.
However, this apparently does not satisfy the OS X `dlopen`
implementation, which complains about a missing symbol `_A_foo` referenced
by `ghc_3.dylib` and which is defined in `ghc_1.dylib`. Apparently the
dynamic loader only checks the direct dependencies when trying to resolve
undefined symbols.
(The Linux dynamic loader seems to be perfectly happy to use an indirect
dependency to resolve an undefined symbol. But I found out that the linker
[https://sourceware.org/bugzilla/show_bug.cgi?id=10238 gold] has the same
sort of behavior as the OS X dynamic loader. I don't know whether there is
any standard here, but it seems that we cannot rely on the Linux dynamic
loader's behavior.)
Presumably the fix is to keep track of all the previous temporary dylibs
(rather than just one in `last_temp_so`) and link against all of them when
building a new temporary dylib. I'm slightly worried about quadratic
behavior here, but I think it's unlikely to be an issue in practice.
I have a reproducer at http://lpaste.net/808723564239781888 (which I'll
add to the test suite next) and oherrala ran the test on an OS X system
with the following results:
{{{
=====> Last(ghci) 1167 of 4480 [0, 0, 0]
cd ./ghci/scripts && HC="/Users/oherrala/gits/ghc/inplace/bin/ghc-stage2"
HC_OPTS="-dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db
-rtsopts -fno-warn-tabs -fno-ghci-history "
"/Users/oherrala/gits/ghc/inplace/bin/ghc-stage2" -dcore-lint -dcmm-lint
-dno-debug-output -no-user-package-db -rtsopts -fno-warn-tabs -fno-ghci-
history --interactive -v0 -ignore-dot-ghci +RTS -I0.1 -RTS

#10322: In ghci object code loader, linking against the previous temp dylib is not
enough on OS X
-------------------------------------+-------------------------------------
Reporter: rwbarton | Owner:
Type: bug | Status: new
Priority: high | Milestone: 7.10.2
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: MacOS X | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
Comment (by Reid Barton

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Changes (by rwbarton): * differential: => Phab:D852 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Comment (by George): Not sure but the -flat_namespace option might be what you are looking for. Following is from the Mac man page for ld. I wonder if ghc has always had this bug or if this is a regression. == Two-level namespace == By default all references resolved to a dynamic library record the library to which they were resolved. At runtime, dyld uses that information to directly resolve symbols. The alternative is to use the -flat_namespace option. With flat namespace, the library is not recorded. At runtime, dyld will search each dynamic library in load order when resolving symbols. This is slower, but more like how other operating systems resolve symbols. == Indirect dynamic libraries == If the command line specifies to link against dylib A, and when dylib A was built it linked against dylib B, then B is considered an indirect dylib. When linking for two-level namespace, ld does not look at indirect dylibs, except when re-exported by a direct dylibs. On the other hand when linking for flat namespace, ld does load all indirect dylibs and uses them to resolve references. Even though indirect dylibs are specified via a full path, ld first uses the specified search paths to locate each indirect dylib. If one cannot be found using the search paths, the full path is used. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Changes (by George): * cc: George (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: patch Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Changes (by thoughtpolice): * status: new => patch -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not
enough on OS X
-------------------------------------+-------------------------------------
Reporter: rwbarton | Owner:
Type: bug | Status: patch
Priority: high | Milestone: 7.10.2
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: MacOS X | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions: Phab:D852
-------------------------------------+-------------------------------------
Comment (by Austin Seipp

#10322: In ghci object code loader, linking against the previous temp dylib is not
enough on OS X
-------------------------------------+-------------------------------------
Reporter: rwbarton | Owner:
Type: bug | Status: patch
Priority: high | Milestone: 7.10.2
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: MacOS X | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions: Phab:D852
-------------------------------------+-------------------------------------
Comment (by Austin Seipp

#10322: In ghci object code loader, linking against the previous temp dylib is not
enough on OS X
-------------------------------------+-------------------------------------
Reporter: rwbarton | Owner:
Type: bug | Status: patch
Priority: high | Milestone: 7.10.2
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: MacOS X | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions: Phab:D852
-------------------------------------+-------------------------------------
Comment (by trommler):
Replying to [comment:8 Austin Seipp
In [changeset:"470a94947b076cb74a6adcbcf9b39057a67e1fba/ghc"]: {{{ [...] It apparently made Harbormaster sad. }}} Do you have details on what went wrong with Harbormaster?
Linking all libraries looked to me like the most promising way to do dynamic linking in the future and also to implement library unload. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: patch Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Comment (by trommler): Replying to [comment:4 George]:
Not sure but the -flat_namespace option might be what you are looking for. How bad as in breaking assumptions made by MacOS would it be to use `-flat_namespace`?
-- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: patch Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Changes (by a.ulrich): * cc: a.ulrich (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not
enough on OS X
-------------------------------------+-------------------------------------
Reporter: rwbarton | Owner:
Type: bug | Status: patch
Priority: high | Milestone: 7.10.2
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: MacOS X | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions: Phab:D852
-------------------------------------+-------------------------------------
Comment (by Austin Seipp

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: merge Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Changes (by thoughtpolice): * status: patch => merge -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: closed Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: fixed | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Changes (by thoughtpolice): * status: merge => closed * resolution: => fixed Comment: Merged to `ghc-7.10`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: closed Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: fixed | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Comment (by rwbarton): Replying to [comment:10 trommler]:
Replying to [comment:4 George]:
Not sure but the -flat_namespace option might be what you are looking for. How bad as in breaking assumptions made by MacOS would it be to use `-flat_namespace`?
I don't know, but I found this cryptic comment in `compiler/main/SysTools.hs`: -- This feature requires Mac OS X 10.3 or later; there is -- a similar feature, -flat_namespace -undefined suppress, -- which works on earlier versions, but it has other -- disadvantages. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10322: In ghci object code loader, linking against the previous temp dylib is not enough on OS X -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: closed Priority: high | Milestone: 7.10.2 Component: Compiler | Version: 7.10.1 Resolution: fixed | Keywords: Operating System: MacOS X | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D852 -------------------------------------+------------------------------------- Comment (by George): see also #10568 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10322#comment:16 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC