implemented Setup.hs to build boehm cpp libs and install them;
[hs-boehmgc.git] / gc-7.2 / doc / README.linux
1 See README.alpha for Linux on DEC AXP info.
2
3 This file applies mostly to Linux/Intel IA32.  Ports to Linux on an M68K, IA64,
4 SPARC, MIPS, Alpha and PowerPC are also integrated.  They should behave
5 similarly, except that the PowerPC port lacks incremental GC support, and
6 it is unknown to what extent the Linux threads code is functional.
7 See below for M68K specific notes.
8
9 Incremental GC is generally supported.
10
11 Dynamic libraries are supported on an ELF system.  A static executable
12 should be linked with the gcc option "-Wl,-defsym,_DYNAMIC=0".
13
14 The collector appears to work reliably with Linux threads, but beware
15 of older versions of glibc and gdb.
16
17 The garbage collector uses SIGPWR and SIGXCPU if it is used with
18 Linux threads.  These should not be touched by the client program.
19
20 To use threads, you need to abide by the following requirements:
21
22 1) You need to use LinuxThreads or NPTL (which are included in libc6).
23
24    The collector relies on some implementation details of the LinuxThreads
25    package.  This code may not work on other
26    pthread implementations (in particular it will *not* work with
27    MIT pthreads).
28
29 2) You must compile the collector with -DGC_LINUX_THREADS (or
30    just -DGC_THREADS) and -D_REENTRANT specified in the Makefile.
31
32 3a) Every file that makes thread calls should define GC_LINUX_THREADS and
33    _REENTRANT and then include gc.h.  Gc.h redefines some of the
34    pthread primitives as macros which also provide the collector with
35    information it requires.
36
37 3b) A new alternative to (3a) is to build the collector and compile GC clients
38    with -DGC_USE_LD_WRAP, and to link the final program with
39
40    (for ld) --wrap dlopen --wrap pthread_create \
41             --wrap pthread_join --wrap pthread_detach \
42             --wrap pthread_sigmask --wrap pthread_exit --wrap pthread_cancel
43
44    (for gcc) -Wl,--wrap -Wl,dlopen -Wl,--wrap -Wl,pthread_create \
45              -Wl,--wrap -Wl,pthread_join -Wl,--wrap -Wl,pthread_detach \
46              -Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,pthread_exit \
47              -Wl,--wrap -Wl,pthread_cancel
48
49    In any case, _REENTRANT should be defined during compilation.
50
51 4) Dlopen() disables collection during its execution.  (It can't run
52    concurrently with the collector, since the collector looks at its
53    data structures.  It can't acquire the allocator lock, since arbitrary
54    user startup code may run as part of dlopen().)  Under unusual
55    conditions, this may cause unexpected heap growth.
56
57 5) The combination of GC_LINUX_THREADS, REDIRECT_MALLOC, and incremental
58    collection is probably not fully reliable, though it now seems to work
59    in simple cases.
60
61 6) Thread local storage may not be viewed as part of the root set by the
62    collector.  This probably depends on the linuxthreads version.  For the
63    time being, any collectable memory referenced by thread local storage should
64    also be referenced from elsewhere, or be allocated as uncollectable.
65    (This is really a bug that should be fixed somehow.  The current GC
66    version probably gets things right if there are not too many tls locations
67    and if dlopen is not used.)
68
69
70 M68K LINUX:
71 (From Richard Zidlicky)
72 The bad news is that it can crash every linux-m68k kernel on a 68040,
73 so an additional test is needed somewhere on startup. I have meanwhile
74 patches to correct the problem in 68040 buserror handler but it is not
75 yet in any standard kernel.
76
77 Here is a simple test program to detect whether the kernel has the
78 problem. It could be run as a separate check in configure or tested
79 upon startup. If it fails (return !0) than mprotect can't be used
80 on that system.
81
82 /*
83  * test for bug that may crash 68040 based Linux
84  */
85
86 #include <sys/mman.h>
87 #include <signal.h>
88 #include <unistd.h>
89 #include <stdio.h>
90 #include <stdlib.h>
91
92
93 char *membase;
94 int pagesize=4096;
95 int pageshift=12;
96 int x_taken=0;
97
98 int sighandler(int sig)
99 {
100    mprotect(membase,pagesize,PROT_READ|PROT_WRITE);
101    x_taken=1;
102 }
103
104 main()
105 {
106   long l;
107
108    signal(SIGSEGV,sighandler);
109    l=(long)mmap(NULL,pagesize,PROT_READ,MAP_PRIVATE | MAP_ANON,-1,0);
110   if (l==-1)
111      {
112        perror("mmap/malloc");
113        abort();
114      }
115   membase=(char*)l;
116     *(long*)(membase+sizeof(long))=123456789;
117   if (*(long*)(membase+sizeof(long)) != 123456789 )
118     {
119       fprintf(stderr,"writeback failed !\n");
120       exit(1);
121     }
122   if (!x_taken)
123     {
124       fprintf(stderr,"exception not taken !\n");
125       exit(1);
126     }
127   fprintf(stderr,"vmtest Ok\n");
128   exit(0);
129 }