init cli_py
This commit is contained in:
@@ -2,8 +2,125 @@ import bisect
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import ctypes
|
||||
from ctypes import *
|
||||
|
||||
# __pattern = re.compile(r"([0-9a-f]+)-([0-9a-f]+) [\w-]+ [\w:]+ [\w:]+ \S+ (.*?)\n")
|
||||
MAX_NAME_LEN = 15
|
||||
TIMER_MAX_WATCH_NUM = 32
|
||||
CGROUP_NAME_LEN = 32
|
||||
TASK_COMM_LEN = 16
|
||||
BACKTRACE_DEPTH = 30
|
||||
PROCESS_CHAINS_COUNT = 10
|
||||
PROCESS_ARGV_LEN = 128
|
||||
|
||||
|
||||
class threshold(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("task_id", c_int),
|
||||
("name", c_char * (MAX_NAME_LEN + 1)),
|
||||
("ptr", c_void_p),
|
||||
("threshold", c_longlong),
|
||||
]
|
||||
|
||||
|
||||
class variable_monitor_record(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("et_type", c_int),
|
||||
("id", c_ulong),
|
||||
("tv", c_ulonglong),
|
||||
("threshold_num", c_int),
|
||||
("threshold_record", threshold * TIMER_MAX_WATCH_NUM),
|
||||
]
|
||||
|
||||
|
||||
class task_detail(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("cgroup_buf", c_char * CGROUP_NAME_LEN),
|
||||
("cgroup_cpuset", c_char * CGROUP_NAME_LEN),
|
||||
("pid", c_int),
|
||||
("tgid", c_int),
|
||||
("container_pid", c_int),
|
||||
("container_tgid", c_int),
|
||||
("state", c_long),
|
||||
("task_type", c_int),
|
||||
("syscallno", c_ulong),
|
||||
("sys_task", c_ulong),
|
||||
("user_mode", c_ulong),
|
||||
("comm", c_char * TASK_COMM_LEN),
|
||||
]
|
||||
|
||||
|
||||
class PtRegs(Structure):
|
||||
_fields_ = [
|
||||
("r15", c_ulong),
|
||||
("r14", c_ulong),
|
||||
("r13", c_ulong),
|
||||
("r12", c_ulong),
|
||||
("rbp", c_ulong),
|
||||
("rbx", c_ulong),
|
||||
("r11", c_ulong),
|
||||
("r10", c_ulong),
|
||||
("r9", c_ulong),
|
||||
("r8", c_ulong),
|
||||
("rax", c_ulong),
|
||||
("rcx", c_ulong),
|
||||
("rdx", c_ulong),
|
||||
("rsi", c_ulong),
|
||||
("rdi", c_ulong),
|
||||
("orig_rax", c_ulong),
|
||||
("rip", c_ulong),
|
||||
("cs", c_ulong),
|
||||
("eflags", c_ulong),
|
||||
("rsp", c_ulong),
|
||||
("ss", c_ulong),
|
||||
]
|
||||
|
||||
|
||||
class user_stack_detail(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("regs", PtRegs), # Replace with actual type
|
||||
("ip", c_ulong),
|
||||
("bp", c_ulong),
|
||||
("sp", c_ulong),
|
||||
("stack", c_ulong * BACKTRACE_DEPTH),
|
||||
]
|
||||
|
||||
|
||||
class kern_stack_detail(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("stack", c_ulong * BACKTRACE_DEPTH),
|
||||
]
|
||||
|
||||
|
||||
class InnerArray(ctypes.Structure):
|
||||
_fields_ = [("chain", ctypes.c_char * PROCESS_ARGV_LEN)]
|
||||
|
||||
|
||||
temp_array = (
|
||||
InnerArray * PROCESS_CHAINS_COUNT
|
||||
) # Creates an array of 10 user_stack_detail objects
|
||||
|
||||
|
||||
class proc_chains_detail(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("full_argv", c_uint * PROCESS_CHAINS_COUNT),
|
||||
# ("chains", ctypes.c_char * PROCESS_ARGV_LEN * PROCESS_CHAINS_COUNT),
|
||||
("chains", (c_char * PROCESS_ARGV_LEN) * PROCESS_CHAINS_COUNT),
|
||||
# ("chains", temp_array),
|
||||
("tgid", c_uint * PROCESS_CHAINS_COUNT),
|
||||
]
|
||||
|
||||
|
||||
class variable_monitor_task(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("et_type", c_int),
|
||||
("id", c_ulong),
|
||||
("tv", c_ulonglong),
|
||||
("task", task_detail),
|
||||
("user_stack", user_stack_detail),
|
||||
("kern_stack", kern_stack_detail),
|
||||
("proc_chains", proc_chains_detail),
|
||||
]
|
||||
|
||||
|
||||
class ProcMapsParser:
|
||||
@@ -63,6 +180,32 @@ def addr_to_symbol(path, offset):
|
||||
return prev_sym
|
||||
|
||||
|
||||
# 使用示例:
|
||||
# p = ProcMapsParser(1234) # 请将 1234 替换成你想要查询的进程 ID
|
||||
# print(p.lookup(0x7FF6C4D2D000)) # 将这里的地址替换成你想要查询的地址
|
||||
def diag_printf_proc_chains(proc_chains: proc_chains_detail, detail=1):
|
||||
print(" 进程链信息:")
|
||||
for i in range(PROCESS_CHAINS_COUNT):
|
||||
a = proc_chains.chains[i][0]
|
||||
if proc_chains.chains[i][0] == b"\x00":
|
||||
break
|
||||
if proc_chains.full_argv[i] == 0 and detail:
|
||||
cmdline = get_pid_cmdline(proc_chains.tgid[i])
|
||||
if len(cmdline) > 0:
|
||||
print(f"#^ 0xffffffffffffff {cmdline} (UNKNOWN)")
|
||||
else:
|
||||
chains_bytes = bytes(proc_chains.chains[i])
|
||||
chains_str = chains_bytes.decode(errors="ignore")
|
||||
print(f"#^ 0xffffffffffffff {chains_str} (UNKNOWN)")
|
||||
else:
|
||||
chains_bytes = bytes(proc_chains.chains[i])
|
||||
chains_str = chains_bytes.decode(errors="ignore")
|
||||
print(f"#^ 0xffffffffffffff {chains_str} (UNKNOWN)")
|
||||
|
||||
|
||||
cmdlines = {}
|
||||
|
||||
|
||||
def get_pid_cmdline(pid):
|
||||
if pid not in cmdlines:
|
||||
with open(f"/proc/{pid}/cmdline", "r") as f:
|
||||
buf = f.read().replace("\x00", " ").strip()
|
||||
cmdlines[pid] = buf
|
||||
return cmdlines[pid]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import os
|
||||
import ctypes
|
||||
from ctypes import *
|
||||
import fcntl
|
||||
import pickle
|
||||
import bisect
|
||||
@@ -60,7 +59,7 @@ def do_dump(arg):
|
||||
|
||||
with open("len", "wb") as f:
|
||||
pickle.dump(len_temp, f)
|
||||
# do_extract(variant_buf, len_temp.value)
|
||||
do_extract(variant_buf, len_temp.value)
|
||||
|
||||
|
||||
def do_extract(buf, len):
|
||||
@@ -99,87 +98,6 @@ def extract_variant_buffer(buf, len, func, arg):
|
||||
os.chdir(dir)
|
||||
|
||||
|
||||
MAX_NAME_LEN = 15
|
||||
TIMER_MAX_WATCH_NUM = 32
|
||||
CGROUP_NAME_LEN = 32
|
||||
TASK_COMM_LEN = 16
|
||||
BACKTRACE_DEPTH = 30
|
||||
PROCESS_CHAINS_COUNT = 10
|
||||
PROCESS_ARGV_LEN = 128
|
||||
|
||||
|
||||
class threshold(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("task_id", c_int),
|
||||
("name", c_char * (MAX_NAME_LEN + 1)),
|
||||
("ptr", c_void_p),
|
||||
("threshold", c_longlong),
|
||||
]
|
||||
|
||||
|
||||
class variable_monitor_record(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("et_type", c_int),
|
||||
("id", c_ulong),
|
||||
("tv", c_ulonglong),
|
||||
("threshold_num", c_int),
|
||||
("threshold_record", threshold * TIMER_MAX_WATCH_NUM),
|
||||
]
|
||||
|
||||
|
||||
class task_detail(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("cgroup_buf", c_char * CGROUP_NAME_LEN),
|
||||
("cgroup_cpuset", c_char * CGROUP_NAME_LEN),
|
||||
("pid", c_int),
|
||||
("tgid", c_int),
|
||||
("container_pid", c_int),
|
||||
("container_tgid", c_int),
|
||||
("state", c_long),
|
||||
("task_type", c_int),
|
||||
("syscallno", c_ulong),
|
||||
("sys_task", c_ulong),
|
||||
("user_mode", c_ulong),
|
||||
("comm", c_char * TASK_COMM_LEN),
|
||||
]
|
||||
|
||||
|
||||
class kern_stack_detail(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("stack", c_ulong * BACKTRACE_DEPTH),
|
||||
]
|
||||
|
||||
|
||||
class user_stack_detail(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("regs", c_ulong), # Replace with actual type
|
||||
("ip", c_ulong),
|
||||
("bp", c_ulong),
|
||||
("sp", c_ulong),
|
||||
("stack", c_ulong * BACKTRACE_DEPTH),
|
||||
]
|
||||
|
||||
|
||||
class proc_chains_detail(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("full_argv", c_uint * PROCESS_CHAINS_COUNT),
|
||||
("chains", c_char * PROCESS_CHAINS_COUNT * PROCESS_ARGV_LEN),
|
||||
("tgid", c_uint * PROCESS_CHAINS_COUNT),
|
||||
]
|
||||
|
||||
|
||||
class variable_monitor_task(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("et_type", c_int),
|
||||
("id", c_ulong),
|
||||
("tv", c_ulonglong),
|
||||
("task", task_detail),
|
||||
("user_stack", user_stack_detail),
|
||||
("kern_stack", kern_stack_detail),
|
||||
("proc_chains", proc_chains_detail),
|
||||
]
|
||||
|
||||
|
||||
def parse_file(file_path):
|
||||
result = {}
|
||||
with open(file_path, "r") as file:
|
||||
@@ -247,14 +165,20 @@ def diag_printf_kern_stack(kern_stack: kern_stack_detail):
|
||||
def print_structure(structure, indent=0, struct_name=""):
|
||||
indent_spaces = " " * indent
|
||||
for field_name, field_type in structure._fields_:
|
||||
if field_name == "chains": # 跳过 'chains' 字段
|
||||
continue
|
||||
# if field_name == "chains":
|
||||
# print_structure(value, indent + 4, field_name)
|
||||
value = getattr(structure, field_name)
|
||||
if hasattr(value, "_fields_"): # 如果是嵌套的结构体
|
||||
print(f"{indent_spaces}{struct_name} {field_name}:")
|
||||
print_structure(value, indent + 4, field_name) # 递归打印,增加缩进
|
||||
elif isinstance(value, ctypes.Array): # 如果是数组
|
||||
print(f"{indent_spaces}{struct_name} {field_name}: {list(value)}")
|
||||
if field_name == "chains":
|
||||
for i, item in enumerate(value):
|
||||
chains_bytes = bytes(item)
|
||||
chains_str = chains_bytes.decode(errors="ignore")
|
||||
print(f"{indent_spaces}{struct_name} {field_name}: {chains_str}")
|
||||
else:
|
||||
print(f"{indent_spaces}{struct_name} {field_name}: {list(value)}")
|
||||
else:
|
||||
print(f"{indent_spaces}{struct_name} {field_name}: {value}")
|
||||
|
||||
@@ -319,7 +243,7 @@ def load_monitor_extract(buf, len, _):
|
||||
diag_printf_user_stack(tsk_info.task.pid, tsk_info.user_stack)
|
||||
diag_printf_kern_stack(tsk_info.kern_stack)
|
||||
print(f"#* 0xffffffffffffff {tsk_info.task.comm.decode()} (UNKNOWN)")
|
||||
# diag_printf_proc_chains(&tsk_info->proc_chains, 0, process_chains);
|
||||
diag_printf_proc_chains(tsk_info.proc_chains)
|
||||
|
||||
print("##")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user