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

GHC ghc-devs at haskell.org
Mon May 5 22:54:46 UTC 2014


#8935: Obscure linker bug leads to crash in GHCi
-------------------------------------+------------------------------------
        Reporter:  simonmar          |            Owner:  simonmar
            Type:  bug               |           Status:  infoneeded
        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 trommler):

 Arrrg! Now I see what I was doing wrong! The libraries were specified with
 paths that do not exist on openSUSE. With this program I can reproduce the
 problem:
 {{{
 #include <dlfcn.h>
 #include <stdio.h>

 char *so = "libgmp.so";
 char *so2 = "libpthread.so";

 extern char**environ;

 int main(int argc, char *argv[])
 {
   void *deflt, *hdl;
   deflt = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
   printf("&environ = %p, environ = %p\n", &environ, environ);
   char ***dflt_env = dlsym(deflt,"environ");
   printf("dlsym(deflt, \"environ\") = %p, *dflt_env = %p\n", dflt_env,
 *dflt_env );
   hdl = dlopen(so, RTLD_LAZY);
   char ***env = dlsym(hdl,"environ");
   printf("dlsym(\"libgmp\", \"environ\") = %p\n", env);
   printf("*env = %p\n", *env);
   hdl = dlopen(so2, RTLD_LAZY);
   printf("dlsym(\"libpthread\", \"environ\") = %p\n",
 dlsym(hdl,"environ"));
 }
 }}}
 I also added code that shows the content of the pointer returned from
 `dlsym` called with `libgmp.so`.
 {{{
 peter at montebre:~/tmp> ./a.out
 &environ = 0x601060, environ = 0x7fffc82ce4b8
 dlsym(deflt, "environ") = 0x601060, *dflt_env = 0x7fffc82ce4b8
 dlsym("libgmp", "environ") = 0x7f9dcb870fd8
 *env = (nil)
 dlsym("libpthread", "environ") = 0x601060
 }}}

 Now, playing some more, I removed `extern char **environ;` and the print
 statements and the `NULL` pointer issue is gone:
 {{{
 #include <dlfcn.h>
 #include <stdio.h>

 char *so = "libgmp.so";
 char *so2 = "libpthread.so";

 // extern char**environ;

 int main(int argc, char *argv[])
 {
   void *deflt, *hdl;
   deflt = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
   //  printf("&environ = %p, environ = %p\n", &environ, environ);
   char ***dflt_env = dlsym(deflt,"environ");
   printf("dlsym(deflt, \"environ\") = %p, *dflt_env = %p\n", dflt_env,
 *dflt_env );
   hdl = dlopen(so, RTLD_LAZY);
   char ***env = dlsym(hdl,"environ");
   printf("dlsym(\"libgmp\", \"environ\") = %p\n", env);
   printf("*env = %p\n", *env);
   hdl = dlopen(so2, RTLD_LAZY);
   printf("dlsym(\"libpthread\", \"environ\") = %p\n",
 dlsym(hdl,"environ"));
 }
 }}}

 {{{
 peter at montebre:~/tmp> ./a.out
 dlsym(deflt, "environ") = 0x7f4a0181bfd8, *dflt_env = 0x7fff2d021848
 dlsym("libgmp", "environ") = 0x7f4a0181bfd8
 *env = 0x7fff2d021848
 dlsym("libpthread", "environ") = 0x7f4a0181bfd8
 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8935#comment:25>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list