fstat triggered INVARIANTS panic in memrw()

Alan Cox alc at cs.rice.edu
Tue Jan 18 12:32:29 PST 2005


On Sun, Jan 16, 2005 at 06:30:31PM -0800, Kris Kennaway wrote:
> On Sun, Jan 16, 2005 at 06:18:15PM -0800, Kris Kennaway wrote:
> > On Sun, Jan 16, 2005 at 05:47:46PM -0800, Kris Kennaway wrote:
> > > On Sun, Jan 16, 2005 at 03:13:49PM -0600, Alan Cox wrote:
> > > 
> > > > The "deadc0de" passed to generic_copyout() comes from the following
> > > > lines in devfs_read_f(c51773b8,eed96c84,ca75c800,flags=0):
> > > > 
> > > >         if ((flags & FOF_OFFSET) == 0)
> > > >                 uio->uio_offset = fp->f_offset;
> > > > 
> > > > Can you print the contents of the file structure?
> > > 
> > > (kgdb) frame 28
> > > #28 0xc04d8d91 in devfs_read_f (fp=0xc25f5dd0, uio=0xe7275c84, cred=0xc3540380, flags=0, td=0xc3c34170)
> > >     at ../../../fs/devfs/devfs_vnops.c:931
> > > 931             error = dsw->d_read(dev, uio, ioflag);
> > > (kgdb) print *fp
> > > $1 = {f_list = {le_next = 0xc25f5bf4, le_prev = 0xc25f52a8}, f_type = 1, f_data = 0xc22f8200, f_flag = 1,
> > >   f_mtxp = 0xc2251fd0, f_ops = 0xc074c140, f_cred = 0xc2b2a900, f_count = 2, f_vnode = 0xc3c6fbdc,
> > >   f_offset = 3735929054, f_gcflag = 0, f_msgcount = 0, f_seqcount = 1, f_nextoff = 3263609792}
> > 
> > 3735929054 = 0xdeadc0de.  This same struct file appears all the way
> > back to the syscall frame.  I wonder if fstat is racing with a tty
> > device removal or something (it's certainly racing with something,
> > e.g.:
> 
> Devices may not be to blame; I was able to trigger this by running
> fstat in a loop and then running 'make' in /usr/ports/misc/screen
> (with the idea of testing the tty hypothesis :)
> 
> An interesting datapoint is that none of the non-i386 package machines
> have hit this problem, but the i386 machines can't stay up for more
> than a few minutes under load (which translates to only a few fstat
> invocations).

The field f_offset is 64 bits wide.  If this were a race between use
and deallocation of the file structure within the kernel, then I would
expect f_offset's value to be 0xdeadc0dedeadc0de, not
0x00000000deadc0de.  More likely than not, the 0xdeadc0de is being
passed in from user level.  The i386 kernel is just not handling it
gracefully.  

Alan


More information about the freebsd-current mailing list