()
| 3267 | |
| 3268 | // The inspector reads scheduler and PCB state straight from guest memory, so this |
| 3269 | // guards the PCB field offsets and symbol resolution end to end. |
| 3270 | #[test] |
| 3271 | fn os_inspector_sees_shell_as_pid1() { |
| 3272 | use full_stack::inspect::os_view::{self, OsSymbols, Role}; |
| 3273 | |
| 3274 | let kernel = cached_kernel(); |
| 3275 | let shell = compile_hosted_program("shell"); |
| 3276 | let image = build_fs_image(&[FsEntry::Dir { path: "/home" }]); |
| 3277 | |
| 3278 | let mut vm = setup_kernel_vm(kernel, Some(&shell), Some(&image), ""); |
| 3279 | let _ = vm.run(80_000_000); |
| 3280 | |
| 3281 | let sym = OsSymbols::from_kernel(kernel).expect("kernel scheduler symbols resolve"); |
| 3282 | let procs = os_view::capture(&vm, &sym); |
| 3283 | |
| 3284 | let running: Vec<_> = procs.iter().filter(|p| p.role == Role::Running).collect(); |
| 3285 | assert_eq!( |
| 3286 | running.len(), |
| 3287 | 1, |
| 3288 | "expected exactly one running process; got {}", |
| 3289 | running.len() |
| 3290 | ); |
| 3291 | let shell_proc = running[0]; |
| 3292 | assert_eq!(shell_proc.pid, 1, "shell should be pid 1"); |
| 3293 | assert_eq!(shell_proc.parent, 0, "pid 1 is parented by the kernel (0)"); |
| 3294 | assert!( |
| 3295 | shell_proc.state <= 3, |
| 3296 | "decoded a nonsense state {} (PCB offsets wrong?)", |
| 3297 | shell_proc.state |
| 3298 | ); |
| 3299 | } |
| 3300 | |
| 3301 | // The stack view walks a process's user stack by software Sv39 translation, so a |
| 3302 | // shell that has already made syscalls must yield at least one mapped word. |
| 3303 | #[test] |
| 3304 | fn os_inspector_walks_pid1_stack() { |
| 3305 | use full_stack::inspect::os_view::{self, OsSymbols, Role}; |
| 3306 | |
| 3307 | let kernel = cached_kernel(); |
| 3308 | let shell = compile_hosted_program("shell"); |
| 3309 | let image = build_fs_image(&[FsEntry::Dir { path: "/home" }]); |
| 3310 | |
| 3311 | let mut vm = setup_kernel_vm(kernel, Some(&shell), Some(&image), ""); |
| 3312 | let _ = vm.run(80_000_000); |
| 3313 | |
| 3314 | let sym = OsSymbols::from_kernel(kernel).expect("kernel scheduler symbols resolve"); |
| 3315 | let procs = os_view::capture(&vm, &sym); |
| 3316 | let shell_proc = procs |
| 3317 | .iter() |
| 3318 | .find(|p| p.role == Role::Running) |
| 3319 | .expect("a running process"); |
| 3320 | |
| 3321 | assert!( |
| 3322 | shell_proc.sp != 0 && shell_proc.sp < 0x8000_0000, |
| 3323 | "saved sp {:#x} is not a user-stack address (trap-frame offset wrong?)", |
| 3324 | shell_proc.sp |
| 3325 | ); |
| 3326 | assert!( |
nothing calls this directly
no test coverage detected