summaryrefslogtreecommitdiffstats
path: root/rsnix
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rsnix/src/memory.rs84
1 files changed, 60 insertions, 24 deletions
diff --git a/rsnix/src/memory.rs b/rsnix/src/memory.rs
index 3362d94..ecaf806 100644
--- a/rsnix/src/memory.rs
+++ b/rsnix/src/memory.rs
@@ -405,58 +405,94 @@ fn heap_guard_report(ptr: usize, rsp: usize) -> ! {
405 // Words around the block header — the corruption lives in the 405 // Words around the block header — the corruption lives in the
406 // header's size/free slots or the payload. Only when the addresses 406 // header's size/free slots or the payload. Only when the addresses
407 // are inside the mapped heap (reading a garbage pointer would fault 407 // are inside the mapped heap (reading a garbage pointer would fault
408 // mid-report). 408 // mid-report). Four words per line: the fault band is ~110 chars
409 let mut b4 = [0u8; 216]; 409 // wide, so one long line would truncate under hand-copy.
410 let n4 = { 410 let mut b4 = [0u8; 96];
411 let mut w = crate::strbuf::FmtBuf::new(&mut b4); 411 let mut b4b = [0u8; 96];
412 let (n4, n4b) = {
412 let focus = if block >= hs && block < he { block } else { ptr }; 413 let focus = if block >= hs && block < he { block } else { ptr };
413 if focus >= hs + 8 && focus < he { 414 if focus >= hs + 8 && focus < he {
414 let lo = (focus - 16).max(hs); 415 let lo = (focus - 16).max(hs);
415 let hi = (focus + 40).min(he - 8); 416 let hi = (focus + 40).min(he - 8);
417 let mut w = crate::strbuf::FmtBuf::new(&mut b4);
416 let _ = fmt::write(&mut w, core::format_args!("mem:")); 418 let _ = fmt::write(&mut w, core::format_args!("mem:"));
417 let mut a = lo & !7; 419 let mut a = lo & !7;
418 while a <= hi { 420 let mut n = 0;
421 while a <= hi && n < 4 {
419 let _ = fmt::write( 422 let _ = fmt::write(
420 &mut w, 423 &mut w,
421 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }), 424 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }),
422 ); 425 );
423 a += 8; 426 a += 8;
427 n += 1;
424 } 428 }
429 let mut w2 = crate::strbuf::FmtBuf::new(&mut b4b);
430 let _ = fmt::write(&mut w2, core::format_args!("mem2:"));
431 let mut n = 0;
432 while a <= hi && n < 4 {
433 let _ = fmt::write(
434 &mut w2,
435 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }),
436 );
437 a += 8;
438 n += 1;
439 }
440 (w.len(), w2.len())
425 } else { 441 } else {
442 let mut w = crate::strbuf::FmtBuf::new(&mut b4);
426 let _ = fmt::write(&mut w, core::format_args!("mem: out of heap — no dump")); 443 let _ = fmt::write(&mut w, core::format_args!("mem: out of heap — no dump"));
444 (w.len(), 0)
427 } 445 }
428 w.len()
429 }; 446 };
430 447
431 // Live return-address chain on the stack above our rsp (dealloc ← 448 // Live return-address chain on the stack above our rsp (dealloc ←
432 // drop glue ← shell::run); raw stack words, resolves against the PDB. 449 // drop glue ← shell::run); raw stack words, resolves against the PDB.
433 let mut b5 = [0u8; 216]; 450 // 16 words in 4 lines of 4 — enough to capture the drop caller
434 let n5 = { 451 // chain on the band even when the copy truncates a line.
435 let mut w = crate::strbuf::FmtBuf::new(&mut b5); 452 let mut b5 = [0u8; 96];
436 let _ = fmt::write(&mut w, core::format_args!("stk:")); 453 let mut b6 = [0u8; 96];
454 let mut b7 = [0u8; 96];
455 let mut b8 = [0u8; 96];
456 let (n5, n6, n7, n8) = {
437 let mut a = rsp.wrapping_add(8); 457 let mut a = rsp.wrapping_add(8);
438 for _ in 0..12 { 458 let bufs: [&mut [u8]; 4] = [&mut b5, &mut b6, &mut b7, &mut b8];
439 let v = unsafe { *(a as *const usize) }; 459 let mut lens = [0usize; 4];
440 let _ = fmt::write(&mut w, core::format_args!(" {:x}={:#x}", a, v)); 460 for li in 0..4 {
441 a += 8; 461 let mut w = crate::strbuf::FmtBuf::new(bufs[li]);
462 let lbl = match li {
463 0 => "",
464 1 => "2",
465 2 => "3",
466 _ => "4",
467 };
468 let _ = fmt::write(
469 &mut w,
470 core::format_args!("stk{}:", lbl),
471 );
472 for _ in 0..4 {
473 let v = unsafe { *(a as *const usize) };
474 let _ = fmt::write(&mut w, core::format_args!(" {:x}={:#x}", a, v));
475 a += 8;
476 }
477 lens[li] = w.len();
442 } 478 }
443 w.len() 479 (lens[0], lens[1], lens[2], lens[3])
444 }; 480 };
445 481
446 let l1 = core::str::from_utf8(&b1[..n1]).unwrap_or("!!!"); 482 let l1 = core::str::from_utf8(&b1[..n1]).unwrap_or("!!!");
447 let l2 = core::str::from_utf8(&b2[..n2]).unwrap_or(""); 483 let l2 = core::str::from_utf8(&b2[..n2]).unwrap_or("");
448 let l3 = core::str::from_utf8(&b3[..n3]).unwrap_or(""); 484 let l3 = core::str::from_utf8(&b3[..n3]).unwrap_or("");
449 let l4 = core::str::from_utf8(&b4[..n4]).unwrap_or(""); 485 let l4 = core::str::from_utf8(&b4[..n4]).unwrap_or("");
486 let l4b = if n4b > 0 { core::str::from_utf8(&b4b[..n4b]).unwrap_or("") } else { "" };
450 let l5 = core::str::from_utf8(&b5[..n5]).unwrap_or(""); 487 let l5 = core::str::from_utf8(&b5[..n5]).unwrap_or("");
451 crate::serial::write_raw(l2); 488 let l6 = core::str::from_utf8(&b6[..n6]).unwrap_or("");
452 crate::serial::write_raw("\r\n"); 489 let l7 = core::str::from_utf8(&b7[..n7]).unwrap_or("");
453 crate::serial::write_raw(l3); 490 let l8 = core::str::from_utf8(&b8[..n8]).unwrap_or("");
454 crate::serial::write_raw("\r\n"); 491 for l in [l2, l3, l4, l4b, l5, l6, l7, l8] {
455 crate::serial::write_raw(l4); 492 crate::serial::write_raw(l);
456 crate::serial::write_raw("\r\n"); 493 crate::serial::write_raw("\r\n");
457 crate::serial::write_raw(l5); 494 }
458 crate::serial::write_raw("\r\n"); 495 let lines = [l1, l2, l3, l4, l4b, l5, l6, l7, l8];
459 let lines = [l1, l2, l3, l4, l5];
460 crate::gop::dump_lines(&lines); 496 crate::gop::dump_lines(&lines);
461 crate::fs::write_crash_log(&lines); 497 crate::fs::write_crash_log(&lines);
462 crate::interrupts::halt() 498 crate::interrupts::halt()