[GHC] #8935: Obscure linker bug leads to crash in GHCi

GHC ghc-devs at haskell.org
Wed May 14 10:09:24 UTC 2014


#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 <dlfcn.h>
 #include <stdio.h>
 #include <stdlib.h>

 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


More information about the ghc-tickets mailing list