summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel/fd_table.go
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2020-03-13 17:16:59 -0700
committergVisor bot <gvisor-bot@google.com>2020-03-13 17:18:10 -0700
commit829beebf0b67e20e50dd5ec4a5030636e38cc576 (patch)
tree722c3f8177c4d8a9dbd09d7df5c9b681af075bf1 /pkg/sentry/kernel/fd_table.go
parentb0f2c3e7646df603156f1b8e8b3382f33353eb04 (diff)
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
Diffstat (limited to 'pkg/sentry/kernel/fd_table.go')
-rw-r--r--pkg/sentry/kernel/fd_table.go11
1 files changed, 11 insertions, 0 deletions
diff --git a/pkg/sentry/kernel/fd_table.go b/pkg/sentry/kernel/fd_table.go
index 58001d56c..00f914564 100644
--- a/pkg/sentry/kernel/fd_table.go
+++ b/pkg/sentry/kernel/fd_table.go
@@ -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++
}
}