()
| 17 | // Run the test with nocapture to see the trace. |
| 18 | #[test] |
| 19 | fn kernel_asm_diag() { |
| 20 | use virtual_machine::virtual_machine::StepOutcome; |
| 21 | |
| 22 | let stdlib_objs = |
| 23 | CompilationPipeline::compile_stdlib_objects(TargetMode::Kernel).expect("stdlib compile"); |
| 24 | let mut kernel_objs = |
| 25 | CompilationPipeline::compile_kernel_module_objects().expect("kernel module compile"); |
| 26 | // The kernel build marks `kmain` as an ABI export (kernel.build); the flat closure |
| 27 | // leaves it local, so mark it here or `entry`'s external reference stays unresolved. |
| 28 | for (_, obj) in &mut kernel_objs { |
| 29 | if obj.has_symbol("kmain") { |
| 30 | obj.mark_entry_global("kmain"); |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | let mut pipeline = CompilationPipeline::new(); |
| 35 | pipeline.set_target_mode(TargetMode::Kernel); |
| 36 | pipeline.set_write_artifacts(false); |
| 37 | pipeline.set_entry_point(Some("_kernel_start".to_owned())); |
| 38 | |
| 39 | let mut modules: Vec<(&str, &AssembledOutput)> = |
| 40 | stdlib_objs.iter().map(|(n, o)| (n.as_str(), o)).collect(); |
| 41 | for (name, obj) in &kernel_objs { |
| 42 | modules.push((name.as_str(), obj)); |
| 43 | } |
| 44 | let assembled = pipeline.link_assembled_objects(&modules).expect("link"); |
| 45 | let mut vm = VirtualMachine::new_kernel(&assembled); |
| 46 | |
| 47 | eprintln!("\n=== STEP TRACE (first 500000 steps) ==="); |
| 48 | let mut uart_so_far = String::new(); |
| 49 | for step in 0..500_000 { |
| 50 | match vm.step() { |
| 51 | Ok(StepOutcome::Halted(code)) => { |
| 52 | eprintln!(" [step {step}] HALTED with code {code}"); |
| 53 | break; |
| 54 | } |
| 55 | Ok(StepOutcome::Continue) => {} |
| 56 | Err(e) => { |
| 57 | eprintln!(" [step {step}] ERROR: {e:?}"); |
| 58 | break; |
| 59 | } |
| 60 | } |
| 61 | // drain UART each step so we can see where output stops |
| 62 | let new_output = String::from_utf8_lossy(&vm.drain_uart_output()).into_owned(); |
| 63 | if !new_output.is_empty() { |
| 64 | uart_so_far.push_str(&new_output); |
| 65 | eprint!("{new_output}"); |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | eprintln!("\n=== UART OUTPUT SO FAR ===\n{uart_so_far}"); |
| 70 | } |
| 71 | |
| 72 | // --- Linking helper --- |
| 73 | // The canonical link path the GUI also uses: stdlib and user compile separately, |
nothing calls this directly
no test coverage detected