-
Notifications
You must be signed in to change notification settings - Fork 3.8k
fix(process): make process.title work properly on Linux #25521
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
On Linux, process.title should modify the process name visible in tools like `ps`, `top`, and `htop`. Previously, setting process.title only updated an internal variable but did not modify the actual process title that external tools see. This fix implements process.title properly on Linux by: 1. Storing the original argv buffer location during initialization 2. Overwriting the original argv memory when process.title is set (this is how /proc/self/cmdline is populated) 3. Using prctl(PR_SET_NAME) to set the thread name (shown in top/htop) This matches Node.js behavior, which uses libuv's implementation that does the same argv memory overwriting technique. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Updated 5:05 PM PT - Dec 15th, 2025
@Jarred-Sumner, your commit 746cec1 is building: |
WalkthroughAdds Linux-specific process title support: records the original argv buffer and capacity, exposes a public ProcessTitleInfo with setTitle to overwrite argv and set the thread name, invokes it from Node's setTitle on Linux, and adds a Linux-only test that verifies /proc/self/cmdline reflects process.title. Changes
Possibly related PRs
Suggested reviewers
Pre-merge checks✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (2)
🧰 Additional context used📓 Path-based instructions (6)test/**/*.{js,ts,jsx,tsx}📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)
Files:
test/**/*.test.{ts,js,jsx,tsx,mjs,cjs}📄 CodeRabbit inference engine (test/CLAUDE.md)
Files:
test/**/*.test.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
src/**/*.{cpp,zig}📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)
Files:
src/**/*.zig📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)
Files:
**/*.zig📄 CodeRabbit inference engine (.cursor/rules/zig-javascriptcore-classes.mdc)
Files:
🧠 Learnings (20)📚 Learning: 2025-11-24T18:37:30.259ZApplied to files:
📚 Learning: 2025-12-02T05:59:51.485ZApplied to files:
📚 Learning: 2025-11-24T18:37:30.259ZApplied to files:
📚 Learning: 2025-11-24T18:36:59.706ZApplied to files:
📚 Learning: 2025-11-24T18:35:50.422ZApplied to files:
📚 Learning: 2025-11-24T18:35:08.612ZApplied to files:
📚 Learning: 2025-11-24T18:37:30.259ZApplied to files:
📚 Learning: 2025-11-24T18:36:59.706ZApplied to files:
📚 Learning: 2025-09-20T00:57:56.685ZApplied to files:
📚 Learning: 2025-11-24T18:37:11.466ZApplied to files:
📚 Learning: 2025-11-24T18:37:30.259ZApplied to files:
📚 Learning: 2025-11-24T18:35:50.422ZApplied to files:
📚 Learning: 2025-12-02T05:59:51.485ZApplied to files:
📚 Learning: 2025-11-08T04:06:33.198ZApplied to files:
📚 Learning: 2025-11-24T18:37:11.466ZApplied to files:
📚 Learning: 2025-11-06T00:58:23.965ZApplied to files:
📚 Learning: 2025-11-24T18:35:39.205ZApplied to files:
📚 Learning: 2025-10-26T01:32:04.844ZApplied to files:
📚 Learning: 2025-11-24T18:37:30.259ZApplied to files:
📚 Learning: 2025-11-10T00:57:09.173ZApplied to files:
🔇 Additional comments (3)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/bun.zig(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{cpp,zig}
📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)
src/**/*.{cpp,zig}: Usebun bdorbun run build:debugto build debug versions for C++ and Zig source files; creates debug build at./build/debug/bun-debug
Run tests usingbun bd test <test-file>with the debug build; never usebun testdirectly as it will not include your changes
Execute files usingbun bd <file> <...args>; never usebun <file>directly as it will not include your changes
Enable debug logs for specific scopes usingBUN_DEBUG_$(SCOPE)=1environment variable
Code generation happens automatically as part of the build process; no manual code generation commands are required
Files:
src/bun.zig
src/**/*.zig
📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)
Use
bun.Output.scoped(.${SCOPE}, .hidden)for creating debug logs in Zig codeImplement core functionality in Zig, typically in its own directory in
src/
src/**/*.zig: Private fields in Zig are fully supported using the#prefix:struct { #foo: u32 };
Use decl literals in Zig for declaration initialization:const decl: Decl = .{ .binding = 0, .value = 0 };
Prefer@importat the bottom of the file (auto formatter will move them automatically)Be careful with memory management in Zig code - use defer for cleanup with allocators
Files:
src/bun.zig
**/*.zig
📄 CodeRabbit inference engine (.cursor/rules/zig-javascriptcore-classes.mdc)
**/*.zig: Expose generated bindings in Zig structs usingpub const js = JSC.Codegen.JS<ClassName>with trait conversion methods:toJS,fromJS, andfromJSDirect
Use consistent parameter nameglobalObjectinstead ofctxin Zig constructor and method implementations
Usebun.JSError!JSValuereturn type for Zig methods and constructors to enable proper error handling and exception propagation
Implement resource cleanup usingdeinit()method that releases resources, followed byfinalize()called by the GC that invokesdeinit()and frees the pointer
UseJSC.markBinding(@src())in finalize methods for debugging purposes before callingdeinit()
For methods returning cached properties in Zig, declare external C++ functions usingextern fnandcallconv(JSC.conv)calling convention
Implement getter functions with naming patternget<PropertyName>in Zig that acceptthisandglobalObjectparameters and returnJSC.JSValue
Access JavaScript CallFrame arguments usingcallFrame.argument(i), check argument count withcallFrame.argumentCount(), and getthiswithcallFrame.thisValue()
For reference-counted objects, use.deref()in finalize instead ofdestroy()to release references to other JS objects
Files:
src/bun.zig
🧠 Learnings (1)
📚 Learning: 2025-11-24T18:34:55.173Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/building-bun.mdc:0-0
Timestamp: 2025-11-24T18:34:55.173Z
Learning: Applies to src/**/*.{cpp,zig} : Execute files using `bun bd <file> <...args>`; never use `bun <file>` directly as it will not include your changes
Applied to files:
src/bun.zig
🔇 Additional comments (1)
src/bun.zig (1)
2078-2094: Please provide the review comment to be rewritten. No review_comment was found in your message.
| title.* = bun.String.cloneUTF8(str orelse "bun"); | ||
| } | ||
|
|
||
| // TODO: https://github.com/nodejs/node/blob/master/deps/uv/src/unix/darwin-proctitle.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is macos supported yet? otherwise shouldn't the todo still be present?
| import { beforeAll, describe, expect, it } from "bun:test"; | ||
| import { beforeAll, describe, expect, it, setDefaultTimeout } from "bun:test"; | ||
| import { bunEnv, bunExe, isASAN, isBroken, isMusl, isWindows, nodeExe, tmpdirSync } from "harness"; | ||
| import assert from "node:assert"; | ||
| import fs from "node:fs/promises"; | ||
| import { basename, join } from "path"; | ||
|
|
||
| // Building native modules with node-gyp takes a long time | ||
| setDefaultTimeout(1000 * 60 * 5); // 5 minutes | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unrelated change?
The v8 test compiles native modules with node-gyp in the beforeAll hook, which takes much longer than the default 5 second timeout. This was causing the test to time out and fail on slower machines or CI. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
dacf3ed to
5874a79
Compare
Summary
process.titleon Linux to actually modify the process name visible in tools likeps,top, andhtopprocess.titleonly updated an internal variable but did not change what external tools seeImplementation
process.titleis set, overwrite the original argv memory (this is how/proc/self/cmdlineis populated)prctl(PR_SET_NAME)to set the thread name (visible in top/htop's thread name column)This matches Node.js behavior, which uses libuv's implementation with the same argv memory overwriting technique.
Test plan
/proc/self/cmdlineon Linuxprocess.titletests still passbun run zig:check-allpasses (compiles on all platforms)🤖 Generated with Claude Code