This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Crash when dlclosing oneself in a global destructor

Hi folks,

I'm using a (proprietary) app at $DAYJOB that is triggering a glibc assertion failure when it shuts down. I fully admit that what it's doing is bizarre, but I don't think it's so bizarre that it's reasonable for glibc to crash the process in this scenario. Here's a minimal reproducer:

titan:/tmp geofft$ cat libstupid.c
#include <dlfcn.h>

void *handle = 0;

void c(void) {
        handle = dlopen("/tmp/",
                        RTLD_GLOBAL | RTLD_LAZY | RTLD_NODELETE);

void d(void) {
titan:/tmp geofft$ cat hello.c
#include <stdio.h>

int main(void) {
        printf("Hello world!\n");
        return 0;
titan:/tmp geofft$ cc -fPIC -shared -o libstupid.c -ldl
titan:/tmp geofft$ cc -L. -o hello hello.c -lstupid -Wl,-rpath,/tmp
titan:/tmp geofft$ ./hello
Hello world!
Inconsistency detected by dl-close.c: 762: _dl_close: Assertion `map->l_init_called' failed!
titan:/tmp geofft$

It looks like what's happening is that map->l_init_called is being set to 0 in _dl_fini (with comment "Make sure nothing happens if we are called twice"), before it runs global destructors, but _dl_close has the following check:

  /* First see whether we can remove the object at all.  */
  if (__glibc_unlikely (map->l_flags_1 & DF_1_NODELETE))
      assert (map->l_init_called);
      /* Nope.  Do nothing.  */

I'm not entirely sure what the purpose of this assertion is, but if it's useful, at the least _dl_fini should flip some flag other than l_init_called. Maybe add a new l_fini_called?

See also
for some different cases of people running up against this assertion (in somewhat different contexts) and getting confused.

(The actual app in question has a library that dlopens a list of shared libraries, which happens to include the library that does the dlopening. I don't think it's particularly trying to dlopen itself, but does so sort of by accident.)

Geoffrey Thomas

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]