refactor: 全量迁移 includes 到新规范语法
按根目录 新规范 迁移 R1/R2/R3/R4/R6/R7/R8/R9:指针 T* 后缀、内建类型短别名、c.Addr/c.Deref 单目化、c.Asm 改 __asm__、t.CDefine 改 define 软关键字、t.CEnum 改 enum。R4 对内建 cast 多参实参保留 c.Deref 原写法(单目化会致 TPC 类型退化)。验证:includes 52/52 编译通过,TransPyV 自举产物顺序回归 77/77 全通过。
This commit is contained in:
1 parent
aecdf27132
commit
e80284a6d5
88 files changed
+4474
-4474
No files matched your search
+83
-83
@@ -444,34 +444,34 @@ extern def GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: CHARPTR, nSize: DWO
|
||||
# 段、WalkViaDbgHelp 的整个函数体、DumpMainThread 的可选加强调用)在置 0 时整体不生成代码
|
||||
# ——范式与依据同 includes/memhub.vp 的 MEMBUDDY_THREAD_SAFE 注释("未取分支整体不生成
|
||||
# 代码 ⇒ 函数体为空")。故置 0 后本模块不留任何 dbghelp 链接期符号。
|
||||
TRACEBACK_USE_DBGHELP: t.CDefine = 1
|
||||
define TRACEBACK_USE_DBGHELP = 1
|
||||
|
||||
# Trigger event values: see includes/w32/win32console.vp (CTRL_C_EVENT=0 / CTRL_BREAK_EVENT=1).
|
||||
# Crash-dump filter return value (winnt.h EXCEPTION_*): the unhandled-exception dump must never
|
||||
# swallow a crash, so its filter always returns CONTINUE_SEARCH (= 0) and hands the exception back
|
||||
# to the system default handling (exit code / WER / ASan report stay exactly as before).
|
||||
TRACEBACK_EXCEPTION_CONTINUE_SEARCH: t.CDefine = 0
|
||||
define TRACEBACK_EXCEPTION_CONTINUE_SEARCH = 0
|
||||
|
||||
# ---- Sidecar (.stackmap) format ----
|
||||
# 20-byte header (magic "TPCS" read little-endian as u32); 20-byte records.
|
||||
TRACEBACK_MAP_MAGIC: t.CDefine = 0x53435054 # "TPCS" ('T','P','C','S' little-endian)
|
||||
TRACEBACK_MAP_VERSION: t.CDefine = 1
|
||||
TRACEBACK_MAP_HEADER: t.CDefine = 20 # header size in bytes
|
||||
TRACEBACK_ENTRY_SIZE: t.CDefine = 20 # bytes per record
|
||||
TRACEBACK_ENTRY_FILEOFF: t.CDefine = 8 # file_off offset within a record
|
||||
TRACEBACK_ENTRY_LINE: t.CDefine = 12 # line offset within a record
|
||||
TRACEBACK_ENTRY_FUNCOFF: t.CDefine = 16 # func_off offset within a record
|
||||
define TRACEBACK_MAP_MAGIC = 0x53435054# "TPCS" ('T','P','C','S' little-endian)
|
||||
define TRACEBACK_MAP_VERSION = 1
|
||||
define TRACEBACK_MAP_HEADER = 20# header size in bytes
|
||||
define TRACEBACK_ENTRY_SIZE = 20# bytes per record
|
||||
define TRACEBACK_ENTRY_FILEOFF = 8# file_off offset within a record
|
||||
define TRACEBACK_ENTRY_LINE = 12# line offset within a record
|
||||
define TRACEBACK_ENTRY_FUNCOFF = 16# func_off offset within a record
|
||||
# Sidecar size cap (defence only: a corrupt entry_count/str_bytes must not demand a huge alloc).
|
||||
TRACEBACK_MAP_LIMIT: t.CDefine = 67108864 # 64 MiB
|
||||
define TRACEBACK_MAP_LIMIT = 67108864# 64 MiB
|
||||
|
||||
# ---- Runtime buffers and limits ----
|
||||
TRACEBACK_PATH_CAP: t.CDefine = 4096 # exe path + ".stackmap" buffer
|
||||
TRACEBACK_LINE_CAP: t.CDefine = 1024 # single output line buffer
|
||||
TRACEBACK_MAX_FRAMES: t.CDefine = 64 # max frames printed
|
||||
TRACEBACK_RBP_MAX_STEP: t.CDefine = 0x100000 # max gap between adjacent rbp values (1 MiB)
|
||||
define TRACEBACK_PATH_CAP = 4096# exe path + ".stackmap" buffer
|
||||
define TRACEBACK_LINE_CAP = 1024# single output line buffer
|
||||
define TRACEBACK_MAX_FRAMES = 64# max frames printed
|
||||
define TRACEBACK_RBP_MAX_STEP = 0x100000# max gap between adjacent rbp values (1 MiB)
|
||||
# RBP chain sanity check: a return address is accepted only within [Base, Base+this).
|
||||
# 128 MiB is far above any real PE image, a coarse "obviously out of range" filter.
|
||||
TRACEBACK_MODULE_MAX: t.CDefine = 0x8000000
|
||||
define TRACEBACK_MODULE_MAX = 0x8000000
|
||||
|
||||
# ---- Collected-frame buffer (Python-traceback output) ----
|
||||
# Frames are collected innermost-first by the walk paths and printed in reverse (outermost
|
||||
@@ -479,24 +479,24 @@ TRACEBACK_MODULE_MAX: t.CDefine = 0x8000000
|
||||
# (TRACEBACK_MAX_FRAMES) plus the ScanStack candidates (TRACEBACK_SCAN_MAX_HITS). It is an
|
||||
# inline array inside TracebackState, so Install's TracebackState.__sizeof__() allocation
|
||||
# covers it (the callback thread allocates nothing). Frames beyond the limit are dropped.
|
||||
TRACEBACK_FRAME_BUF: t.CDefine = 128 # = TRACEBACK_MAX_FRAMES + TRACEBACK_SCAN_MAX_HITS
|
||||
define TRACEBACK_FRAME_BUF = 128# = TRACEBACK_MAX_FRAMES + TRACEBACK_SCAN_MAX_HITS
|
||||
# A hit frame re-reads its source line from the .vp file at dump time, sequentially in fixed
|
||||
# stack chunks (no heap allocation from the callback thread).
|
||||
TRACEBACK_SRC_CHUNK: t.CDefine = 4096 # bytes per ReadFile while scanning for a source line
|
||||
define TRACEBACK_SRC_CHUNK = 4096# bytes per ReadFile while scanning for a source line
|
||||
|
||||
# ---- Stack scan fallback (ScanStack) ----
|
||||
# Scan window [RSP, RSP + this) towards higher addresses (caller direction).
|
||||
TRACEBACK_SCAN_MAX_BYTES: t.CDefine = 0x200000 # 2 MiB
|
||||
define TRACEBACK_SCAN_MAX_BYTES = 0x200000# 2 MiB
|
||||
# Chunked reads: one ReadProcessMemory per chunk instead of one per 8 bytes.
|
||||
TRACEBACK_SCAN_CHUNK_BYTES: t.CDefine = 4096 # 4 KiB per chunk
|
||||
TRACEBACK_SCAN_CHUNK_WORDS: t.CDefine = 512 # 4096 / 8 u64 words per chunk
|
||||
TRACEBACK_SCAN_MAX_HITS: t.CDefine = 64 # max candidate return addresses (scan_candidates=)
|
||||
TRACEBACK_SUSPEND_FAILED: t.CDefine = 0xFFFFFFFF # SuspendThread failure return value
|
||||
define TRACEBACK_SCAN_CHUNK_BYTES = 4096# 4 KiB per chunk
|
||||
define TRACEBACK_SCAN_CHUNK_WORDS = 512# 4096 / 8 u64 words per chunk
|
||||
define TRACEBACK_SCAN_MAX_HITS = 64# max candidate return addresses (scan_candidates=)
|
||||
define TRACEBACK_SUSPEND_FAILED = 0xFFFFFFFF# SuspendThread failure return value
|
||||
# The suffixes ".stackmap" (10) and ".stackdump.txt" (16, incl. NUL) share the same 16-byte
|
||||
# slack check in Install; no extra constant is needed.
|
||||
# FILE_APPEND_DATA(0x0004) is not defined by wf; open the dump file with it so every WriteFile
|
||||
# appends to the end (combined with OPEN_ALWAYS to create the file when missing).
|
||||
TRACEBACK_FILE_APPEND_DATA: t.CDefine = 0x00000004
|
||||
define TRACEBACK_FILE_APPEND_DATA = 0x00000004
|
||||
|
||||
|
||||
class TracebackState():
|
||||
@@ -635,7 +635,7 @@ def EmitToFile(N: int):
|
||||
return
|
||||
_DumpFileFailWarned = 1
|
||||
LB: t.CArray[char, 160]
|
||||
M: int = stdio.snprintf(&LB, t.CSizeT(160),
|
||||
M: int = stdio.snprintf(&LB, sizet(160),
|
||||
"[traceback] WARN: stack dump file write failed (further file-write failures not reported)\n")
|
||||
if M <= 0:
|
||||
return
|
||||
@@ -672,7 +672,7 @@ def EmitLine(N: int):
|
||||
if DiagEnabled() != 0:
|
||||
_DumpLineNo = _DumpLineNo + 1
|
||||
Pfx: t.CArray[char, 32]
|
||||
Pl: int = stdio.snprintf(&Pfx, t.CSizeT(32), " [dump#%d] ", _DumpLineNo)
|
||||
Pl: int = stdio.snprintf(&Pfx, sizet(32), " [dump#%d] ", _DumpLineNo)
|
||||
if Pl > 0:
|
||||
# Keep room for the trailing '\0' after prefixing.
|
||||
if N + Pl > TRACEBACK_LINE_CAP - 1:
|
||||
@@ -689,7 +689,7 @@ def EmitText(Text: str):
|
||||
"""Write one constant line with no format specifiers (same buffer / WriteFile path)."""
|
||||
if _State == None or _State.LineBuf == None:
|
||||
return
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP), "%s", Text)
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP), "%s", Text)
|
||||
EmitLine(N)
|
||||
|
||||
|
||||
@@ -719,11 +719,11 @@ def EmitEarly(Text: str):
|
||||
def EmitEarlyCode(Text: str, Code: ULONG):
|
||||
"""EmitEarly variant that appends a GetLastError code (same output path)."""
|
||||
if _State != None and _State.LineBuf != None:
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP), "%s(GetLastError=%u)\n", Text, Code)
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP), "%s(GetLastError=%u)\n", Text, Code)
|
||||
EmitLine(N)
|
||||
return
|
||||
LB: t.CArray[char, 256]
|
||||
N2: int = stdio.snprintf(&LB, t.CSizeT(256), "%s(GetLastError=%u)\n", Text, Code)
|
||||
N2: int = stdio.snprintf(&LB, sizet(256), "%s(GetLastError=%u)\n", Text, Code)
|
||||
if N2 <= 0:
|
||||
return
|
||||
H: HANDLE = wf.GetStdHandle(wf.STD_ERROR_HANDLE)
|
||||
@@ -794,7 +794,7 @@ def MapFailPlain(Size: int64, Reason: str) -> int:
|
||||
"""Validation failed before the header could be read: print reason + actual file size."""
|
||||
if _State == None or _State.LineBuf == None:
|
||||
return 0
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
"[traceback] WARN: <exe>.stackmap invalid -- %s (file %lld bytes), addresses only this run\n",
|
||||
Reason, Size)
|
||||
EmitLine(N)
|
||||
@@ -805,7 +805,7 @@ def MapFailHdr(Size: int64, Reason: str, Head: bytes) -> int:
|
||||
"""Validation failed with the header read: also print the actual header fields."""
|
||||
if _State == None or _State.LineBuf == None:
|
||||
return 0
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
"[traceback] WARN: <exe>.stackmap invalid -- %s"
|
||||
" (read magic=0x%x version=%u entry_count=%u str_count=%u str_bytes=%u; file %lld bytes),"
|
||||
" addresses only this run\n",
|
||||
@@ -819,7 +819,7 @@ def MapFailEntry(Size: int64, Index: int, Reason: str, Got: uint64) -> int:
|
||||
"""Record-table validation failed: print the offending index and value."""
|
||||
if _State == None or _State.LineBuf == None:
|
||||
return 0
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
"[traceback] WARN: <exe>.stackmap invalid -- %s (entry %d, value=0x%llx; file %lld bytes),"
|
||||
" addresses only this run\n",
|
||||
Reason, Index, Got, Size)
|
||||
@@ -896,12 +896,12 @@ def LoadMapFile(hFile: HANDLE, Size: int64) -> int:
|
||||
Err: ULONG = GetLastError()
|
||||
stdlib.free(t.CPtr(Buf))
|
||||
if _State != None and _State.LineBuf != None:
|
||||
RN: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
RN: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
"[traceback] WARN: read <exe>.stackmap failed (GetLastError=%u),"
|
||||
" addresses only this run\n", Err)
|
||||
EmitLine(RN)
|
||||
return 0
|
||||
if t.CSizeT(Got) != t.CSizeT(Size):
|
||||
if sizet(Got) != sizet(Size):
|
||||
stdlib.free(t.CPtr(Buf))
|
||||
return MapFailPlain(Size, "read fewer bytes than the file size")
|
||||
# Header: magic / version / entry_count / str_count / str_bytes
|
||||
@@ -1037,7 +1037,7 @@ def EmitSourceText(Path: str, LineNo: int):
|
||||
if Out == 0:
|
||||
return
|
||||
Src[Out] = char(0)
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP), " %s\n", Src)
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP), " %s\n", Src)
|
||||
EmitLine(N)
|
||||
|
||||
|
||||
@@ -1069,14 +1069,14 @@ def EmitFrame(Addr: uint64, Base: uint64, Scanned: int):
|
||||
# coarse upper bound WalkRbpChain / ScanStack already use for "inside the main module".
|
||||
if Base == 0 or Addr < Base or Addr >= Base + uint64(TRACEBACK_MODULE_MAX):
|
||||
# Outside the main image (DLL / system / corrupt frame): address only.
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" File \"<0x%llx external>\", line 0, in <unknown>%s\n", Addr, Tail)
|
||||
EmitLine(N)
|
||||
return
|
||||
Rva: uint64 = Addr - Base
|
||||
if _State.MapOk == 0:
|
||||
# No map (sidecar missing/corrupt): keep the address + RVA in the same File line.
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" File \"<0x%llx +0x%llx no source line mapping>\", line 0, in <unknown>%s\n",
|
||||
Addr, Rva, Tail)
|
||||
EmitLine(N)
|
||||
@@ -1092,12 +1092,12 @@ def EmitFrame(Addr: uint64, Base: uint64, Scanned: int):
|
||||
else:
|
||||
First: uint64 = EntryRva(0)
|
||||
Last: uint64 = EntryRva(int(_State.EntryCount) - 1)
|
||||
M: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
M: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" srcline map: rva 0x%llx not hit (%u entries: first rva=0x%llx last rva=0x%llx;"
|
||||
" target < first => writer RVA base mismatch)\n",
|
||||
Rva, _State.EntryCount, First, Last)
|
||||
EmitLine(M)
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" File \"<0x%llx +0x%llx no source line mapping>\", line 0, in <unknown>%s\n",
|
||||
Addr, Rva, Tail)
|
||||
EmitLine(N)
|
||||
@@ -1110,7 +1110,7 @@ def EmitFrame(Addr: uint64, Base: uint64, Scanned: int):
|
||||
FuncName: str = "unknown"
|
||||
if FuncOff != 0:
|
||||
FuncName = str(_State.StrBase + int(FuncOff))
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" File \"%s\", line %u, in %s%s\n", FileName, Line, FuncName, Tail)
|
||||
EmitLine(N)
|
||||
EmitSourceText(FileName, int(Line))
|
||||
@@ -1232,10 +1232,10 @@ def WalkViaDbgHelp(hProcess: HANDLE, hThread: HANDLE, CtxPtr: VOIDPTR,
|
||||
Fta: uint64 = 0
|
||||
if Cur != 0:
|
||||
Fta = uint64(dbg.SymFunctionTableAccess64(hProcess, Cur))
|
||||
D0: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D0: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] StackWalk64 first: ret=%d addrpc=0x%llx fta=0x%llx\n", int(Ok), Cur, Fta)
|
||||
EmitLine(D0)
|
||||
D1: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D1: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] StackWalk64 in: machine=0x%x rip=0x%llx rsp=0x%llx rbp=0x%llx\n",
|
||||
uint32(dbg.IMAGE_FILE_MACHINE_AMD64), InRip, InRsp, InRbp)
|
||||
EmitLine(D1)
|
||||
@@ -1245,13 +1245,13 @@ def WalkViaDbgHelp(hProcess: HANDLE, hThread: HANDLE, CtxPtr: VOIDPTR,
|
||||
else:
|
||||
Reason = "stackwalk_failed"
|
||||
if DiagEnabled() != 0:
|
||||
D2: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D2: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] StackWalk64 returned 0 at frame %d (addrpc=0x%llx), stop\n", i, Cur)
|
||||
EmitLine(D2)
|
||||
if _State.ReadMemFailed != 0 and DiagEnabled() != 0:
|
||||
# Right after the first-frame code, print the read-memory failure (one "0
|
||||
# frames" cause: the callback returned 0 and StackWalk64 stopped).
|
||||
DR: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
DR: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] readmem failed addr=0x%llx size=%u GetLastError=%u\n",
|
||||
_State.ReadMemAddr, _State.ReadMemSize, _State.ReadMemErr)
|
||||
EmitLine(DR)
|
||||
@@ -1259,7 +1259,7 @@ def WalkViaDbgHelp(hProcess: HANDLE, hThread: HANDLE, CtxPtr: VOIDPTR,
|
||||
if Cur == 0:
|
||||
Reason = "addrpc_zero"
|
||||
if DiagEnabled() != 0:
|
||||
D3: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D3: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] StackWalk64 frame %d addrpc=0, stop\n", i)
|
||||
EmitLine(D3)
|
||||
break
|
||||
@@ -1268,7 +1268,7 @@ def WalkViaDbgHelp(hProcess: HANDLE, hThread: HANDLE, CtxPtr: VOIDPTR,
|
||||
Frames = i
|
||||
# Unified "leave walk" diagnostic covering every break and the normal end; Reason is set.
|
||||
if DiagEnabled() != 0:
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] walk: return reason=%s frames=%d\n", Reason, Frames)
|
||||
EmitLine(N)
|
||||
return Frames
|
||||
@@ -1326,7 +1326,7 @@ def WalkRbpChain(Rip: uint64, Rbp: uint64, Base: uint64) -> int:
|
||||
# faulting); dereferencing a wild rbp directly would crash, which the primary path
|
||||
# must never do.
|
||||
OkRead: BOOL = wm.ReadProcessMemory(HProc, t.CPtr(Cur), &Two, sizet(16), &Rd)
|
||||
if OkRead == 0 or t.CSizeT(Rd) < t.CSizeT(16):
|
||||
if OkRead == 0 or sizet(Rd) < sizet(16):
|
||||
# GetLastError must be read immediately after ReadProcessMemory.
|
||||
RpmErr = GetLastError()
|
||||
Reason = "rpm_failed"
|
||||
@@ -1352,14 +1352,14 @@ def WalkRbpChain(Rip: uint64, Rbp: uint64, Base: uint64) -> int:
|
||||
Reason = "step_too_large"
|
||||
Reject = 1
|
||||
if DiagEnabled() != 0:
|
||||
D0: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D0: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] rbp: frame=%d rbp=0x%llx [rbp]=0x%llx [rbp+8]=0x%llx\n", i, Cur, V0, V1)
|
||||
EmitLine(D0)
|
||||
Acc: int = 1
|
||||
if Reject != 0:
|
||||
Acc = 0
|
||||
if DiagEnabled() != 0:
|
||||
D1: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D1: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] rbp: frame=%d rpm_ok=%d rpm_err=%u accept=%d reject_reason=%s\n",
|
||||
i, RpmOk, RpmErr, Acc, Reason)
|
||||
EmitLine(D1)
|
||||
@@ -1414,18 +1414,18 @@ def ScanStack(StartIndex: int, Rsp: uint64, Base: uint64) -> int:
|
||||
Addr: uint64 = Rsp
|
||||
Stop: str = "reached_scan_limit"
|
||||
if DiagEnabled() != 0:
|
||||
D0: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D0: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] scan: rsp=0x%llx upper=0x%llx chunk=%d hits_max=%d\n",
|
||||
Rsp, Upper, TRACEBACK_SCAN_CHUNK_BYTES, TRACEBACK_SCAN_MAX_HITS)
|
||||
EmitLine(D0)
|
||||
while Addr < Upper:
|
||||
Rd: sizet = 0
|
||||
OkRead: BOOL = wm.ReadProcessMemory(HProc, t.CPtr(Addr), &Words, sizet(TRACEBACK_SCAN_CHUNK_BYTES), &Rd)
|
||||
N: int = int(t.CSizeT(Rd) / t.CSizeT(8)) # u64 words actually read in this chunk
|
||||
N: int = int(sizet(Rd) / sizet(8)) # u64 words actually read in this chunk
|
||||
if OkRead == 0 or N <= 0:
|
||||
Er: ULONG = GetLastError()
|
||||
if DiagEnabled() != 0:
|
||||
D1: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D1: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] scan: block read failed addr=0x%llx err=%u, stop\n", Addr, Er)
|
||||
EmitLine(D1)
|
||||
Stop = "block_read_failed"
|
||||
@@ -1459,7 +1459,7 @@ def ScanStack(StartIndex: int, Rsp: uint64, Base: uint64) -> int:
|
||||
k += 1
|
||||
Addr = Addr + uint64(TRACEBACK_SCAN_CHUNK_BYTES)
|
||||
if DiagEnabled() != 0:
|
||||
D2: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
D2: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] scan: scan_candidates=%d stop=%s\n", Hits, Stop)
|
||||
EmitLine(D2)
|
||||
# Collect the inferred frames, capped by the global frame limit (authoritative frames already
|
||||
@@ -1514,7 +1514,7 @@ def PrintFrames(Base: uint64):
|
||||
while j >= 0:
|
||||
EmitFrame(_State.FrameAddr[j], Base, int(_State.FrameScan[j]))
|
||||
j -= 1
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" frames=%d\n", _State.FrameCount)
|
||||
EmitLine(N)
|
||||
|
||||
@@ -1537,7 +1537,7 @@ def WriteDumpHeaderFile(IsBreak: int):
|
||||
Trig: str = "Ctrl+C"
|
||||
if IsBreak != 0:
|
||||
Trig = "Ctrl+Break"
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
"\n===== 栈转储 %04u-%02u-%02u %02u:%02u:%02u.%03u pid=%u 触发=%s 主线程id=%u Seq=%d =====\n",
|
||||
uint32(St.wYear), uint32(St.wMonth), uint32(St.wDay),
|
||||
uint32(St.wHour), uint32(St.wMinute), uint32(St.wSecond),
|
||||
@@ -1599,16 +1599,16 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
MB: int = 1 if _State.ModuleBaseAddr != None else 0
|
||||
N: int = 0
|
||||
if DiagEnabled() != 0:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] Seq=%d cbthread=%u mainthread=%u dump_enter_prev=%d "
|
||||
"mapok=%d symready=%d modinited=%d\n",
|
||||
_State.Seq, wp.GetCurrentThreadId(), _State.MainThreadId, EnterOld,
|
||||
_State.MapOk, _State.SymReady, _State.ModInited)
|
||||
EmitLine(N)
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] modbase=0x%llx SymGetModuleBase64(main)=0x%llx\n", MBase, ModBaseRet)
|
||||
EmitLine(N)
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] frame_buf=%d cb_fta=%d cb_mba=%d\n", FB, FT, MB)
|
||||
EmitLine(N)
|
||||
Trigger: str = "Ctrl+C"
|
||||
@@ -1616,20 +1616,20 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
if IsBreak != 0:
|
||||
Trigger = "Ctrl+Break"
|
||||
AfterTag = "continue"
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" Trigger=%s after_dump=%s mainthread=%u cbthread=%u\n",
|
||||
Trigger, AfterTag, _State.MainThreadId, wp.GetCurrentThreadId())
|
||||
EmitLine(N)
|
||||
hThread: HANDLE = wp.OpenThread(ULONG(wp.THREAD_SUSPEND_RESUME | wp.THREAD_GET_CONTEXT), 0, _State.MainThreadId)
|
||||
if hThread == None or hThread == INVALID_HANDLE_VALUE:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" fallback: OpenThread(main) failed (GetLastError=%u), cannot dump stack\n",
|
||||
GetLastError())
|
||||
EmitLine(N)
|
||||
AtomicLeaveDump()
|
||||
return 0
|
||||
if wp.SuspendThread(hThread) == ULONG(TRACEBACK_SUSPEND_FAILED):
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" fallback: SuspendThread(main) failed (GetLastError=%u), cannot dump stack\n",
|
||||
GetLastError())
|
||||
EmitLine(N)
|
||||
@@ -1641,7 +1641,7 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
ctx: rawptr[wp.CONTEXT] = (rawptr[wp.CONTEXT])(_State.ContextBuf)
|
||||
ctx.ContextFlags = uint32(wp.CONTEXT_FULL)
|
||||
if wp.GetThreadContext(hThread, t.CPtr(_State.ContextBuf)) == 0:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" fallback: GetThreadContext failed (GetLastError=%u), cannot dump stack\n",
|
||||
GetLastError())
|
||||
EmitLine(N)
|
||||
@@ -1669,7 +1669,7 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
AsanPresent = 1
|
||||
DbgUsable: int = DbgHelpUsable()
|
||||
if DiagEnabled() != 0:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] symwalk: use_dbghelp=%d symready=%d asan=%d dbg_usable=%d\n",
|
||||
TRACEBACK_USE_DBGHELP, _State.SymReady, AsanPresent, DbgUsable)
|
||||
EmitLine(N)
|
||||
@@ -1691,19 +1691,19 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
SymTag: str = "rbp-chain primary (dbghelp not required)"
|
||||
if DbgUsable != 0:
|
||||
SymTag = "rbp-chain primary, dbghelp optional"
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" exe base=0x%llx RIP=0x%llx RSP=0x%llx RBP=0x%llx\n",
|
||||
Base, Rip, Rsp, Rbp)
|
||||
EmitLine(N)
|
||||
if DiagEnabled() != 0:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" srcline_map=%s symwalk=%s\n", MapTag, SymTag)
|
||||
EmitLine(N)
|
||||
Frames: int = 0
|
||||
# "enter walk" evidence (only with diagnostics on); if it is missing after a key press while
|
||||
# TRACEBACK_DIAG=1, DumpMainThread returned earlier at one of the three fallbacks above.
|
||||
if DiagEnabled() != 0:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] walk: enter use_dbghelp=%d symready=%d modinited=%d "
|
||||
"frame_buf=%d mapok=%d asan=%d\n",
|
||||
TRACEBACK_USE_DBGHELP, _State.SymReady, _State.ModInited, FB, _State.MapOk,
|
||||
@@ -1712,7 +1712,7 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
if DbgUsable == 0:
|
||||
# Keep a "[diag] StackWalk64 first:" line before the RBP chain (here ret=not-called, with
|
||||
# the prerequisites); a real call would emit it from inside WalkViaDbgHelp.
|
||||
DNC: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
DNC: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] StackWalk64 first: ret=not-called symready=%d cb_fta=%d cb_mba=%d frame_buf=%d\n",
|
||||
_State.SymReady, FT, MB, FB)
|
||||
EmitLine(DNC)
|
||||
@@ -1727,7 +1727,7 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
# able to unwind through the frameless ntdll/kernel32 frames and print the real .vp stack.
|
||||
RbpFrames: int = Frames
|
||||
if DiagEnabled() != 0:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] walk: rbp_chain frames=%d\n", Frames)
|
||||
EmitLine(N)
|
||||
# ---- Second fallback: stack scan (no RBP / frame pointer) ----
|
||||
@@ -1739,7 +1739,7 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
Sc: int = ScanStack(Frames, Rsp, Base)
|
||||
Frames = Frames + Sc
|
||||
if DiagEnabled() != 0:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] walk: scan frames=%d total=%d\n", Sc, Frames)
|
||||
EmitLine(N)
|
||||
# ---- Optional enhancement: only when the RBP chain got <=1 frame and dbghelp is usable ----
|
||||
@@ -1778,7 +1778,7 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
Frames = _State.FrameCount
|
||||
if DiagEnabled() != 0:
|
||||
# "leave walk" evidence, paired with walk: enter.
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [diag] walk: leave frames=%d mapok=%d\n", Frames, _State.MapOk)
|
||||
EmitLine(N)
|
||||
if Frames == 0:
|
||||
@@ -1788,10 +1788,10 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
PrintFrames(Base)
|
||||
# Summary after the whole traceback: dump sequence + dump-file notice.
|
||||
if _DumpFile != None and _DumpFile != INVALID_HANDLE_VALUE:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [traceback] dump seq=%d also appended to <exe>.stackdump.txt\n", _State.Seq)
|
||||
else:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [traceback] dump seq=%d console only (dump file unavailable)\n", _State.Seq)
|
||||
EmitLine(N)
|
||||
EmitText("=== stack dump end ===\n")
|
||||
@@ -1850,7 +1850,7 @@ def DumpCrashThread(Info: VOIDPTR) -> int:
|
||||
Two[0] = 0
|
||||
Two[1] = 0
|
||||
if wm.ReadProcessMemory(HProc, t.CPtr(Info), &Two, sizet(16), &Rd) == 0 \
|
||||
or t.CSizeT(Rd) < t.CSizeT(16):
|
||||
or sizet(Rd) < sizet(16):
|
||||
EmitText(" fallback: EXCEPTION_POINTERS unreadable, crash dump skipped\n")
|
||||
AtomicLeaveDump()
|
||||
return 0
|
||||
@@ -1871,12 +1871,12 @@ def DumpCrashThread(Info: VOIDPTR) -> int:
|
||||
RecWords[0] = 0
|
||||
if Rec != 0:
|
||||
if wm.ReadProcessMemory(HProc, t.CPtr(Rec), &RecWords, sizet(48), &Rd) != 0 \
|
||||
and t.CSizeT(Rd) >= t.CSizeT(48):
|
||||
and sizet(Rd) >= sizet(48):
|
||||
Code = RecWords[0]
|
||||
ExAddr = uint64(RecWords[4]) | (uint64(RecWords[5]) << 32)
|
||||
AvKind = RecWords[8]
|
||||
AvAddr = uint64(RecWords[10]) | (uint64(RecWords[11]) << 32)
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" Trigger=unhandled-exception code=0x%x addr=0x%llx"
|
||||
" av_kind=%u av_addr=0x%llx crashthread=%u\n",
|
||||
Code, ExAddr, AvKind, AvAddr, wp.GetCurrentThreadId())
|
||||
@@ -1887,7 +1887,7 @@ def DumpCrashThread(Info: VOIDPTR) -> int:
|
||||
return 0
|
||||
if wm.ReadProcessMemory(HProc, t.CPtr(CtxPtr), t.CPtr(_State.ContextBuf),
|
||||
wp.CONTEXT.__sizeof__(), &Rd) == 0 \
|
||||
or t.CSizeT(Rd) < t.CSizeT(wp.CONTEXT.__sizeof__()):
|
||||
or sizet(Rd) < sizet(wp.CONTEXT.__sizeof__()):
|
||||
EmitText(" fallback: CONTEXT unreadable, crash dump skipped\n")
|
||||
AtomicLeaveDump()
|
||||
return 0
|
||||
@@ -1896,7 +1896,7 @@ def DumpCrashThread(Info: VOIDPTR) -> int:
|
||||
Rip: uint64 = uint64(ctx.Rip)
|
||||
Rsp: uint64 = uint64(ctx.Rsp)
|
||||
Rbp: uint64 = uint64(ctx.Rbp)
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" exe base=0x%llx RIP=0x%llx RSP=0x%llx RBP=0x%llx\n",
|
||||
Base, Rip, Rsp, Rbp)
|
||||
EmitLine(N)
|
||||
@@ -1906,7 +1906,7 @@ def DumpCrashThread(Info: VOIDPTR) -> int:
|
||||
# dereference). Printed for crashes only: the Ctrl+C path has no faulting instruction whose
|
||||
# operands matter, and this is the one datum that distinguishes "wrong argument" from
|
||||
# "argument right, pointee contents wrong" without another rebuild.
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" regs: rcx=0x%llx rdx=0x%llx r8=0x%llx r9=0x%llx r12=0x%llx\n",
|
||||
uint64(ctx.Rcx), uint64(ctx.Rdx), uint64(ctx.R8), uint64(ctx.R9),
|
||||
uint64(ctx.R12))
|
||||
@@ -1928,11 +1928,11 @@ def DumpCrashThread(Info: VOIDPTR) -> int:
|
||||
Frames = Frames + ScanStack(Frames, Rsp, Base)
|
||||
PrintFrames(Base)
|
||||
if _DumpFile != None and _DumpFile != INVALID_HANDLE_VALUE:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [traceback] crash dump seq=%d also appended to <exe>.stackdump.txt\n",
|
||||
_State.Seq)
|
||||
else:
|
||||
N = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
" [traceback] crash dump seq=%d console only (dump file unavailable)\n",
|
||||
_State.Seq)
|
||||
EmitLine(N)
|
||||
@@ -1980,7 +1980,7 @@ def NoteError(Text: str, Code: ULONG):
|
||||
"""Install/degradation diagnostic: one '<Text>(GetLastError=%u)' line to the dump sink."""
|
||||
if _State == None or _State.LineBuf == None:
|
||||
return
|
||||
N: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
"%s(GetLastError=%u)\n", Text, Code)
|
||||
EmitLine(N)
|
||||
|
||||
@@ -2006,11 +2006,11 @@ def Install() -> int:
|
||||
EmitEarly("[traceback] WARN: path buffer alloc failed, ctrl handler not installed\n")
|
||||
return 0
|
||||
Plen: ULONG = wf.GetModuleFileNameA(None, Pb, ULONG(TRACEBACK_PATH_CAP))
|
||||
if Plen == 0 or t.CSizeT(Plen) >= t.CSizeT(TRACEBACK_PATH_CAP):
|
||||
if Plen == 0 or sizet(Plen) >= sizet(TRACEBACK_PATH_CAP):
|
||||
stdlib.free(t.CPtr(Pb))
|
||||
EmitEarly("[traceback] WARN: GetModuleFileNameA failed, ctrl handler not installed\n")
|
||||
return 0
|
||||
if t.CSizeT(Plen) + 16 > t.CSizeT(TRACEBACK_PATH_CAP):
|
||||
if sizet(Plen) + 16 > sizet(TRACEBACK_PATH_CAP):
|
||||
# 16 bytes of slack covers both ".stackmap" (10) and ".stackdump.txt" (16).
|
||||
stdlib.free(t.CPtr(Pb))
|
||||
EmitEarly("[traceback] WARN: exe path too long to append suffix safely, ctrl handler not installed\n")
|
||||
@@ -2068,7 +2068,7 @@ def Install() -> int:
|
||||
_DumpFile = None
|
||||
EmitText("[traceback] WARN: cannot open stack dump file, console-only output\n")
|
||||
else:
|
||||
DN: int = stdio.snprintf(_State.LineBuf, t.CSizeT(TRACEBACK_LINE_CAP),
|
||||
DN: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
"[traceback] stack dump also written to: %s\n", str(Pb))
|
||||
EmitLine(DN)
|
||||
# (4) load the sidecar (a failure only disables the map; the handler is still installed so at
|
||||
|
||||
Reference in new issue
Block a user