chore(debug): 加临时探针定位 MMAP 返回高半污染与 Tk.buf 野指针 - MMAP/get_winbuf/redraw

This commit is contained in:
TermiNexus committed 2026-10-15 16:20:14 +08:00
1 parent 53535c557e
commit 89a319e1be
3 files changed
+60 -31

No files matched your search

+16
View File
@@ -350,13 +350,29 @@ def SPAWN(path_ptr: str, blocking: int) -> int:
define USER_HEAP_BASE = 0x20000000
# [临时探针] MMAP 返回形态:定位"heap 高半被污染"与"重复 malloc 导致堆暴涨"(定位后删除)
_mmap_dbg: int = 0
def MMAP(size: uint64) -> uint64:
global _mmap_dbg
p: process.Process* = _current_proc()
if size == 0: return 0
aligned_size: uint64 = (size + 4095) & ~uint64(4095)
if p.heap_start == 0:
p.heap_start = USER_HEAP_BASE
heap_end: uint64 = p.heap_start + p.heap_size
# [临时探针] end 的低半应是 0x20000000 + k*0x1000,高半必须为 0。
hi: uint64 = heap_end >> 32
if _mmap_dbg < 6 or (hi != 0 and _mmap_dbg < 16) or (p.heap_size > 0x2000000 and _mmap_dbg < 24):
_mmap_dbg = _mmap_dbg + 1
_mmb: [192]char
viperlib.snprintf(&_mmb, 192, "[mmap] pid=%d sz=%lu start=0x%lx acc=0x%lx end=0x%lx hi=%lu\n",
process.current(), size, p.heap_start, p.heap_size, heap_end, hi)
serial.puts(&_mmb)
if p.heap_start != uint64(USER_HEAP_BASE):
serial.puts("[mmap] BAD: heap_start != 0x20000000\n")
if hi != 0:
serial.puts("[mmap] BAD: heap_end high half != 0\n")
new_end: uint64 = heap_end + aligned_size
for va in range(heap_end, new_end, 4096):
phys_page: rawptr = mm.malloc(4096)
+29 -31
View File
@@ -52,7 +52,10 @@ _g_wl_sticky: t.CArray[int, MAX_WIDGETS]
_g_layout_init: int
_hex_tbl: t.CArray[char, 17] = "0123456789ABCDEF"
_hex_buf: t.CArray[char, 20] = "0000000000000000000"
_hex_buf: t.CArray[char, 20] = "0000000000000000000"
# [临时探针] Tk.buf 形态(定位后删除)
_tk_dbg: int = 0
def _serial_puts(s: const str):
_syscall._syscall1(uint64(_syscall.SERIAL_PUTS), uint64(s))
@@ -289,9 +292,7 @@ def _register_widget(master: t.CPtr, widget: Widget*) -> int:
tk.widget_count = idx + 1
return idx
@t.Object
@t.CVTable
class Widget:
virtual class Widget:
x: int
y: int
w: int
@@ -321,9 +322,7 @@ class Widget:
if h > 0:
self.h = h
@t.Object
@t.CVTable
class Label(Widget):
virtual class Label(Widget):
text: t.CArray[char, 64]
color: uint32
@@ -344,7 +343,7 @@ class Label(Widget):
self.text[i] = ch
i += 1
self.text[i] = 0
_register_widget(master, t.CType(self, Widget, t.CPtr))
_register_widget(master, Widget*(self))
def draw(self, fb: UINT32PTR, fw: int, fh: int):
_draw_text(fb, fw, fh, self.x, self.y, &self.text[0], self.color)
@@ -364,9 +363,7 @@ class Label(Widget):
if color is not None:
self.color = color
@t.Object
@t.CVTable
class Button(Widget):
virtual class Button(Widget):
text: t.CArray[char, 32]
fill_color: uint32
text_color: uint32
@@ -393,7 +390,7 @@ class Button(Widget):
self.text[i] = ch
i += 1
self.text[i] = 0
_register_widget(master, t.CType(self, Widget, t.CPtr))
_register_widget(master, Widget*(self))
def draw(self, fb: UINT32PTR, fw: int, fh: int):
fill: uint32 = self.fill_color
@@ -422,7 +419,7 @@ class Button(Widget):
_draw_hline(fb, fw, fh, self.x - 1, self.y + self.h, self.w + 2, border)
_draw_vline(fb, fw, fh, self.x - 1, self.y - 1, self.h + 2, border)
_draw_vline(fb, fw, fh, self.x + self.w, self.y - 1, self.h + 2, border)
tl: int = string.strlen(&self.text[0])
tl: int = int(string.strlen(&self.text[0]))
tx: int = self.x + (self.w - 8 * tl) / 2
ty: int = self.y + (self.h - CHAR_H) / 2
_draw_text(fb, fw, fh, tx, ty, &self.text[0], self.text_color)
@@ -486,9 +483,7 @@ pop r12""",
if callback is not None:
self.callback = callback
@t.Object
@t.CVTable
class Entry(Widget):
virtual class Entry(Widget):
text: t.CArray[char, 64]
text_len: int
cursor_pos: int
@@ -517,7 +512,7 @@ class Entry(Widget):
self.cursor_color = uint32(0x000000)
for i in range(64):
self.text[i] = 0
_register_widget(master, t.CType(self, Widget, t.CPtr))
_register_widget(master, Widget*(self))
def draw(self, fb: UINT32PTR, fw: int, fh: int):
bg: uint32 = self.bg_color
@@ -572,7 +567,7 @@ class Entry(Widget):
if not self.focused:
self.focused = 1
tk4: Tk* = t.CType(self.master, Tk, t.CPtr)
tk4.focused_widget = t.CType(self, Widget, t.CPtr)
tk4.focused_widget = Widget*(self)
rel_x: int = ex - self.x - 6
if rel_x < 0: rel_x = 0
new_pos: int = (rel_x + CHAR_W / 2) / CHAR_W
@@ -649,9 +644,7 @@ class Entry(Widget):
if border_color is not None:
self.border_color = border_color
@t.Object
@t.CVTable
class Scrollbar(Widget):
virtual class Scrollbar(Widget):
orient: int
command: t.CPtr
slider_first: int
@@ -691,7 +684,7 @@ class Scrollbar(Widget):
self.slider_color = uint32(0x4A4A6A)
self.arrow_color = uint32(0xAAAAAA)
self.slider_hover = 0
_register_widget(master, t.CType(self, Widget, t.CPtr))
_register_widget(master, Widget*(self))
def draw(self, fb: UINT32PTR, fw: int, fh: int):
_fill_rect(fb, fw, fh, self.x, self.y, self.w, self.h, self.trough_color)
@@ -860,9 +853,7 @@ pop r12""",
self.slider_first = first
self.slider_last = last
@t.Object
@t.CVTable
class FBCanvas(Widget):
virtual class FBCanvas(Widget):
_fb: UINT32PTR
_cw: int
_ch: int
@@ -880,7 +871,7 @@ class FBCanvas(Widget):
self._fb = None
self._cw = w
self._ch = h
_register_widget(master, t.CType(self, Widget, t.CPtr))
_register_widget(master, Widget*(self))
def draw(self, fb: UINT32PTR, fw: int, fh: int):
if not self._fb: return
@@ -914,9 +905,7 @@ class FBCanvas(Widget):
def get_h(self) -> int:
return self._ch
@t.Object
@t.CVTable
class Text(Widget):
virtual class Text(Widget):
lines: t.CArray[t.CArray[char, 80], TEXT_MAX_LINES]
line_count: int
input_buf: t.CArray[char, 80]
@@ -964,7 +953,7 @@ class Text(Widget):
self.lines[i][j] = 0
for i in range(80):
self.input_buf[i] = 0
_register_widget(master, t.CType(self, Widget, t.CPtr))
_register_widget(master, Widget*(self))
def draw(self, fb: UINT32PTR, fw: int, fh: int):
self._update_scrollbar()
@@ -992,7 +981,7 @@ class Text(Widget):
if not self.focused:
self.focused = 1
tk: Tk* = t.CType(self.master, Tk, t.CPtr)
tk.focused_widget = t.CType(self, Widget, t.CPtr)
tk.focused_widget = Widget*(self)
prompt_y: int = self.y + self.h - CHAR_H - 4
if ey >= prompt_y and ey < prompt_y + CHAR_H:
rel_x: int = ex - self.x - 4 - 2 * CHAR_W
@@ -1367,6 +1356,15 @@ class Tk:
def redraw(self):
self._do_layout()
self.buf = window.get_winbuf(self.win_id)
# [临时探针] Tk.buf 高半非 0 ⇒ 该字段/指针已坏(上限 12 行,定位后删除)
global _tk_dbg
if _tk_dbg < 6 or (uint64(self.buf) >> 32) != 0:
if _tk_dbg < 12:
_tk_dbg = _tk_dbg + 1
_serial_puts("[tk] buf=")
_ptr_to_hex(uint64(self.buf), &_hex_buf[0])
_serial_puts(&_hex_buf[0])
_serial_puts("\n")
sz: int = window.get_win_size(self.win_id)
if sz != 0:
self.bw = sz >> 16
+15
View File
@@ -66,12 +66,27 @@ define WINBUF_MAX_BYTES = 4194304
_winbufs: t.CArray[uint64, 64]
# [临时探针] 窗口缓冲指针形态:高半非 0 即根因现场(定位后删除)
_win_dbg: int = 0
def _dbg_puts(s: const str):
syscall._syscall1(uint64(syscall.SERIAL_PUTS), uint64(s))
def get_winbuf(win_id: int) -> UINT32PTR:
global _win_dbg
if win_id < 0 or win_id >= 64: return None
if _winbufs[win_id] == 0:
p: t.CPtr = stdlib.malloc(WINBUF_MAX_BYTES)
if p is None: return None
_winbufs[win_id] = uint64(p)
if _win_dbg < 4:
_win_dbg = _win_dbg + 1
_dbg_puts("[win] first malloc\n")
# [临时探针] 高半非 0 ⇒ 这里返回的指针就已被污染(上限 12 行)
if (_winbufs[win_id] >> 32) != 0:
if _win_dbg < 12:
_win_dbg = _win_dbg + 1
_dbg_puts("[win] BAD winbuf high half != 0\n")
return t.CPtr(_winbufs[win_id])
def get_win_size(win_id: int) -> int: