init cli_py

This commit is contained in:
zy
2023-11-20 22:27:37 -05:00
parent c9d7c8710a
commit 8081c2cc82
2 changed files with 158 additions and 91 deletions

View File

@@ -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]

View File

@@ -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("##")