[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
- Bug while calling dlcose,
marco <=