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

GHC ghc-devs at haskell.org
Tue May 6 20:43:34 UTC 2014


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

 > No, no, it does not look bad at all. The address looks strange but that
 is caused by the fact that it was created by the dynamic linker. Look at
 *defl_env and *env in the second program in comment:25. The addresses
 match and I checked they really point to the environment array!

 Well, every time we call `dlsym` passing the handle of a `dlopen`'d
 library, we get a bogus result.  This happens for both `libgmp` and
 `libpthread` (after modifying the `libpthread` path to point to the real
 .so, not the linker script).

 {{{
 #include <dlfcn.h>
 #include <stdio.h>
 #include <stdlib.h>

 char *so = "/usr/lib/x86_64-linux-gnu/libgmp.so";
 char *so2 = "/lib/x86_64-linux-gnu/libpthread.so.0";

 extern char**environ;

 int main(int argc, char *argv[])
 {
   void *deflt, *hdl;
   char ***env;

   deflt = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
   printf("&environ = %p, environ = %p\n", &environ, environ);

   env = dlsym(deflt,"environ");
   printf("dlsym(deflt, \"environ\") = %p, *env = %p\n", env, *env );

   hdl = dlopen(so, RTLD_LAZY);
   if (hdl == NULL) {
       printf("%s\n", dlerror());
       exit(1);
   }
   env = dlsym(hdl,"environ");
   printf("dlsym(\"libgmp\", \"environ\") = %p, *env = %p\n", env, *env);

   hdl = dlopen(so2, RTLD_LAZY);
   if (hdl == NULL) {
       printf("%s\n", dlerror());
       exit(1);
   }
   env = dlsym(hdl,"environ");
   printf("dlsym(\"libpthread\", \"environ\") = %p, *env = %p\n", env,
 *env);
 }
 }}}

 output:

 {{{
 $ ./a.out
 &environ = 0x601078, environ = 0x7fffc44c2008
 dlsym(deflt, "environ") = 0x601078, *env = 0x7fffc44c2008
 dlsym("libgmp", "environ") = 0x2ba8772b64e8, *env = (nil)
 dlsym("libpthread", "environ") = 0x2ba8772b64e8, *env = (nil)
 }}}

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


More information about the ghc-tickets mailing list