ghci segfault on OS X after dlsym failed lookup
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.
Trac metadata
Trac field | Value |
---|---|
Version | 7.2.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | GHCi |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |