mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 09:23:52 -05:00
## Summary
- Fixes EBADF error in HeaptrackWrapper by removing redundant file
descriptor close operation
- The net.Socket takes ownership of the FD and closes it during cleanup,
making manual close unnecessary and dangerous
## Root Cause Analysis
The issue occurred in `lib/runtime-tools/heaptrack-wrapper.ts:133` where
the code attempted to manually close a file descriptor that was already
owned by a `net.Socket`. When creating a socket with `new
net.Socket({fd: fd})`, the socket takes ownership of the file descriptor
and closes it during cleanup operations like `resetAndDestroy()`.
Attempting to close the FD again results in:
1. EBADF errors when the FD hasn't been recycled
2. Potentially closing a different resource if the FD has been recycled
by the OS
## Solution
Removed the manual `oldfs.close(fd)` call since the socket handles FD
cleanup automatically. This prevents both the EBADF error and the more
dangerous scenario of closing recycled file descriptors.
## Verification
Created tests to verify that `net.Socket` takes ownership of file
descriptors:
```javascript
// Test confirms that after socket.destroy(), the FD is no longer valid
const fd = fs.openSync(pipePath, O_RDWR | O_NONBLOCK);
const socket = new net.Socket({ fd: fd, readable: true, writable: true });
socket.destroy();
// fs.fstatSync(fd) throws EBADF - confirming FD was closed by socket
```
## Test Plan
- [x] TypeScript compilation passes
- [x] Minimal test suite passes
- [x] Pre-commit hooks pass
- [x] Created unit test to verify net.Socket FD ownership behavior
Fixes COMPILER-EXPLORER-EA7
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>