#8935: Obscure linker bug leads to crash in GHCi
-------------------------------------+------------------------------------
        Reporter:  simonmar          |            Owner:  trommler
            Type:  bug               |           Status:  patch
        Priority:  high              |        Milestone:  7.8.3
       Component:  Runtime System    |          Version:  7.8.1-rc2
      Resolution:                    |         Keywords:
Operating System:  Unknown/Multiple  |     Architecture:  Unknown/Multiple
 Type of failure:  GHCi crash        |       Difficulty:  Rocket Science
       Test Case:                    |       Blocked By:
        Blocking:                    |  Related Tickets:
-------------------------------------+------------------------------------
Comment (by simonmar):
 `bar.c`:
 {{{
 static int bar = 1;
 int _getbar(void)
 {
     return bar;
 }
 void _setbar(int x)
 {
     bar = x;
 }
 }}}
 `foo.c`:
 {{{
 extern int _getbar(void);
 extern void _setbar(int);
 int getbar(void)
 {
     return _getbar();
 }
 int setbar(int x)
 {
     _setbar(x);
 }
 }}}
 `test.c`:
 {{{
 #include 
 #include 
 #include 
 extern int getbar(void);
 extern void setbar(int);
 int main(int argc, char *argv[])
 {
   void *deflt, *hdl;
   int (*pgetbar)(void);
   int (*psetbar)(int);
   setbar(2);
   printf("getbar() = %d\n", getbar());
   deflt = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
   if (deflt == NULL) {
       printf("%s\n", dlerror());
       exit(1);
   }
   pgetbar = dlsym(deflt, "getbar");
   printf("dlsym(deflt, \"getbar\") = %p, pgetbar() = %d\n", pgetbar,
 (*pgetbar)());
   hdl = dlopen("libbar.so", RTLD_LOCAL | RTLD_LAZY);
   if (hdl == NULL) {
       printf("%s\n", dlerror());
       exit(1);
   }
   pgetbar = dlsym(hdl, "_getbar");
   psetbar = dlsym(hdl, "_setbar");
   printf("dlsym(deflt, \"_getbar\") = %p, pgetbar() = %d\n", pgetbar,
 (*pgetbar)());
   (*psetbar)(3);
   printf("(*psetbar)(3); pgetbar() = %d\n", (*pgetbar)());
   hdl = dlopen("libfoo.so", RTLD_LOCAL | RTLD_LAZY);
   if (hdl == NULL) {
       printf("%s\n", dlerror());
       exit(1);
   }
   pgetbar = dlsym(hdl, "getbar");
   psetbar = dlsym(hdl, "setbar");
   printf("dlsym(deflt, \"getbar\") = %p, pgetbar() = %d\n", pgetbar,
 (*pgetbar)());
   (*psetbar)(4);
   printf("(*psetbar)(4); pgetbar() = %d\n", (*pgetbar)());
 }
 }}}
 {{{
 $ gcc -shared -fPIC bar.c -o libbar.so
 $ gcc -shared -fPIC foo.c -o libfoo.so -L. -lbar
 $ gcc test.c -L. -lfoo -lbar -ldl -g
 $ LD_LIBRARY_PATH=. ./a.out
 getbar() = 2
 dlsym(deflt, "getbar") = 0x2b4660dcc61c, pgetbar() = 2
 dlsym(deflt, "_getbar") = 0x2b46615a658c, pgetbar() = 2
 (*psetbar)(3); pgetbar() = 3
 dlsym(deflt, "getbar") = 0x2b4660dcc61c, pgetbar() = 3
 (*psetbar)(4); pgetbar() = 4
 }}}
--
Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8935#comment:47
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler