diff options
author | Fabricio Voznika <fvoznika@google.com> | 2020-03-13 17:16:59 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-03-13 17:18:10 -0700 |
commit | 829beebf0b67e20e50dd5ec4a5030636e38cc576 (patch) | |
tree | 722c3f8177c4d8a9dbd09d7df5c9b681af075bf1 /pkg/sentry/kernel | |
parent | b0f2c3e7646df603156f1b8e8b3382f33353eb04 (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')
-rw-r--r-- | pkg/sentry/kernel/fd_table.go | 11 |
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++ } } |