Skip to contentSkip to conversation

more statd segfault

DISCUSSION michael 4 participants 4 messages Sep 9, 2003 – Sep 12, 2003

Subsystems (2)
lore
Share & tools
lore

michael

author
#0 lore raw

okay i have tracked down the segfault to here...

void
svc_getreqset (fd_set *readfds)
{
register u_int32_t mask;
register u_int32_t *maskp;
register int setsize;
register int sock;
register int bit;

setsize = _rpc_dtablesize ();
maskp = (u_int32_t *) readfds->fds_bits;
for (sock = 0; sock < setsize; sock += 32)
* for (mask = *maskp++; (bit = ffs (mask)); mask ^= (1 << (bit - 1)))

      svc_getreq_common (sock + bit - 1);
}

the contents of the variables are as follows...
358 in svc.c
(gdb) print *maskp
$13 = 128
(gdb) print mask
$14 = 3221224588
(gdb) print setsize
$15 = 1048566
(gdb) print bit
$16 = 1048566
(gdb) print *readfds
$17 = {fds_bits = {128, 0 <repeats 31 times>}}
(gdb) n 10000

Program received signal SIGSEGV, Segmentation fault. 0x40112e3a in svc_getreqset (readfds=0xbffffc0c) at svc.c:359
359 in svc.c
(gdb) print sock
$37 = 8096
(gdb) print setsize
$38 = 1048566
(gdb) print bit
$39 = -1073741824
(gdb) print maskp
$40 = (u_int32_t *) 0xc0000000
(gdb) print *maskp
Cannot access memory at address 0xc0000000
(gdb)

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#1 lore raw

I finally tracked down the statd segfault that had been plaguing me for sometime.

statd calls sunrpc code which is in libc on debian. this code loops through all possible file descriptors and in my case if the number of fds per process is set higher then 8096 it segfaults.

for the archives here is the code that segfaults:

void
svc_getreqset (fd_set *readfds)
{
register u_int32_t mask;
register u_int32_t *maskp;
register int setsize;
register int sock;
register int bit;

setsize = _rpc_dtablesize ();
maskp = (u_int32_t *) readfds->fds_bits;
for (sock = 0; sock < setsize; sock += 32)

    for (mask = *maskp++; (bit = ffs (mask)); mask ^= (1 << (bit - 1)))
      svc_getreq_common (sock + bit - 1);
}

keywords: statd segfault sun rpc file lock ulimit

michael

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#2 lore raw
Quoted 6 lines · On Thursday September 11, [email protected] wrote:

I finally tracked down the statd segfault that had been plaguing me for sometime.

statd calls sunrpc code which is in libc on debian. this code loops through all possible file descriptors and in my case if the number of fds per process is set higher then 8096 it segfaults.

Well done.
I have just applied a patch to statd and mountd in nfs-utils so that it forces the fd limit down to FD_SETSIZE if it is above that. This appears to effectively work around what is really a libc bug (I think).

Have you reported it to the glibc maintainers?

NeilBrown

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#3 lore raw
Quoted 7 lines · Neil Brown
Quoted 3 lines · On Thursday September 11, [email protected] wrote:

I finally tracked down the statd segfault that had been plaguing me for sometime.

statd calls sunrpc code which is in libc on debian. this code loops through all possible file descriptors and in my case if the number of fds per process is set higher then 8096 it segfaults.

Quoted 7 lines

Well done.
I have just applied a patch to statd and mountd in nfs-utils so that it forces the fd limit down to FD_SETSIZE if it is above that. This appears to effectively work around what is really a libc bug (I think).

Have you reported it to the glibc maintainers?

I was curious, so I grepped for references to fd_set and FD_SETSIZE in glibc-2.3.2. Looks like the rpc code actually exports an fd_set to the world!
Sad to have FD_SETSIZE show up in the interface like that.

(Looks like H.J. Lu had some interest in this code; see
http://sources.redhat.com/ml/libc-alpha/2001-05/msg00071.html)

Here are the hits of interest.

glibc-2.3.2/ChangeLog.11:       [_LIBC]: Fully reinstate the code that avoids the FD_SETSIZE limit
glibc-2.3.2/ChangeLog.12:       (rpc_thread_multi, __rpc_thread_svc_fdset, __rpc_thread_createerr,
glibc-2.3.2/ChangeLog.12:       * include/rpc/rpc.h: Remove svc_fdset, rpc_createerr, svc_pollfd, and
glibc-2.3.2/ChangeLog.12:       * sunrpc/rpc/rpc.h: Declare __rpc_thread_svc_fdset,
glibc-2.3.2/ChangeLog.12:       Define svc_fdset, get_rpc_createerr, svc_pollfd, and
glibc-2.3.2/ChangeLog.12:       Define __rpc_thread_svc_fdset, __rpc_thread_createerr,
glibc-2.3.2/ChangeLog.12:       * sunrpc/Versions [libc] (GLIBC_2.2.3): Export  __rpc_thread_svc_fdset,

glibc-2.3.2/FAQ.in:only place where OPEN_MAX and FD_SETSIZE is really needed in the library glibc-2.3.2/FAQ.in:itself is the size of fd_set which is used by select. glibc-2.3.2/FAQ.in:limits imposed by the fd_set' type. Instead all places where the glibc-2.3.2/FAQ.in:prominent example is struct fd_set'.
glibc-2.3.2/INTERFACE:svc_fdset svc_fdset
glibc-2.3.2/include/rpc/rpc.h: fd_set svc_fdset_s; /* Global, rpc_common.c */
glibc-2.3.2/include/rpc/rpc.h:libc_hidden_proto (__rpc_thread_svc_fdset) glibc-2.3.2/include/rpc/svc.h:extern void svc_getreqset_internal (fd_set *__readfds) attribute_hidden;

glibc-2.3.2/sunrpc/Versions:    rpc_createerr; svc_fdset; svcauthdes_stats;
glibc-2.3.2/sunrpc/Versions:    __rpc_thread_svc_fdset; __rpc_thread_createerr;

glibc-2.3.2/sunrpc/rpc/rpc.h:extern fd_set *__rpc_thread_svc_fdset (void) __attribute__ ((__const__)); glibc-2.3.2/sunrpc/rpc/rpc.h:#define svc_fdset (*__rpc_thread_svc_fdset ()) glibc-2.3.2/sunrpc/rpc/svc.h:extern fd_set svc_fdset;
glibc-2.3.2/sunrpc/rpc/svc.h:#define svc_fds svc_fdset.fds_bits[0] /* compatibility */
glibc-2.3.2/sunrpc/rpc/svc.h:extern void svc_getreqset (fd_set *__readfds) __THROW; glibc-2.3.2/sunrpc/rpc_common.c:#undef svc_fdset glibc-2.3.2/sunrpc/rpc_common.c:fd_set svc_fdset;

glibc-2.3.2/sunrpc/rpc_svcout.c:  f_print (fout, "\t\textern fd_set svc_fdset;\n");
glibc-2.3.2/sunrpc/rpc_svcout.c:  f_print (fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
glibc-2.3.2/sunrpc/rpc_thread.c:#undef svc_fdset
glibc-2.3.2/sunrpc/rpc_thread.c:fd_set *
glibc-2.3.2/sunrpc/rpc_thread.c:__rpc_thread_svc_fdset (void)
glibc-2.3.2/sunrpc/rpc_thread.c:                return &svc_fdset;
glibc-2.3.2/sunrpc/rpc_thread.c:        return &tvp->svc_fdset_s;
glibc-2.3.2/sunrpc/rpc_thread.c:libc_hidden_def (__rpc_thread_svc_fdset)
glibc-2.3.2/sunrpc/svc.c:      if (sock < FD_SETSIZE)
glibc-2.3.2/sunrpc/svc.c:       FD_SET (sock, &svc_fdset);
glibc-2.3.2/sunrpc/svc.c:      if (sock < FD_SETSIZE)
glibc-2.3.2/sunrpc/svc.c:       FD_CLR (sock, &svc_fdset);
glibc-2.3.2/sunrpc/svc.c:  fd_set readfds;

glibc-2.3.2/sunrpc/svc.c:svc_getreqset (fd_set *readfds)
- Dan

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs