bug-hurd
[Top][All Lists]
Advanced

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

fork() loses when thread self port's refcount is max'ed out


From: Marcus Brinkmann
Subject: fork() loses when thread self port's refcount is max'ed out
Date: Sun, 13 Oct 2002 03:34:27 +0200
User-agent: Mutt/1.4i

Hi,

I found one problem with pthreads, but it is not pthread specific.  pthread
just seem to trigger it by calling mach_thread_self often.  Not sure.

The problem was in fork().  The assertion at line 446 in 
sysdeps/mach/hurd/fork.c
was failing.  The error returned is EKERN_UREFS_OVERFLOW.

      /* Create the child main user thread and signal thread.  */
      if ((err = __thread_create (newtask, &thread)) ||
          (err = __thread_create (newtask, &sigthread)))
        LOSE;

This occured in miniperl with pthreads, but I was able to find a test case
without threads.  Here it is:

  for (i = 0; i < 65535; i++)
    mach_thread_self ();

  child = fork ();

Afer the loop the main thread port has 65534 user references, the maximum.
This is not a problem per se: mach_thread_self() will still succeed.  However,
any mach_port_mod_refs call that tries to increase the number of send rights is
bound to fail with the error EKERN_UREFS_OVERFLOW.

When running the program, it just hangs.

What I don't know is where exactly the error occurs.  Someone might want to
step through thread_create to find out where the problem happens, or Roland
might already know.  I think there are a couple of places where the glibc
code assumes it can just bump up the refs by one (for example in the stubs
code for interruptible RPCs, but that is obviously not the case here).  This
does not work for mach_host_self, mach_task_self and mach_thread_self, which
are special in that we just let them overrun and never deallocate send
rights (we must not even so that we don't underrun them unexpectedly).

Below is a backtrace.

It is probably not good behaviour of pthread to allocate so many thread self
send rights.  But still this is a bug in fork, as over a long run time the
number of thread self send rights is doomed to increase.  Eventually it will
hit the limit.  65534 is not high.

Thanks,
Marcus

(gdb) bt
#0  0x0104351c in __swtch_pri () from /lib/debug/libc.so.0.3
#1  0x01044846 in __spin_lock_solid (lock=0x11710c4) at spin-solid.c:27
#2  0x010449b7 in __mutex_lock_solid (lock=0x11710c4) at mutex-solid.c:31
#3  0x01107891 in __libc_write (fd=2, buf=0x8049b28, nbytes=93) at 
../mach/lock-intern.h:77
#4  0x010b09a2 in _IO_new_file_write (f=0x1174fa0, data=0x8049b28, n=93) at 
fileops.c:885
#5  0x010afeda in new_do_write (fp=0x1174fa0,
    data=0x8049b28 "test-4: ../sysdeps/mach/hurd/fork.c:446: __fork: Unexpected 
error: (os/kern) urefs overflow.\n", to_do=93) at fileops.c:467
#6  0x010b0af9 in _IO_new_file_xsputn (f=0x1174fa0, data=0x8049b28, n=93) at 
fileops.c:975
#7  0x010a94fb in _IO_fputs (
    str=0x8049b28 "test-4: ../sysdeps/mach/hurd/fork.c:446: __fork: Unexpected 
error: (os/kern) urefs overflow.\n", fp=0x1174fa0) at iofputs.c:47
#8  0x01072b07 in __assert_perror_fail (errnum=19, file=0x11693d6 
"../sysdeps/mach/hurd/fork.c",
    line=446, function=0x0) at assert-perr.c:68
#9  0x010e1e61 in __fork () at ../sysdeps/mach/hurd/fork.c:531
#10 0x080485fb in main ()
#11 0x01067dc0 in __libc_start_main (main=0x80485b8 <main>, argc=1, 
ubp_av=0x1022c70,
    init=0x8048460 <_init>, fini=0x217e8 <_dl_debug_mask>, rtld_fini=0x1, 
stack_end=0x11710c4)
    at ../sysdeps/generic/libc-start.c:129


bt full:

#0  0x0104351c in __swtch_pri () from /lib/debug/libc.so.0.3
No locals.
#1  0x01044846 in __spin_lock_solid (lock=0x11710c4) at spin-solid.c:27
No locals.
#2  0x010449b7 in __mutex_lock_solid (lock=0x11710c4) at mutex-solid.c:31
No locals.
#3  0x01107891 in __libc_write (fd=2, buf=0x8049b28, nbytes=93) at 
../mach/lock-intern.h:77
No locals.
#4  0x010b09a2 in _IO_new_file_write (f=0x1174fa0, data=0x8049b28, n=93) at 
fileops.c:885
        to_do = 93
#5  0x010afeda in new_do_write (fp=0x1174fa0,
    data=0x8049b28 "test-4: ../sysdeps/mach/hurd/fork.c:446: __fork: Unexpected 
error: (os/kern) urefs overflow.\n", to_do=93) at fileops.c:467
        count = 18304999
#6  0x010b0af9 in _IO_new_file_xsputn (f=0x1174fa0, data=0x8049b28, n=93) at 
fileops.c:975
        block_size = 1
        do_write = 93
        s = 0x8049b28 "test-4: ../sysdeps/mach/hurd/fork.c:446: __fork: 
Unexpected error: (os/kern)
urefs overflow.\n"
        to_do = 93
        must_flush = 0
        count = 0
#7  0x010a94fb in _IO_fputs (
    str=0x8049b28 "test-4: ../sysdeps/mach/hurd/fork.c:446: __fork: Unexpected 
error: (os/kern) urefs overflow.\n", fp=0x1174fa0) at
iofputs.c:47
        len = 93
        result = -1
#8  0x01072b07 in __assert_perror_fail (errnum=19, file=0x11693d6 
"../sysdeps/mach/hurd/fork.c",
    line=446, function=0x0) at assert-perr.c:68
        errbuf = "GNU\0\001", '\0' <repeats 15 times>,
"õ\003\0\0|\002\0\0\0\0\0\0\0\0\0\0¹\001\0\0\006\001\0\0\206\0\0\01\0\0\0Ú\001\0\0\201\001\0\0\203",
'\0' <repeats 19 times>, "@\001\0\0\0\0\0\0û\001\0\0³\001", '\0' <repeats 18 
times>,
"7\001\0\0á\0\0\0\232\001\0\0\0\0\0\0\230\0\0\0(\002\0\0;\002\0\0\0\0\0\0<\001\0\0\0\0\0\0d",
'\0' <repeats 11 times>,
"ó\001\0\0A\002\0\0\004\002\0\0\003\001\0\0-\207\004\bø&\002\001\0\0\0\0\0\0\0\0ä+\002\001\0\0\0\0ç\001\0\0\r\0\0\0ÿÿÿÿ\0\0\0\06\001\0"...
        buf = 0x8049b28 "test-4: ../sysdeps/mach/hurd/fork.c:446: __fork: 
Unexpected error: (os/kern) urefs overflow.\n"
#9  0x010e1e61 in __fork () at ../sysdeps/mach/hurd/fork.c:531
        env = {{__jmpbuf = {18311000, 18538448, 16919664, 16919528, 16918976, 
17697962},
    __mask_was_saved = 0, __saved_mask = 16919664}}
        pid = 137700
        i = 2
        err = EKERN_UREFS_OVERFLOW
        ss = (struct hurd_sigstate * volatile) 0x11af808
#10 0x080485fb in main ()
No symbol table info available.
#11 0x01067dc0 in __libc_start_main (main=0x80485b8 <main>, argc=1, 
ubp_av=0x1022c70,
    init=0x8048460 <_init>, fini=0x217e8 <_dl_debug_mask>, rtld_fini=0x1, 
stack_end=0x11710c4)
    at ../sysdeps/generic/libc-start.c:129
        ubp_ev = (char **) 0x0



-- 
`Rhubarb is no Egyptian god.' GNU      http://www.gnu.org    marcus@gnu.org
Marcus Brinkmann              The Hurd http://www.gnu.org/software/hurd/
Marcus.Brinkmann@ruhr-uni-bochum.de
http://www.marcus-brinkmann.de/




reply via email to

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