-
Notifications
You must be signed in to change notification settings - Fork 167
Heap memory profile tracing using DHAT #2797
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
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.
Pull request overview
Adds an optional (mem-profile-tracing, default-off) heap profiling capability for OpenHCL using the dhat allocator/profiler, and exposes collection via the diagnostics RPC surface and ohcldiag-dev.
Changes:
- Introduces a
mem-profile-tracingfeature that swaps the global allocator todhat::Allocand instantiatesdhat::Profilerin relevant Underhill processes. - Adds a new diagnostics RPC to fetch the DHAT heap profile output and wires it through server/client plumbing.
- Adds an
ohcldiag-dev memory-profile-tracecommand to request and write the trace output.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| openhcl/underhill_entry/src/lib.rs | Switches global allocator to dhat::Alloc when mem-profile-tracing is enabled. |
| openhcl/underhill_entry/Cargo.toml | Adds mem-profile-tracing feature and optional dhat dependency. |
| openhcl/underhill_core/src/worker.rs | Initializes a per-worker dhat::Profiler when the feature is enabled. |
| openhcl/underhill_core/src/lib.rs | Adds diag request handling to collect/reset heap profile output (and optionally forward to worker). |
| openhcl/underhill_core/src/dispatch/mod.rs | Adds VM RPC variant + LoadedVm profiler storage and handling. |
| openhcl/underhill_core/Cargo.toml | Adds mem-profile-tracing feature wiring and optional dhat dependency. |
| openhcl/openvmm_hcl/Cargo.toml | Plumbs mem-profile-tracing feature through the top-level OpenHCL crate. |
| openhcl/ohcldiag-dev/src/main.rs | Adds CLI command to request/write the memory profile trace. |
| openhcl/diag_server/src/diag_service.rs | Adds RPC handler that requests the trace from Underhill (or returns an error if disabled). |
| openhcl/diag_server/Cargo.toml | Adds mem-profile-tracing feature flag to gate server-side behavior. |
| openhcl/diag_proto/src/diag.proto | Adds new proto RPC + request/response messages for memory profile trace. |
| openhcl/diag_client/src/lib.rs | Adds client helper to call the new memory profile trace RPC. |
| Cargo.toml | Adds workspace dependency on dhat. |
| Cargo.lock | Locks dhat and its transitive dependencies. |
| } else { | ||
| pid.unwrap() |
Copilot
AI
Feb 11, 2026
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.
pid.unwrap() will panic if the user forgets to pass either --pid or --name. CoreDump already uses a clap ArgGroup to make one of these required; MemoryProfileTrace should do the same (or handle the None case with a proper error).
| } else { | |
| pid.unwrap() | |
| } else if let Some(pid) = pid { | |
| pid | |
| } else { | |
| anyhow::bail!("either --pid or --name must be specified") |
| // Older methods. | ||
| service UnderhillDiag { | ||
| rpc Exec(ExecRequest) returns (ExecResponse); | ||
| rpc Wait(WaitRequest) returns (WaitResponse); | ||
| rpc Start(StartRequest) returns (google.protobuf.Empty); | ||
| rpc Crash(CrashRequest) returns (google.protobuf.Empty); | ||
| rpc Kmsg(KmsgRequest) returns (google.protobuf.Empty); | ||
| rpc Restart(google.protobuf.Empty) returns (google.protobuf.Empty); | ||
| rpc Pause(google.protobuf.Empty) returns (google.protobuf.Empty); | ||
| rpc Resume(google.protobuf.Empty) returns (google.protobuf.Empty); | ||
| rpc ReadFile(FileRequest) returns (google.protobuf.Empty); | ||
| rpc DumpSavedState(google.protobuf.Empty) returns (DumpSavedStateResponse); | ||
| rpc PacketCapture(NetworkPacketCaptureRequest) returns (NetworkPacketCaptureResponse); | ||
| rpc MemoryProfileTrace(MemoryProfileTraceRequest) returns (MemoryProfileTraceResponse); | ||
| } |
Copilot
AI
Feb 11, 2026
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.
diag.proto has a comment stating that new methods should be added to OpenhclDiag because the older diagnostics service didn't handle unknown methods correctly, but this adds MemoryProfileTrace to UnderhillDiag. To preserve compatibility with older servers/clients, consider moving this RPC to OpenhclDiag (and updating client/server dispatch accordingly).
| #[cfg(not(feature = "mem-profile-tracing"))] | ||
| { | ||
| let _ = request; | ||
| anyhow::bail!("Profiler tracing feature disabled") |
Copilot
AI
Feb 11, 2026
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.
When mem-profile-tracing is disabled, this returns "Profiler tracing feature disabled". Consider mentioning the exact build feature name (mem-profile-tracing) and/or how to enable it so the error is actionable.
| anyhow::bail!("Profiler tracing feature disabled") | |
| anyhow::bail!( | |
| "Profiler tracing feature disabled: rebuild with the `mem-profile-tracing` feature enabled" | |
| ) |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Added a new feature
mem-profile-tracing(disabled by default) that provides for heap memory profiling using the DHAT crate.Steps:
mem-profile-tracing. Debug info is necessary to get backtraces in the tracingcargo xflowey build-igvm x64 --override-openvmm-hcl-feature mem-profile-tracing --with-debuginfo --releaseTo collect the trace:
underhill-vm process trace:
ohcldiag-dev.exe <vmname> memory-profile-trace -n vm > vm.jsoninit process trace:
ohcldiag-dev.exe <vmname> memory-profile-trace -n underhill > underhill.jsonViewing the trace:
Load the trace in https://nnethercote.github.io/dh_view/dh_view.html or use the instructions from here to view the trace: https://docs.rs/dhat/latest/dhat/#viewing
Additional resources:
https://docs.rs/dhat/latest/dhat/
https://valgrind.org/docs/manual/dh-manual.html
Screenshot of a sample trace:
