Files
Viper_VRTE/sys.vp
T
TermiNexus db3be6968f fix(memhub,gzip): 内存池 OOM 归属画像与 free 拒绝现场;gzip 注解 *= 词法粘连
memhub: alloc 失败打印归属 site/ctx 与存活块 order 分布(新增 dump_alive_orders);free 被 _is_valid_ptr 拒绝时首次打印现场;接通 big_alloc_count

gzip: ub: uchar*= buf 补空格(*= 被词法合并为单 OP,注解止于 uchar)

新增 traceback 模块;删除 dbgstack.vp;其余模块随新语法与尺寸口径同步
2026-09-26 19:27:24 +08:00

164 lines
5.3 KiB
Plaintext

import t
from stdint import *
import platmacro
import memhub
import string
import stdio
# Windows backend dependencies
import w32.win32base
import w32.win32process
# POSIX backend dependencies
import posix
# Module global MBuddy pointer (initialized in user main), Plans to ban
_mbuddy: memhub.MemBuddy*
# =============================================================================
# C Standard Library IO Declarations
# =============================================================================
extern def fgets(buf: bytes, size: int, stream: rawptr) -> str
extern def fflush(stream: rawptr) -> int
# C standard library exit (terminates the process after flushing the buffer, cross-platform)
extern def exit(status: int)
# =============================================================================
# Platform Information
# =============================================================================
# Maximum integer value (64-bit platform ssize_t upper limit)
define maxsize = 9223372036854775807 # 2^63 - 1
def platform() -> str:
"""Returns the platform identifier string ('win32' or 'linux')."""
if platmacro.IS_WINDOWS: return "win32"
return "linux"
# =============================================================================
# Process Information
# =============================================================================
def get_pid() -> int:
"""返回当前进程 ID"""
if platmacro.IS_WINDOWS: return w32.win32process.GetCurrentProcessId()
return posix.getpid()
# =============================================================================
# Command Line Arguments (argv)
# =============================================================================
# global argv status (initialized on first access)
_argc: int = 0
_argv: str*
def _init_argv():
"""Initialize global argv once on first access"""
global _argc, _argv
if _argc != 0: return
# 必须用 if/else 派发:编译器只翻译"调用表达式语句",三元表达式语句会被丢弃(argv 恒空)
if platmacro.IS_WINDOWS:
_init_argv_win32()
else:
_init_argv_posix()
def _init_argv_win32():
"""Windows: GetCommandLineA + manual parsing (handle spaces/double quotes/backslashes)"""
global _argc, _argv
cmdline: str = w32.win32base.GetCommandLineA()
if cmdline == None:
stdio.printf("ERROR: GetCommandLineA 返回 NULL,无法获取命令行,argv 将为空\n")
return
cmdlen: sizet = len(cmdline)
if cmdlen == 0:
stdio.printf("ERROR: 命令行字符串为空,无法获取参数,argv 将为空\n")
return
# Allocate buffer for parameter strings (worst case: entire command line + argc \0s)
buf: bytes = _mbuddy.alloc(cmdlen + 1)
if buf == None: return
# Allocate pointer array for argv (worst case: each character is a parameter)
max_args: sizet = cmdlen + 1
argv_arr: str* = str*(_mbuddy.alloc(max_args * platmacro.SIZEOF_POINTER))
if argv_arr == None: return
argc: int = 0
j: sizet = 0
in_quote: bool = False
in_arg: bool = False
for i in range(cmdlen):
ch: int = cmdline[i]
if ch == 34: # Double quote
in_quote = not in_quote
if not in_arg:
argv_arr[argc] = str(buf + j)
argc += 1
in_arg = True
elif (ch == 32 or ch == 9) and not in_quote:
# Space or Tab (outside quotes): parameter delimiter
if in_arg:
buf[j] = 0
j += 1
in_arg = False
else:
if not in_arg:
argv_arr[argc] = str(buf + j)
argc += 1
in_arg = True
buf[j] = ch
j += 1
if in_arg: buf[j] = 0
_argc = argc
_argv = argv_arr
def _init_argv_posix():
"""POSIX: Read cmdline from /proc/self/cmdline (\0) separated parameters"""
global _argc, _argv
fd: int = posix.open("/proc/self/cmdline", posix.O_RDONLY, 0)
if fd < 0: return
# Read cmdline (4KB)
buf: bytes = _mbuddy.alloc(4096) # Need to verify size of buffer
if buf == None:
posix.close(fd)
return
total: ssize_t = posix.read(fd, buf, 4096)
posix.close(fd)
if total <= 0: return
# Calculate argument count (\0 delimited)
argc: int = 0
total_size: sizet = sizet(total)
for i in range(total_size):
if buf[i] == 0: argc += 1
if argc == 0: return
# Allocate pointer array for argv (argc pointers)
argv_arr: str* = str*(_mbuddy.alloc(argc * platmacro.SIZEOF_POINTER))
if argv_arr == None: return
# Populate pointer array (start address of each parameter)
argv_arr[0] = str(buf)
idx: int = 1
i = 0
while i < total_size and idx < argc:
if buf[i] == 0:
argv_arr[idx] = str(buf + i + 1)
idx += 1
i += 1
_argc = argc
_argv = argv_arr
def argc() -> int:
"""Returns the number of command line arguments. Automatically initializes on the first call."""
if _argc == 0: _init_argv()
return _argc
def argv(index: int) -> str:
"""Returns the command line argument at index `index` (starting from 0).
Automatically initializes on first call. Returns None if the index is out of range."""
if _argc == 0: _init_argv()
if index < 0 or index >= _argc: return None
return _argv[index]