diff options
Diffstat (limited to 'rsnix/src/memory.rs')
| -rw-r--r-- | rsnix/src/memory.rs | 120 |
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() |
