Panic if file in FDTable has been destroyed

This will give more information about the file to
identify where possibly the extra DecRef()
would be.

PiperOrigin-RevId: 300855874
This commit is contained in:
Fabricio Voznika
2020-03-13 17:18:10 -07:00
committed by gVisor bot
parent b0f2c3e764
commit 829beebf0b
+11
View File
@@ -195,6 +195,8 @@ func (f *FDTable) Size() int {
//
// It is the caller's responsibility to acquire an appropriate lock.
func (f *FDTable) forEach(fn func(fd int32, file *fs.File, fileVFS2 *vfs.FileDescription, flags FDFlags)) {
// retries tracks the number of failed TryIncRef attempts for the same FD.
retries := 0
fd := int32(0)
for {
file, fileVFS2, flags, ok := f.getAll(fd)
@@ -204,17 +206,26 @@ func (f *FDTable) forEach(fn func(fd int32, file *fs.File, fileVFS2 *vfs.FileDes
switch {
case file != nil:
if !file.TryIncRef() {
retries++
if retries > 1000 {
panic(fmt.Sprintf("File in FD table has been destroyed. FD: %d, File: %+v, FileOps: %+v", fd, file, file.FileOperations))
}
continue // Race caught.
}
fn(fd, file, nil, flags)
file.DecRef()
case fileVFS2 != nil:
if !fileVFS2.TryIncRef() {
retries++
if retries > 1000 {
panic(fmt.Sprintf("File in FD table has been destroyed. FD: %d, File: %+v, Impl: %+v", fd, fileVFS2, fileVFS2.Impl()))
}
continue // Race caught.
}
fn(fd, nil, fileVFS2, flags)
fileVFS2.DecRef()
}
retries = 0
fd++
}
}