Skip to content

Add std_hello e2e test: println! on vibix (#852)#870

Merged
dburkart merged 2 commits into
mainfrom
m852-std-hello-e2e
May 5, 2026
Merged

Add std_hello e2e test: println! on vibix (#852)#870
dburkart merged 2 commits into
mainfrom
m852-std-hello-e2e

Conversation

@dburkart
Copy link
Copy Markdown
Owner

@dburkart dburkart commented May 5, 2026

Summary

  • Adds cargo xtask std-hello end-to-end smoke test that builds a standard Rust binary (println!("hello from std")), installs it as /init in the ext2 rootfs, boots under QEMU, and asserts the marker string appears on serial output.
  • Works around a demand-paging bug in load_user_elf_with_vmas by eagerly mapping PT_LOAD segment pages into the PML4 (the VMA tree is still registered for fork compatibility).
  • Cleans up the vibix PAL _start to remove debugging diagnostics.

Test plan

  • cargo xtask std-hello passes (~750ms)
  • cargo test --lib -p vibix passes (714 tests)
  • cargo xtask build succeeds
  • cargo xtask ext2-image hash check passes

Closes #852

🤖 Generated with Claude Code

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6bdd1d5e-ff5f-4448-93a0-73b88b35ccc1

📥 Commits

Reviewing files that changed from the base of the PR and between c552942 and 07c58a8.

📒 Files selected for processing (1)
  • xtask/src/main.rs

📝 Walkthrough

Walkthrough

Adds out-of-tree userspace std_hello built with -Z build-std for x86_64-unknown-vibix, extends target rustflags with linker args, eagerly maps ELF PT_LOAD segments in the kernel loader, provides a vibix _start PAL entry, and adds an xtask std-hello subcommand to build, boot, and assert "hello from std" on QEMU serial.

Changes

Rust std Userspace Enablement

Layer / File(s) Summary
Target & Linker Config
.cargo/config.toml
Added -C link-arg=-z -C link-arg=separate-loadable-segments and -C link-arg=--image-base=0x400000 to target.x86_64-unknown-vibix.rustflags.
Workspace Manifest
Cargo.toml
Added userspace/std_hello to workspace.exclude.
Kernel ELF Loader (eager install)
kernel/src/mem/loader.rs
load_user_elf_with_vmas now iterates parsed.load_segments() and calls map_user_segment(...) to eagerly install PT_LOAD mappings into the provided _pml4, returning early on mapping errors before TLS/PT_INTERP handling.
Std PAL Entry Point
library/std/src/sys/pal/vibix/mod.rs
Added #[cfg(not(test))] #[unsafe(no_mangle)] pub unsafe extern "C" fn _start() -> ! that calls main(0, null) and performs exit_group; init() body cleared.
Userspace Binary & Manifest
userspace/std_hello/Cargo.toml, userspace/std_hello/src/main.rs
New standalone std_hello crate with binary main() printing hello from std; includes an empty [workspace] and intended for out-of-tree -Z build-std builds.
Build & Test Automation
xtask/src/main.rs
Added std-hello xtask subcommand and build_userspace_std_hello() to build the out-of-tree crate with -Z build-std --target x86_64-unknown-vibix.json, strip the ELF, install as /init on an ext2 rootfs, boot QEMU, capture serial, and assert hello from std within a 120s watchdog.

Sequence Diagram

sequenceDiagram
    participant Dev as Developer (xtask)
    participant Cargo as Cargo (-Z build-std)
    participant Host as xtask (image assembly)
    participant QEMU as QEMU VM
    participant Kernel as vibix Kernel
    participant Loader as ELF Loader
    participant PML4 as Page Tables (_pml4)
    participant Userspace as std_hello _start
    participant Main as main()
    participant Serial as QEMU Serial

    Dev->>Cargo: build std_hello with -Z build-std --target x86_64-unknown-vibix
    Cargo-->>Dev: std_hello ELF (image-base set)
    Dev->>Host: inject ELF into ext2 rootfs, create ISO
    Dev->>QEMU: boot ISO
    QEMU->>Kernel: boot
    Kernel->>Loader: load_user_elf_with_vmas(std_hello)
    Loader->>Loader: register PT_LOAD VMAs
    Loader->>PML4: map_user_segment() for each PT_LOAD (eager)
    PML4-->>Loader: mappings installed
    Kernel->>Userspace: jump to _start (PID 1)
    Userspace->>Main: call main(argc=0, argv=null)
    Main->>Serial: println!("hello from std")
    Serial-->>Dev: capture "hello from std"
    Main->>Kernel: exit_group syscall
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related issues

Possibly related PRs

Poem

🐇
I pack flags and tiptoe to the guest,
map segments early, set an image rest.
std_hello hops up, squeaks from userland,
QEMU hums back—"hello from the band!"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add std_hello e2e test: println! on vibix (#852)' accurately summarizes the main change - adding an end-to-end test for running a Rust binary with println on vibix, which matches the primary objective.
Description check ✅ Passed The description comprehensively explains the changes: adding the std_hello e2e test, working around a demand-paging bug, and cleaning up the PAL, all of which align with the changeset.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #852: creates userspace/std_hello with println, builds with build-std, installs into ext2 rootfs, boots under QEMU, captures serial output, and adds cargo xtask test [#852].
Out of Scope Changes check ✅ Passed All changes directly support the std_hello e2e test objective: kernel loader fix for demand-paging, PAL cleanup, xtask implementation, and Cargo configuration adjustments are all necessary scope items.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch m852-std-hello-e2e

Comment @coderabbitai help to get the list of available commands and usage tips.

Phase 1 capstone: a standard Rust binary using println! runs on vibix
under QEMU and emits "hello from std" on serial.

- userspace/std_hello: standalone binary with `println!("hello from std")`
- xtask std-hello: builds with -Z build-std, installs into ext2, boots QEMU
- kernel: eagerly map PT_LOAD pages in load_user_elf_with_vmas to work
  around a demand-paging bug where FileObject::fault serves zero-filled
  pages for certain file offsets
- library/std PAL: remove diagnostic prints from _start

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dburkart dburkart force-pushed the m852-std-hello-e2e branch from e63fcc7 to c552942 Compare May 5, 2026 07:33
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a 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

🧹 Nitpick comments (2)
kernel/src/mem/loader.rs (1)

363-373: ⚡ Quick win

Update the function contract comment above this workaround.

The surrounding docs still say load_user_elf_with_vmas leaves pml4 untouched and eagerly maps nothing, but this loop now installs every PT_LOAD page up front. Please document the temporary eager-map behavior and its scope so callers are not reading a stale contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kernel/src/mem/loader.rs` around lines 363 - 373, Update the function
contract comment for load_user_elf_with_vmas to state that, as a temporary
workaround, the function now eagerly maps all PT_LOAD pages into the provided
pml4 (via map_user_segment over parsed.load_segments()) instead of leaving pml4
untouched; clearly document the scope (this is a workaround for the
init-binary/demand-paging bug and affects only PT_LOAD segments installed into
the PML4 up front), note that callers must not assume pml4 remains unchanged nor
rely on lazy/demand paging for those pages, and mark the behavior as temporary
with a reference to the bug (`#852`) and where to revert (the eager mapping loop).
xtask/src/main.rs (1)

623-653: ⚡ Quick win

Add preflight validation for __CARGO_TESTS_ONLY_SRC_ROOT environment variable usage.

__CARGO_TESTS_ONLY_SRC_ROOT is an internal test-only Cargo environment variable, not a supported public interface. This build flow couples the std-hello target to undocumented Cargo internals. Add explicit detection and validation (e.g., checking for expected library structure or Cargo version constraints) so a toolchain update that removes this escape hatch fails visibly rather than silently breaking the build.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@xtask/src/main.rs` around lines 623 - 653, In build_userspace_std_hello, add
a preflight validation before setting the __CARGO_TESTS_ONLY_SRC_ROOT env:
ensure the library_root has the expected in-repo std layout (e.g.,
library_root.join("Cargo.toml") and library_root.join("src").join("lib.rs") or
at least library_root.join("src").exists()) and return a clear error if missing,
and also validate the toolchain supports the unstable build flags (check cargo
--version contains "nightly" or run a quick cargo -Z help probe and fail with a
descriptive message if unsupported); this makes the use of the internal
__CARGO_TESTS_ONLY_SRC_ROOT explicit and fails visibly if the escape hatch or
layout is absent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@xtask/src/main.rs`:
- Line 258: The new "std-hello" subcommand is implemented in xtask (see the
match arm "std-hello" => std_hello(&opts)? and the std_hello function) but it's
not exercised in CI; add it to the CI smoke pipeline and to the aggregate
runner: update test_all() in xtask/src/main.rs to call std_hello(&opts)? (so
local runners exercise it), and update the relevant GitHub Actions workflow
under .github/workflows (the smoke/test job) to run `cargo xtask std-hello` as
part of the smoke tests step (or add it to the existing cargo xtask test_all
invocation) so the subcommand is executed during CI.

---

Nitpick comments:
In `@kernel/src/mem/loader.rs`:
- Around line 363-373: Update the function contract comment for
load_user_elf_with_vmas to state that, as a temporary workaround, the function
now eagerly maps all PT_LOAD pages into the provided pml4 (via map_user_segment
over parsed.load_segments()) instead of leaving pml4 untouched; clearly document
the scope (this is a workaround for the init-binary/demand-paging bug and
affects only PT_LOAD segments installed into the PML4 up front), note that
callers must not assume pml4 remains unchanged nor rely on lazy/demand paging
for those pages, and mark the behavior as temporary with a reference to the bug
(`#852`) and where to revert (the eager mapping loop).

In `@xtask/src/main.rs`:
- Around line 623-653: In build_userspace_std_hello, add a preflight validation
before setting the __CARGO_TESTS_ONLY_SRC_ROOT env: ensure the library_root has
the expected in-repo std layout (e.g., library_root.join("Cargo.toml") and
library_root.join("src").join("lib.rs") or at least
library_root.join("src").exists()) and return a clear error if missing, and also
validate the toolchain supports the unstable build flags (check cargo --version
contains "nightly" or run a quick cargo -Z help probe and fail with a
descriptive message if unsupported); this makes the use of the internal
__CARGO_TESTS_ONLY_SRC_ROOT explicit and fails visibly if the escape hatch or
layout is absent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e1440e39-58cf-48d0-90ad-b29a65e0f92d

📥 Commits

Reviewing files that changed from the base of the PR and between e764c53 and e63fcc7.

📒 Files selected for processing (7)
  • .cargo/config.toml
  • Cargo.toml
  • kernel/src/mem/loader.rs
  • library/std/src/sys/pal/vibix/mod.rs
  • userspace/std_hello/Cargo.toml
  • userspace/std_hello/src/main.rs
  • xtask/src/main.rs

Comment thread xtask/src/main.rs
repro_fork_build(&opts)?;
}
"shell-pipeline" => shell_pipeline(&opts)?,
"std-hello" => std_hello(&opts)?,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -C2 --hidden -g '.github/**' '\bstd-hello\b|cargo xtask (test|smoke)' .

Repository: dburkart/vibix

Length of output: 4230


The std-hello subcommand is not wired into any CI workflow.

The grep across .github/workflows/ found no invocations of cargo xtask std-hello, despite the subcommand existing in xtask/src/main.rs. The PR objective explicitly requires this to be part of the CI smoke test pipeline, but test_all() still only runs unit and integration tests. The new subcommand will regress silently in CI.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@xtask/src/main.rs` at line 258, The new "std-hello" subcommand is implemented
in xtask (see the match arm "std-hello" => std_hello(&opts)? and the std_hello
function) but it's not exercised in CI; add it to the CI smoke pipeline and to
the aggregate runner: update test_all() in xtask/src/main.rs to call
std_hello(&opts)? (so local runners exercise it), and update the relevant GitHub
Actions workflow under .github/workflows (the smoke/test job) to run `cargo
xtask std-hello` as part of the smoke tests step (or add it to the existing
cargo xtask test_all invocation) so the subcommand is executed during CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dburkart dburkart merged commit c068777 into main May 5, 2026
26 of 27 checks passed
@dburkart dburkart deleted the m852-std-hello-e2e branch May 5, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

End-to-end test: println!("hello from std") running on vibix under QEMU

2 participants