[Top][All Lists]

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

Re: Bug while calling dlcose

From: Bas Wijnen
Subject: Re: Bug while calling dlcose
Date: Mon, 19 May 2003 11:40:55 +0200 (CEST)


I may understand you incorrectly, but it doesn't seem like a bug to me.
SIGTRAP is (and should be) emitted only if a program is being traced
(usually by gdb) when a thread is created (or destroyed?).  The program
doesn't usually handle this signal, and ignoring it doesn't kill the
program.  The reason it exists is that the tracing program may require
manual action when a thread is created: the user should choose which
thread to trace.

Now the fact that you call it a bug suggests that the program crashes.
AFAIK that cannot happen as a result of the SIGTRAP, so (if I'm right)
there must be an other reason for it.  You should probably follow the
other thread after the SIGTRAP to see what it does.  I don't have my GNU
system easily bootable at the moment, so I cannot try it myself for now.

But you wrote it called exit().  I may be wrong again, but I thought
exit() would terminate the program, not only the thread that calls it.
I think stop() should call schedule() instead of exit(): once the thread
is stopped, it will no longer be scheduled.  However, it is still
running.  Calling exit() should kill the program, while calling
schedule() lets the scheduler do its job and schedule other threads (of
any program).  Since the thread is closed, it will not be called again.

However, I don't think that will work.  It depends very much on how
schedule() is implemented, which I don't know.  But if I would have
implemented it, then it starts with saving all its registers.  If a
thread that no longer exists saves its registers, then that should
result in memory corruption at (micro)kernel level, which is a Bad
Thing.  If this is true, then it is really a bug in the microkernel,
which should not call code that doesn't exist (e.g. it should call
schedule() after stopping a thread instead of returning)

I'm not sure how useful this post is, because large parts of it may be
totally irrelevant, or even wrong.  schedule() is the name of the linux
scheduler, as you probably know.  I don't know if Mach gives it the same

I hope it helps.

Bas Wijnen

On Sun, May 18, 2003 at 05:28:44PM +0200, marco@linuxrulez.nl wrote:
> 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
> 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-hurd mailing list
> Bug-hurd@gnu.org
> http://mail.gnu.org/mailman/listinfo/bug-hurd

/** mastermind. input 4 numbers 0-5. output <right>.<in the right place> **/

 main(){int  c[4]   ,x=3  ,l=getpid()  ,i;;   for(  srand(l);c[  x]=-   rand
()%6         ,x--   ;);;  for(         ;44>   x;){  char         a[9] ,*p=
 "%.1f\n",   b[9];x=i=0;  gets(a);for   (l=4 ;l--   ;)x+=-(a[l]  -=48)==
       (b[l  ]=c[   l]);  ;for           (l=0;16    >i;l         =++i %4)x
+=(b[i/4]+   a[l]   ?0:(  a[l]=b[i/4]     =10))     ;printf(p,x  *.1)   ;};}

/** This signature should be viewed in a monospaced font, e.g. courier.  **/

reply via email to

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