bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bug while calling dlcose


From: marco
Subject: Bug while calling dlcose
Date: Sun, 18 May 2003 17:28:44 +0200 (CEST)

Hi,

There is a bug in the console-client when closing drivers, or triggered by
the console-client. That is the funny part about this bug, it can be in
the Hurd, Mach or GDB, i have no idea.

I'll explain what it is all about.

The bug is _only_ triggered under the these conditions (and always
reproducable):

- A program loads a library(I'll call this a plugin from now on because the
  bug is mainly about console-client plugins) with dlopen (the console client
  uses this for plugins).
- The plugin creates a new thread.
- The plugin (pc_kbd for example ;)) calls a fuction from within that thread
  that calls dlcose to close the plugin. In the console-client this function
  is named console_exit

So the conditions are: GDB + Thread + dlclose from within that thread to
close itself. That is exactly what the console-client does.

I also included some example code with this mail to show what I mean. It
is crappy code, I know that, but it is a good example of what happens.

Build this code and run it (=load) from within GDB and it will cause a
SIGTRAP:

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0804885e in main (argc=1, argv=0x11cff74) at load.c:46
46        for (;;);
(gdb) bt
#0  0x0804885e in main (argc=1, argv=0x11cff74) at load.c:46
#1  0x01071dc0 in __libc_start_main () from /lib/libc.so.0.3

I've also commented out some code so you can test it without a thread
or calling it directly.

I'm sure more information is required, but this was the only information I
could think of. Please tell me if more information (and what) is required.

Thanks,
Marco

load.c:

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

void *shobj = NULL;

void
foo_exit (void)
{
  printf ("dlclose\n");
  dlclose (shobj);
  printf ("exit\n");
  exit (0);
}

int
main (int argc, char *argv[])
{
  any_t (*fookill)(any_t);

  shobj = dlopen ("./test.so", RTLD_LAZY);
  if (!shobj)
    {
      char *errstr = dlerror ();
      fprintf (stderr, "error: %s\n", errstr);
      exit (1);
    }

  fookill = dlsym (shobj, "fookill");
  if (!fookill)
    {
      fprintf (stderr, "No fookill\n");
      exit (1);
    }

  /* Call fookill directly.  */
/*   fookill (0); */

  /* Test with cthreads, this is what pc_kbd does.  */
  cthread_detach (cthread_fork (fookill, NULL));

  /* Call it directly from outside of the thread.  */
/*   foo_exit (); */

  for (;;);
  return 0;
}

test.c:

#include <stdio.h>
#include <cthreads.h>
#include <unistd.h>

void foo_exit (void);

any_t
fookill (any_t foo)
{
  sleep (1);
  foo_exit ();

  return 0;
}

Makefile:

CC      =       gcc
CFLAGS  =       -O -g -Wall
LIBS    =       -lthreads

all: load test.so

test.so: test.c
        $(CC) $(CFLAGS) $(LIBS) -shared -Wl,-soname=test.so -std=gnu99 \
        -o test.so test.c

load: load.c
        $(CC) $(CFLAGS) $(LIBS) -rdynamic load.c -o load -ldl








reply via email to

[Prev in Thread] Current Thread [Next in Thread]