enormous binaries

Willem Robert van Hage wrvh@xs4all.nl
Sat, 29 Sep 2001 10:06:21 +0200


--rwEMma7ioTxnRzrJ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Hello,

I'm trying out GHC along with gtk+hs and iHaskell
and I was surprised that a simple example with a list of selectable
distribution names generated a binary of 2Mb.
So I tried a simple hello world example exactly like the one
I saw somewhere on the GHC pages that compiled to a binary of 6kb
and I was surprised to see that even after stripping the binary
it still takes up 140kb.
Is there a good explanation for this? Am I doing something wrong
or is it something else?

~/haskell/ghc-test % cat hello.hs
module Main where
main = putStrLn "hello, world!"

~/haskell/ghc-test % ghc -o hello hello.hs
~/haskell/ghc-test % ls -l
total 212
-rwxr-xr-x    1 willem   users      201453 Sep 29 09:55 hello
-rw-r--r--    1 willem   users          51 Sep 29 09:54 hello.hs
-rw-r--r--    1 willem   users        1468 Sep 29 09:55 hello.o
~/haskell/ghc-test % strip hello
~/haskell/ghc-test % ls -l
total 152
-rwxr-xr-x    1 willem   users      141024 Sep 29 09:59 hello
-rw-r--r--    1 willem   users          51 Sep 29 09:54 hello.hs
-rw-r--r--    1 willem   users        1468 Sep 29 09:55 hello.o
~/haskell/ghc-test % strings hello > strs

I attached the file strs, maybe someone can deduce something from
its contents...

Willem van Hage

-- 
wrvh@xs4all.nl         | http://www.xs4all.nl/~wrvh
wrvhage@science.uva.nl | http://quest.sourceforge.net

--rwEMma7ioTxnRzrJ
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=strs

/lib/ld-linux.so.2
libm.so.6
_IO_stdin_used
__gmon_start__
libgmp.so.3
_DYNAMIC
__gmpz_divexact
__gmpz_gcd
__gmpz_mul
_init
__gmpz_com
__gmpz_init
__gmpz_xor
__gmpz_and
__gmpz_ior
__gmpz_add
__gmpz_fdiv_qr
__gmpz_tdiv_qr
__gmpz_tdiv_r
_fini
_GLOBAL_OFFSET_TABLE_
__gmpz_tdiv_q
__gmp_set_memory_functions
__gmpz_sub
libc.so.6
strcpy
siginterrupt
printf
sysconf
__strtod_internal
stdout
sigemptyset
times
memcpy
setitimer
perror
__cxa_finalize
malloc
isatty
select
fflush
__umoddi3
lseek
sigaddset
mmap
__udivdi3
abort
__lxstat
strrchr
write
fprintf
__deregister_frame_info
read
unlink
getrusage
realloc
sigaction
gettimeofday
tcgetattr
strcmp
sprintf
fclose
stderr
__errno_location
exit
__fxstat
sigdelset
fopen
__libc_start_main
open
fcntl
tcsetattr
__register_frame_info
close
vfprintf
free
sigprocmask
_edata
__bss_start
_end
GLIBC_2.1.3
GLIBC_2.1
GLIBC_2.0
PTRhp,
;CXs
;CXr
;{`v
;CXr
;{`v
;CTv
;CXs
;CXr
;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
;CXr
;{`v
;CXs
;CTv
 ;{`v
;CXr
;{`v
;{`v
;CTv
;CXs
;{`v
;{`v
 ;{`v
;CTv
;CXs
;CTv
;{`v
;CTv
;{`v
;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;{`v
;CTv
;{`v
;CTv
;CTv
;CXs"
stdout
;CXr
;{`v
;CTv
;CTv
;CXs
;CTv
;{`v
;CTv
;CXs
;{`v
;CXs
 ;{`v
;CTv
;CXs
;CTv
;{`v
;CTv
;CXs
;{`v
;CXs
 ;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
$;{`v
;CTv
;{`v
;CTv
;CTv
;CXs
hPutStr
;CXr
;{`v
hPutChar
;CXr
;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;{`v
;{`v
;CTv
;CXs 
;{`v
;{`v
;CTv
4;{`v
;CXs
;CXs
;{`v
;CXs
;CXr
;{`v
;CTv
;CTv
;{`v"
;CXr
;{`v
;CTv
;CXs
;CXs
;{`v
closed file
;CXr
;{`v
;CXr
;{`v
;CTv
;CXs
;CTv
;CXs
 ;{`v
;CTv
;CXs
;CTv
;CXr
 ;{`v
;{`v
$;{`v
4;{`v
;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
;{`v
;{`v
;CTv
;CXs
(;{`v
;CXs
0;{`v
;CTv
,;{`v
;CTv
;CXs
;CTv
;CXs
;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
(error code: 
;CXr
;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;{`v
;{`v
;CTv
;{`v
;CTv
;{`v
;CXs
gfff
;CXr
;{`v
gfff
;CXs
;CTv
;CXs"
;{`v
handle is not open for writing
;CXr
;{`v
;CTv
;CTv
 ;{`v
;CXr
;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
$;{`v
;CTv
;CXs"
,;{`v
commitAndReleaseBuffer
;CXr
;{`v
;CTv
;CXs
;CTv
;{`v
;{`v
;CTv
;{`v
;CTv
;{`v
;{`v 
;{`v
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
;CTv
;CXs
malloc
;CXr
;{`v
out of memory
;CXr
;{`v
;CTv
;CXs
;CXs
;{`v
;CXs
;{`v
;CXs
;{`v
;CXs
;{`v
;CTv
;CXs
;CXs
;CTv
;{`v
;{`v
;CXs
;CXs
;{`v
;CXs
;{`v
;CXs
;CXr
;{`v
;{`v
;CXs
;CXr
;{`v
;CXs
;{`v
;CXr
;{`v
;CTv
;{`v
$;{`v
;CTv
;CTv
;CXs 
;{`v
;CTv
;{`v
gfff
;CXs
gfff
;CTv
;CTv
;CTv
handle is closed
;CXr
;{`v
;CTv
;CTv
;CXs
;CTv
;CXs
;CXr
;{`v
commitBuffer
;CXr
;{`v
unknown exception
;CXr
;{`v
thread blocked indefinitely
;CXr
;{`v
<<loop>>
;CXr
;{`v
arithmetic overflow
;CXr
;{`v
arithmetic underflow
;CXr
;{`v
loss of precision
;CXr
;{`v
divide by zero
;CXr
;{`v
denormal
;CXr
;{`v
stack overflow
;CXr
;{`v
heap overflow
;CXr
;{`v
thread killed
;CXr
;{`v
;CTv
;CXs
Action: 
;CXr
;{`v
Handle: 
;CXr
;{`v
File: 
;CXr
;{`v
Reason: 
;CXr
;{`v
;CXr
;{`v
array index out of range
;CXr
;{`v
undefined array element
;CXr
;{`v
;CTv
;{`v
;CTv
;CXs
;{`v
;CTv
;CXs
;CXr
;{`v
;{`v
;CXs
;CTv
;{`v
;{`v
;{`v
;CXs
;CTv
;{`v
;{`v
;CXs
;CXs
;CXr
;{`v
;CXr
;{`v
;{`v
;{`v
;{`v
;{`v
;{`v
;CXr
;{`v
;CXr
;{`v
;CXr
;{`v
;CTv
;{`v
 ;{`v
;CXr
;{`v
;CTv
;{`v
;CXr
;{`v
;CTv
;CXs
;CTv
;{`v
hFlush
;CXr
;{`v
;CTv
;CTv
semi-closed
;CXr
;{`v
readable
;CXr
;{`v
writeable
;CXr
;{`v
writeable (append)
;CXr
;{`v
read-writeable
;CXr
;{`v
;CTv
;CXs
;CTv
;CXs
already exists
;CXr
;{`v
hardware fault
;CXr
;{`v
illegal operation
;CXr
;{`v
inappropriate type
;CXr
;{`v
interrupted
;CXr
;{`v
invalid argument
;CXr
;{`v
does not exist
;CXr
;{`v
failed
;CXr
;{`v
permission denied
;CXr
;{`v
protocol error
;CXr
;{`v
resource busy
;CXr
;{`v
resource exhausted
;CXr
;{`v
resource vanished
;CXr
;{`v
system error
;CXr
;{`v
timeout
;CXr
;{`v
unsatisified constraints
;CXr
;{`v
unsupported operation
;CXr
;{`v
end of file
;CXr
;{`v
loc=
;CXr
;{`v
type=
;CXr
;{`v
;CXr
;{`v
buffering=
;CXr
;{`v
block 
;CXr
;{`v
;CTv
;CXr
;{`v
;CXs
new_ps_array
;CXr
;{`v
;CTv
;CXr
;{`v
;{`v
;CTv
;CXs
none
;CXr
;{`v
line
;CXr
;{`v
closed
;CXr
;{`v
lWVS
lWVS
tEA;
t;A;
uNF;5
~F;5
uNF;5
Ph@<
 [^_
 [^_
 [^_
 [^_
Ph ?
PhB?
t$,S
t$0S
SVh`?
UWVS
[^_]
WVS1
Ph@@
UWVS
[^_]
gfff
UWVS
L$<Q
L$P+A($
D$@f
[^_]
UWVS
T$,R
T$ f
[^_]
UWVS
[^_]
PhKB
t$ ;5
UWVS
D$$P
[^_]
UWVS
[^_]
UWVS
[^_]
UWVS
[^_]
UWVS
PhjD
T$LR
D$()
H9D$@u!
D$8;
[^_]
Sh E
$h@F
Ph@G
UWVS
Wh@I
VhYI
[^_]
,UWVS
$E;-
\$,;\
D$,;D
H9D$,r
+D$,
[^_]
|$$1
ths$
D$ =2
UWVS
FAB9
[^_]
,UWVS
9T$,s{
L$ 1
D$,[^_]
,UWVS
9D$,s
T$ 1
L$(A
T$$1
<G;|$$r
D$,[^_]
t$ 1
;CXs
;CXs
;sdu
;CXs
;{`vK
;{`vM
;{`vK
;{`vE
;{`vK
;{`vE
;{`vK
;{`vI
;{`vG
;{`vK
;{`vI
;{`vF
;{`vN
;{`vG
;{`vG
;{`vL
;{`vL
;{`vM
;{`vG
;{`vD
;{`vM
;{`vK
;{`vI
;{`vK
;{`vI
;{`vG
;{`vI
;{`vL
;{`v
;{`v
;{`v
;{`v
;{`v
;{`v
T$$RP
;{`v
D$,P
D$,P
D$,P
D$,P
D$,P
D$,P
D$,P
D$,P
D$,P
D$,P
D$(P
D$(P
D$8P
D$(P
D$(P
D$(P
D$8P
D$(P
;{`v
D$ P
;{`v
D$ P
;{`v
;{`v
;{`v
;{`v
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
;CXs
B;T$
;{`v
;CXs
B;T$
;CXs
UWVS
l$ 1
[^_]
 A;J
 C;Y
\UWVS
9D$8s)
L$$;|
T$0;|
l$$;-
L$$;|
F,9F u
9F0s
|$Ff
L$Ff
T$41
\$$;|
)D$4;-
l$$;-
|$Ff
L$Ff
T$DRV
L$PQ
\$XS
 [^_]
WVS1
UWVS
Ph@N
WhnN
[^_]
UWVS
Ph Q
Ph Q
T$(R
B 9D$
p0[^_]
Ph`R
UWVS
[^_]
UWVS
[^_]
UWVS
|$0;|$4
[^_]
UWVS
[^_]
UWVS
P,[^_]
UWVS
[^_]
,UWVS
l$()D$(u
[^_]
UWVS
[^_]
UWVS
t$01
D$<PV
L$<Q
D$89C
[^_]
UWVS
D$<P
[^_]
LUWVS
L$4Qh
;D$0
\$4)
9\$4
;L$0
;D$0rX
;D$0s
|$4)
B;T$
[^_]
UWVS
3hFc
3hLc
3hQc
:-t2
L$HQ
T$HR
gfff
t	<ct
T$8;2
[^_]
UWVS
[^_]
\$HIy
D$H[^
\$LIy
D$L[^
LWVS
uN9U
hello, world!
!	@ 
unexpected error
no error
argument list too long
inadequate access permission
address already in use
address not available
RFS advertise error
address family not supported by protocol family
insufficient resources
operation already in progress
internal error (EBADF)
next message has wrong type
invalid RPC request or response
device busy
no child processes
no virtual circuit could be found
aborted connection
no listener on remote host
connection reset by peer
resource deadlock avoided
destination address required
file system dirty
argument too large
quota exceeded
file already exists
internal error (EFAULT)
file too large
inappropriate NFS file type or format
destination host down
remote host is unreachable
IPC identifier removed
invalid wide character
operation now in progress
interrupted system call
invalid argument
unknown I/O fault
socket is already connected
file is a directory
too many symbolic links
process file table full
too many links
message too long
multi-hop RFS request
filename too long
network is down
remote host rebooted; connection lost
remote network is unreachable
system file table full
no buffer space available
no message on the stream head read queue
no such device
no such file or directory
not an executable file
no file locks available
RFS link has been severed
not enough virtual memory
no message of desired type
host is not on a network
operation not supported by protocol
no space left on device
out of stream resources
not a stream device
function not implemented
not a block device
socket is not connected
not a directory
directory not empty
not a socket
inappropriate ioctl for device
no such device or address
operation not supported on socket
privileged operation
protocol family not supported
broken pipe
too many processes
unimplemented RPC procedure
unsupported RPC program version
RPC program unavailable
error in streams protocol
protocol not supported
wrong protocol for socket
result too large
remote address changed
too many levels of remote in path
read-only file system
RPC version is wrong
object is remote
can't send after socket shutdown
socket type not supported
can't seek on a pipe
no such process
RFS resources still mounted by remote host(s)
stale NFS file handle
timer expired
connection timed out
too many references; can't splice
text file in-use
quota table full
operation would block
can't make a cross-device link
file is locked
openFile: unknown mode `%d'
file does not exist
dangling symlink
no path to file
unsupported owner or group
file is a directory
file is locked
enforced lock prevents truncation
no threads to run:  infinite loop or deadlock?
main thread exited (uncaught exception)
interrupted
main thread completed with invalid status
getChar: not a Char
getInt: not an Int
getWord: not a Word
getFloat: not a Float
getDouble: not a Double
getStablePtr: not a StablePtr
getPtr: not an Ptr
getBool: not a Bool
%s: uncaught exception
%s: interrupted
%s: no threads to run:  infinite loop or deadlock?
%s: Return code (%d) not ok
%s: fatal error: 
fatal error: 
%s: 
ASSERTION FAILED: file %s, line %u
Clock failed
%ld,%3.3ld
%ld%3.3ld
%ld,%3.3ld,%3.3ld
%ld%3.3ld%3.3ld
%ld,%3.3ld,%3.3ld,%3.3ld
%ld%3.3ld%3.3ld%3.3ld
schedule: invalid what_next field
schedule: invalid thread return code %d
resumeThread: thread not found
waitThread
unblockThread (MVAR): TSO not found
unblockThread (BLACKHOLE): TSO not found
unblockThread (Exception): TSO not found
unblockThread (I/O): TSO not found
unblockThread
raiseAsync
resurrectThreads: thread blocked in a strange way
AwaitEvent
select
select failed
awaitEvent
VM exhausted (in more_handlers)
too many pending signals
stg_sig_install: bad spi
failed to install SIGINT handler
getStablePtr: too light
initStablePtrTable
enlargeStablePtrTable
    Alloc    Collect    Live    GC    GC     TOT     TOT  Page Flts
    bytes     bytes     bytes  user  elap    user    elap
initStats
stat_init: bad call to 'sysconf'!
 GC 
%9ld %9ld %9ld
 %5.2f %5.2f %7.2f %7.2f %4ld %4ld  (Gen: %2ld)
%9ld %9.9s %9.9s
 %5.2f %5.2f
%11s bytes allocated in the heap
%11s bytes copied during GC
%11s bytes maximum residency (%ld sample(s))
%11d collections in generation %d (%6.2fs)
%11ld Mb total memory in use
  INIT  time  %6.2fs  (%6.2fs elapsed)
  MUT   time  %6.2fs  (%6.2fs elapsed)
  GC    time  %6.2fs  (%6.2fs elapsed)
  EXIT  time  %6.2fs  (%6.2fs elapsed)
  Total time  %6.2fs  (%6.2fs elapsed)
  %%GC time     %5.1f%%  (%.1f%% elapsed)
  Alloc rate    %s bytes per MUT second
  Productivity %5.1f%% of total user, %.1f%% of total elapsed
<<ghc: %lld bytes, %d GCs, %ld/%ld avg/max bytes residency (%ld samples), %ldM in use, %.2f INIT (%.2f elapsed), %.2f MUT (%.2f elapsed), %.2f GC (%.2f elapsed) :ghc>>
     Gen    Steps      Max   Mutable  Mut-Once  Step   Blocks     Live    Large
                    Blocks  Closures  Closures                         Objects
%8d %8d %8d %9d %9d
%46s
%6d %8d %8d %8d
initStorage: gens
initStorage: last step
initStorage: steps
Fail: 
malloc: failed on request for %lu bytes; message: %s
Heap exhausted;
Current maximum heap size is %lu bytes;
use `+RTS -M<size>' to increase it.
Stack space overflow: current size %ld bytes.
Use `+RTS -Ksize' to increase it.
killThreadzh_fast
raisezh_fast: weird activation record
TSO object entered!
EVACUATED object entered!
WEAK object entered!
DEAD_WEAK object entered!
NO_FINALIZER object entered!
FOREIGN object entered!
STABLE_NAME object entered!
FULL_MVAR object entered!
EMPTY_MVAR object entered!
END_TSO_QUEUE object entered!
END_MUT_LIST object entered!
MUT_CONS object entered!
END_EXCEPTION_LIST object entered!
EXCEPTION_CONS object entered!
ARR_WORDS object entered!
MUT_ARR_PTRS object entered!
MUT_ARR_PTRS_FROZEN object entered!
MUT_VAR object entered!
PAP_entry: CATCH_FRAME
PAP_entry: strange activation record
stg_update_PAP: strange activation record
evacuate: THUNK_SELECTOR: strange selectee %d
evacuate: stack frame at %p
evacuate: strange closure type %d
evacuate
relocate_TSO %d
scavenge:IND???
scavenge: STATIC object
scavenge: stack frame
scavenge: unimplemented/strange closure type %d @ %p
scavenge_one: strange object %d
scavenge_mut_once_list: strange object? %d
scavenge_mutable_list: strange object? %d
scavenge_static: strange closure %d
scavenge_stack: UPDATE_FRAME updatee
scavenge_stack: weird activation record found on stack: %d
scavenge_large: unknown/strange object  %d
threadPaused
allocSegment
allocHashList
allocHashTable
Invalid object %p
interpretBCO: PAP_entry: CATCH_FRAME
interpretBCO: PAP_entry: strange activation record
interpretBCO: hit a CASEFAIL
interpretBCO: unknown or unimplemented opcode
interpretBCO: fell off end of insn loop
fallen off end of object-type switch in interpretBCO()
getMBlock: out of memory
GetMBlock: mmap failed
GetMBlock: misaligned block %p returned when allocating %d megablock(s) at %p
DEBUG (-D4096): linker
DEBUG (-D2048): par
DEBUG (-D1024): gran
DEBUG (-D512): prof
DEBUG (-D256): stable
DEBUG (-D128): sanity
DEBUG (-D64): block
DEBUG (-D32): gc
DEBUG (-D16): gccafs
DEBUG (-D8): weak
DEBUG (-D4): codegen
DEBUG (-D2): evaluator
DEBUG (-D1): scheduler
_=_*
The GHC User's Guide has full details.
Other RTS options may be available for programs compiled a different way.
                the default is .02 sec; resolution is .02 sec
                (0 or no argument means switch as often as possible)
  -C<secs>  Context-switch interval in seconds
  -B       Sound the bell at the start of each garbage collection
  -Z       Don't squeeze out update frames on stack overflow
  -S<file> Detailed GC statistics
  -s<file> Summary  GC statistics  (with -Sstderr going to stderr)
  -t<file> One-line GC statistics  (default file: <program>.stat)
  -T<n>    Number of steps in younger generations (default: 2)
  -G<n>    Number of generations (default: 2)
  -m<n>%   Minimum % of heap which must be available (default 3%)
  -H<size> Sets the minimum heap size (default 0M)   Egs: -H24m  -H1G
  -M<size> Sets the maximum heap size (default 64M)  Egs: -M256k -M1G
  -A<size> Sets the minimum allocation area size (default 256k) Egs: -A1m -A10k
  -k<size> Sets the initial thread stack size (default 1k)  Egs: -K4k   -K2m
  -K<size> Sets the maximum stack size (default 1M)  Egs: -K32k   -K512k
  -?       Prints this message and exits; the program is not executed
The following run time system options are available:
           program (including any of these RTS flags)
  --RTS    Indicates that ALL subsequent arguments will be given to the
   -RTS    Indicates program arguments follow
   +RTS    Indicates run time system options follow
Usage: <prog> <args> [+RTS <rtsopts> | -RTS <args>] ... --RTS <args>
--RTS
+RTS
-RTS
too many RTS arguments (max %d)
unexpected RTS argument: %s
%0.122s.stat
GHC not built for: -prof or -parallel
GHC not built for: -prof
GHC not built for: -parallel or -smp
GHC not built for: -parallel
GHC not built for: -gransim
GHC not built for: ticky-ticky stats
incomplete RTS option: %s
unknown RTS option: %s
stderr
Can't open stats file %s
+RTS 
@bad RTS option: %s

--rwEMma7ioTxnRzrJ--