summaryrefslogtreecommitdiffstats
path: root/rsnix/src/memory.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rsnix/src/memory.rs')
-rw-r--r--rsnix/src/memory.rs120
1 files changed, 80 insertions, 40 deletions
diff --git a/rsnix/src/memory.rs b/rsnix/src/memory.rs
index e0f0142..f16f943 100644
--- a/rsnix/src/memory.rs
+++ b/rsnix/src/memory.rs
@@ -480,47 +480,84 @@ fn heap_guard_report(ptr: usize, rsp: usize, size: usize, align: usize) -> ! {
480 w.len() 480 w.len()
481 }; 481 };
482 482
483 // Words around the block header — the corruption lives in the 483 // Candidate block bases for this ptr (payload sits at block+24 for
484 // header's size/free slots or the payload. Only when the addresses 484 // align-1 allocs, block+32 for align-16) with their size/free
485 // are inside the mapped heap (reading a garbage pointer would fault 485 // fields, plus a longer raw window around ptr so the next crash
486 // mid-report). Four words per line: the fault band is ~110 chars 486 // shows the header region and neighbours, not just the payload.
487 // wide, so one long line would truncate under hand-copy.
488 let mut b4 = [0u8; 96]; 487 let mut b4 = [0u8; 96];
489 let mut b4b = [0u8; 96]; 488 let mut b4b = [0u8; 96];
490 let (n4, n4b) = { 489 let mut b4c = [0u8; 96];
491 let focus = if block >= hs && block < he { block } else { ptr }; 490 let mut b4d = [0u8; 96];
492 if focus >= hs + 8 && focus < he { 491 let focus = if block >= hs && block < he { block } else { ptr };
493 let lo = (focus - 16).max(hs); 492 let mut a = (focus.wrapping_sub(48)).max(hs) & !7;
494 let hi = (focus + 40).min(he - 8); 493 let (mut n4, mut n4b, mut n4c, mut n4d) = (0usize, 0usize, 0usize, 0usize);
495 let mut w = crate::strbuf::FmtBuf::new(&mut b4); 494 if focus >= hs + 8 && focus < he {
496 let _ = fmt::write(&mut w, core::format_args!("mem:")); 495 let mut w = crate::strbuf::FmtBuf::new(&mut b4);
497 let mut a = lo & !7; 496 let _ = fmt::write(&mut w, core::format_args!("mem:"));
498 let mut n = 0; 497 for _ in 0..4 {
499 while a <= hi && n < 4 { 498 let _ = fmt::write(
500 let _ = fmt::write( 499 &mut w,
501 &mut w, 500 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }),
502 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }), 501 );
503 ); 502 a += 8;
504 a += 8; 503 }
505 n += 1; 504 n4 = w.len();
506 } 505 let mut w = crate::strbuf::FmtBuf::new(&mut b4b);
507 let mut w2 = crate::strbuf::FmtBuf::new(&mut b4b); 506 let _ = fmt::write(&mut w, core::format_args!("mem2:"));
508 let _ = fmt::write(&mut w2, core::format_args!("mem2:")); 507 for _ in 0..4 {
509 let mut n = 0; 508 let _ = fmt::write(
510 while a <= hi && n < 4 { 509 &mut w,
511 let _ = fmt::write( 510 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }),
512 &mut w2, 511 );
513 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }), 512 a += 8;
514 );
515 a += 8;
516 n += 1;
517 }
518 (w.len(), w2.len())
519 } else {
520 let mut w = crate::strbuf::FmtBuf::new(&mut b4);
521 let _ = fmt::write(&mut w, core::format_args!("mem: out of heap — no dump"));
522 (w.len(), 0)
523 } 513 }
514 n4b = w.len();
515 let mut w = crate::strbuf::FmtBuf::new(&mut b4c);
516 let _ = fmt::write(&mut w, core::format_args!("mem3:"));
517 for _ in 0..4 {
518 let _ = fmt::write(
519 &mut w,
520 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }),
521 );
522 a += 8;
523 }
524 n4c = w.len();
525 let mut w = crate::strbuf::FmtBuf::new(&mut b4d);
526 let _ = fmt::write(&mut w, core::format_args!("mem4:"));
527 for _ in 0..4 {
528 let _ = fmt::write(
529 &mut w,
530 core::format_args!(" {:x}={:#x}", a, unsafe { *(a as *const usize) }),
531 );
532 a += 8;
533 }
534 n4d = w.len();
535 } else {
536 let mut w = crate::strbuf::FmtBuf::new(&mut b4);
537 let _ = fmt::write(&mut w, core::format_args!("mem: out of heap — no dump"));
538 n4 = w.len();
539 };
540 // Explicit candidate-block header fields (size/free at +0/+8).
541 let mut b4e = [0u8; 96];
542 let ne = if ptr >= hs + 24 && ptr <= he {
543 let hb = ptr - 24;
544 let hb2 = ptr - 32;
545 let mut w = crate::strbuf::FmtBuf::new(&mut b4e);
546 let _ = fmt::write(
547 &mut w,
548 core::format_args!(
549 "hdr: b={:#x} s={:#x} f={:#x} b16={:#x} s={:#x} f={:#x}",
550 hb,
551 unsafe { *(hb as *const usize) },
552 unsafe { *((hb + 8) as *const usize) },
553 hb2,
554 unsafe { *(hb2 as *const usize) },
555 unsafe { *((hb2 + 8) as *const usize) },
556 ),
557 );
558 w.len()
559 } else {
560 0
524 }; 561 };
525 562
526 // Live return-address chain on the stack above our rsp (dealloc ← 563 // Live return-address chain on the stack above our rsp (dealloc ←
@@ -563,15 +600,18 @@ fn heap_guard_report(ptr: usize, rsp: usize, size: usize, align: usize) -> ! {
563 let l3b = core::str::from_utf8(&b3b[..n3b]).unwrap_or(""); 600 let l3b = core::str::from_utf8(&b3b[..n3b]).unwrap_or("");
564 let l4 = core::str::from_utf8(&b4[..n4]).unwrap_or(""); 601 let l4 = core::str::from_utf8(&b4[..n4]).unwrap_or("");
565 let l4b = if n4b > 0 { core::str::from_utf8(&b4b[..n4b]).unwrap_or("") } else { "" }; 602 let l4b = if n4b > 0 { core::str::from_utf8(&b4b[..n4b]).unwrap_or("") } else { "" };
603 let l4c = if n4c > 0 { core::str::from_utf8(&b4c[..n4c]).unwrap_or("") } else { "" };
604 let l4d = if n4d > 0 { core::str::from_utf8(&b4d[..n4d]).unwrap_or("") } else { "" };
605 let l4e = if ne > 0 { core::str::from_utf8(&b4e[..ne]).unwrap_or("") } else { "" };
566 let l5 = core::str::from_utf8(&b5[..n5]).unwrap_or(""); 606 let l5 = core::str::from_utf8(&b5[..n5]).unwrap_or("");
567 let l6 = core::str::from_utf8(&b6[..n6]).unwrap_or(""); 607 let l6 = core::str::from_utf8(&b6[..n6]).unwrap_or("");
568 let l7 = core::str::from_utf8(&b7[..n7]).unwrap_or(""); 608 let l7 = core::str::from_utf8(&b7[..n7]).unwrap_or("");
569 let l8 = core::str::from_utf8(&b8[..n8]).unwrap_or(""); 609 let l8 = core::str::from_utf8(&b8[..n8]).unwrap_or("");
570 for l in [l2, l3, l3b, l4, l4b, l5, l6, l7, l8] { 610 for l in [l2, l3, l3b, l4, l4b, l4c, l4d, l4e, l5, l6, l7, l8] {
571 crate::serial::write_raw(l); 611 crate::serial::write_raw(l);
572 crate::serial::write_raw("\r\n"); 612 crate::serial::write_raw("\r\n");
573 } 613 }
574 let lines = [l1, l2, l3, l3b, l4, l4b, l5, l6, l7, l8]; 614 let lines = [l1, l2, l3, l3b, l4, l4b, l4c, l4d, l4e, l5, l6, l7, l8];
575 crate::gop::dump_lines(&lines); 615 crate::gop::dump_lines(&lines);
576 crate::fs::write_crash_log(&lines); 616 crate::fs::write_crash_log(&lines);
577 crate::interrupts::halt() 617 crate::interrupts::halt()