chore(debug): 加临时探针定位 MMAP 返回高半污染与 Tk.buf 野指针 - MMAP/get_winbuf/redraw
This commit is contained in:
1 parent
53535c557e
commit
89a319e1be
3 files changed
+60
-31
No files matched your search
@@ -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
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user