Files
bun.sh/test/internal/ban-limits.json
robobun a7fc6eb354 Implement --cpu-prof CLI flag (#24112)
## Summary

Implements the `--cpu-prof` CLI flag for Bun to profile CPU usage and
save results in Chrome CPU Profiler JSON format, compatible with Chrome
DevTools and VSCode.

## Implementation Details

- Uses JSC's `SamplingProfiler` to collect CPU samples during execution
- Converts samples to Chrome CPU Profiler JSON format on exit
- Supports `--cpu-prof-name` to customize output filename
- Supports `--cpu-prof-dir` to specify output directory
- Default filename: `CPU.YYYYMMDD.HHMMSS.PID.0.001.cpuprofile`

## Key Features

 **Chrome DevTools Compatible** - 100% compatible with Node.js CPU
profile format
 **Absolute Timestamps** - Uses wall clock time (microseconds since
epoch)
 **1ms Sampling** - Matches Node.js sampling frequency for comparable
granularity
 **Thread-Safe** - Properly shuts down background sampling thread
before processing
 **Memory-Safe** - Uses HeapIterationScope and DeferGC for safe heap
access
 **Cross-Platform** - Compiles on Windows, macOS, and Linux with proper
path handling

## Technical Challenges Solved

1. **Heap Corruption** - Fixed by calling `profiler->shutdown()` before
processing traces
2. **Memory Safety** - Added `HeapIterationScope` and `DeferGC` when
accessing JSCells
3. **Timestamp Accuracy** - Explicitly start stopwatch and convert to
absolute wall clock time
4. **Path Handling** - Used `bun.path.joinAbsStringBufZ` with proper cwd
resolution
5. **Windows Support** - UTF-16 path conversion for Windows
compatibility
6. **Atomic Writes** - Used `bun.sys.File.writeFile` with ENOENT retry

## Testing

All tests pass (4/4):
-  Generates profile with default name
-  `--cpu-prof-name` sets custom filename
-  `--cpu-prof-dir` sets custom directory
-  Profile captures function names

Verified format compatibility:
- JSON structure matches Node.js exactly
- All samples reference valid nodes
- Timestamps use absolute microseconds since epoch
- Cross-platform compilation verified with `bun run zig:check-all`

## Example Usage

```bash
# Basic usage
bun --cpu-prof script.js

# Custom filename
bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js

# Custom directory
bun --cpu-prof --cpu-prof-dir ./profiles script.js
```

Output can be opened in Chrome DevTools (Performance → Load Profile) or
VSCode's CPU profiling viewer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-29 16:41:21 -07:00

46 lines
1.1 KiB
JSON

{
" != undefined": 0,
" == undefined": 0,
" catch bun.outOfMemory()": 0,
"!= alloc.ptr": 0,
"!= allocator.ptr": 0,
".arguments_old(": 265,
".jsBoolean(false)": 0,
".jsBoolean(true)": 0,
".stdDir()": 42,
".stdFile()": 16,
"// autofix": 164,
": [^=]+= undefined,$": 255,
"== alloc.ptr": 0,
"== allocator.ptr": 0,
"@import(\"bun\").": 0,
"EXCEPTION_ASSERT(!scope.exception())": 0,
"JSValue.false": 0,
"JSValue.true": 0,
"TODO: properly propagate exception upwards": 118,
"alloc.ptr !=": 0,
"alloc.ptr ==": 0,
"allocator.ptr !=": 1,
"allocator.ptr ==": 0,
"global.hasException": 28,
"globalObject.hasException": 47,
"globalThis.hasException": 125,
"std.StringArrayHashMap(": 1,
"std.StringArrayHashMapUnmanaged(": 11,
"std.StringHashMap(": 0,
"std.StringHashMapUnmanaged(": 0,
"std.Thread.Mutex": 1,
"std.debug.assert": 26,
"std.debug.dumpStackTrace": 0,
"std.debug.print": 0,
"std.enums.tagName(": 2,
"std.fs.Dir": 164,
"std.fs.File": 62,
"std.fs.cwd": 102,
"std.log": 1,
"std.mem.indexOfAny(u8": 0,
"std.unicode": 27,
"undefined != ": 0,
"undefined == ": 0,
"usingnamespace": 0
}