id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,difficulty,testcase,blockedby,blocking,related
5748,ghci segfault on OS X after dlsym failed lookup,gwright,igloo,"I've had repeatable segfaults with ghci 7.2.2 (OS X 10.6) and 7.0.4 (OS X 10.7 and 10.6).  The immediate cause is a failed lookup of an external symbol in {{{rts/Linker.c}}}.  The failure is not detected and the NULL value returned is eventually dereferenced, leading to a segfault.  The underlying bug is still present in HEAD.

This is what happens:
{{{
gwright-macbook> ghci -v Test.hs
GHCi, version 7.2.2: http://www.haskell.org/ghc/  :? for help
Glasgow Haskell Compiler, Version 7.2.2, stage 2 booted by GHC version 7.0.4
Using binary package database: /usr/local/lib/ghc-7.2.2/package.conf.d/package.cache
Using binary package database: /Users/gwright/.ghc/x86_64-darwin-7.2.2/package.conf.d/package.cache
hiding package Cabal-1.12.0 to avoid conflict with later version Cabal-1.13.3
wired-in package ghc-prim mapped to ghc-prim-0.2.0.0-14e0c022e5d4efa3a40ab5991f2b2a1b
wired-in package integer-gmp mapped to integer-gmp-0.3.0.0-2e2b0fd56be1a5f60c50913e615691d9
wired-in package base mapped to base-4.4.1.0-5ca60b2acbb66fd59e5f81685cb72740
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.6.0.0-e7db5d1205f362bb792ab7bd5c7bbfae
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags: -static
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
*** Chasing dependencies:
Chasing modules from: 
Stable obj: []
Stable BCO: []
unload: retaining objs []
unload: retaining bcos []
Ready for upsweep []
Upsweep completely successful.
*** Deleting temp files:
Deleting: 
*** Chasing dependencies:
Chasing modules from: *Test.hs
Stable obj: []
Stable BCO: []
unload: retaining objs []
unload: retaining bcos []
Ready for upsweep
  [NONREC
      ModSummary {
         ms_hs_date = Sun Jan  1 18:20:14 EST 2012
         ms_mod = main:Main,
         ms_textual_imps = [import Prelude,
                            import Math.Symbolic.Wheeler.TensorUtilities,
                            import Math.Symbolic.Wheeler.TensorBasics,
                            import Math.Symbolic.Wheeler.Tensor,
                            import Math.Symbolic.Wheeler.IO,
                            import Math.Symbolic.Wheeler.Symbol,
                            import Math.Symbolic.Wheeler.Numeric,
                            import Math.Symbolic.Wheeler.Expr,
                            import Math.Symbolic.Wheeler.Commutativity,
                            import Math.Symbolic.Wheeler.Canonicalize,
                            import Math.Symbolic.Wheeler.Basic, import Data.Ratio,
                            import Data.Maybe]
         ms_srcimps = []
      }]
*** Deleting temp files:
Deleting: 
compile: input file Test.hs
Created temporary directory: /var/folders/4j/4jmo0VgVHgu2WNrlXKFTB++++TI/-Tmp-/ghc61560_1
*** Checking old interface for main:Main:
[1 of 1] Compiling Main             ( Test.hs, interpreted )
*** Parser:
*** Renamer/typechecker:
*** Desugar:
Result size of Desugar = 788
*** Simplifier:
Result size of Simplifier iteration=1 = 800
Result size of Simplifier = 788
*** Tidy Core:
Result size of Tidy Core = 788
*** CorePrep:
Result size of CorePrep = 1010
*** ByteCodeGen:
Upsweep completely successful.
*** Deleting temp files:
Deleting: /var/folders/4j/4jmo0VgVHgu2WNrlXKFTB++++TI/-Tmp-/ghc61560_1/ghc61560_0.c /var/folders/4j/4jmo0VgVHgu2WNrlXKFTB++++TI/-Tmp-/ghc61560_1/ghc61560_0.o
Warning: deleting non-existent /var/folders/4j/4jmo0VgVHgu2WNrlXKFTB++++TI/-Tmp-/ghc61560_1/ghc61560_0.c
Warning: deleting non-existent /var/folders/4j/4jmo0VgVHgu2WNrlXKFTB++++TI/-Tmp-/ghc61560_1/ghc61560_0.o
Ok, modules loaded: Main.
*Main> x
*** Parser:
*** Desugar:
*** Simplify:
*** CorePrep:
*** ByteCodeGen:
Loading package bytestring-0.9.2.0 ... linking ... done.
Loading package transformers-0.2.2.0 ... linking ... done.
Loading package mtl-2.0.1.0 ... linking ... done.
Loading package array-0.3.0.3 ... linking ... done.
Loading package deepseq-1.2.0.1 ... linking ... done.
Loading package text-0.11.1.12 ... linking ... done.
Loading package parsec-3.1.2 ... linking ... done.
Loading package uniqueid-0.1.1 ... linking ... done.
Loading package Wheeler-0.1 ... linking ... done.
Segmentation fault
gwright-macbook> 
}}}

The program is trying to display a record type (the variable ""x"").  The record type has a Show instance associated with it, and that is apparently not being resolved correctly, leading to a NULL dereference and a segfault.

The problem is isolated to OS X as far as I can tell. The code responsible for the error is in the function {{{relocateSection}}}:

{{{
        else if(reloc->r_extern)
        {
            struct nlist *symbol = &nlist[reloc->r_symbolnum];
            char *nm = image + symLC->stroff + symbol->n_un.n_strx;

            IF_DEBUG(linker, debugBelch(""relocateSection: looking up external symbol %s\n"", nm));
            IF_DEBUG(linker, debugBelch(""               : type  = %d\n"", symbol->n_type));
            IF_DEBUG(linker, debugBelch(""               : sect  = %d\n"", symbol->n_sect));
            IF_DEBUG(linker, debugBelch(""               : desc  = %d\n"", symbol->n_desc));
            IF_DEBUG(linker, debugBelch(""               : value = %p\n"", (void *)symbol->n_value));
            if ((symbol->n_type & N_TYPE) == N_SECT) {
                value = relocateAddress(oc, nSections, sections,
                                        symbol->n_value);
                IF_DEBUG(linker, debugBelch(""relocateSection, defined external symbol %s, relocated address %p\n"", nm, (void *)value));
            }
            else {
                value = (uint64_t) lookupSymbol(nm);
                IF_DEBUG(linker, debugBelch(""relocateSection: external symbol %s, address %p\n"", nm, (void *)value));
            }
        }
}}}

The returned value from {{{lookupSymbol}}} is not checked for failure.
A simple check for NULL and a call to {{{errorBelch}}} is all that's needed to fix this.  There's another place where the return value from {{{lookupSymbol}}} is not checked and it should be fixed similarly.

In a bit more detail, the program ""Test.hs"" I was loading does some simple tests on a library.  I admit to having been sloppy while sorting out the module exports, but the library compiles without warnings when -Wall is set.  The library has a top-level module that re-exports the most commonly used symbols, but the test program doesn't use it, importing all of the modules it needs explicitly.  Am I doing something that is known to be dangerous?

The failed symbol lookup is 

{{{
lookupSymbol: looking up _Wheelerzm0zi1_MathziSymbolicziWheelerziSimpleSymbol_zdfShowSzuzdcshowsPrec_closure
}}}

which is the Show instance for a {{{SimpleSymbol}}} data type.  (The library implements a symbolic algebra DSL.)  The symbol is undefined in the object module:

{{{
gwright-macbook> nm HSWheeler-0.1.o  | grep ""_Wheelerzm0zi1_MathziSymbolicziWheelerziSimpleSymbol_zdfShowSzuzdcshowsPrec_closure""
                 U _Wheelerzm0zi1_MathziSymbolicziWheelerziSimpleSymbol_zdfShowSzuzdcshowsPrec_closure
gwright-macbook> 
}}}

so some sort of failure is expected when I try to show something of the {{{SimpleSymbol}}} type.

I'm puzzled that the first indication of failure is a segfault, or, after I patch {{{rts/Linker.c}}}, an error from deep inside the linker.  It seems that there is something else going wrong which ought to generate a warning at least.

I will generate a patch against HEAD to check for the failed symbol lookups; it would be good if it were included in the final 7.4.1.",bug,closed,highest,7.4.1,GHCi,7.2.1,fixed,,pho@…,MacOS X,Unknown/Multiple,GHCi crash,Unknown,,,,
