Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ tests/stress/signal-race
!tests/stress/*.c
build/lkl-src
src/web-assets.c
trace.pftrace
trace-graph/
*.pftrace
5 changes: 5 additions & 0 deletions include/kbox/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ struct kbox_image_args {
int web_port; /* --web=PORT (default 8080) */
const char *web_bind; /* --web-bind ADDR */
const char *trace_format; /* --trace-format=json */
const char *ftrace_tracer; /* --ftrace=TRACER */
const char *ftrace_filter; /* --ftrace-filter=SYM */
const char *ftrace_dump; /* --ftrace-dump=PATH */
const char *ftrace_events; /* --ftrace-events=cat/ev,... */
const char *ftrace_outdir; /* --ftrace-outdir=DIR */
bool sqpoll; /* --sqpoll: busy-poll service thread */
const char *const *extra_args; /* remaining args after -- */
int extra_argc; /* count of extra_args */
Expand Down
10 changes: 10 additions & 0 deletions include/kbox/ftrace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: MIT */
#ifndef KBOX_FTRACE_H
#define KBOX_FTRACE_H
struct kbox_sysnrs;
struct kbox_image_args;
int kbox_ftrace_enable(const struct kbox_sysnrs *s,
const struct kbox_image_args *args);
void kbox_ftrace_dump(const struct kbox_sysnrs *s,
const struct kbox_image_args *args);
#endif /* KBOX_FTRACE_H */
1 change: 1 addition & 0 deletions mk/features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ SRCS = $(SRC_DIR)/main.c \
$(SRC_DIR)/mount.c \
$(SRC_DIR)/probe.c \
$(SRC_DIR)/image.c \
$(SRC_DIR)/ftrace.c \
$(SRC_DIR)/seccomp-bpf.c \
$(SRC_DIR)/seccomp-notify.c \
$(SRC_DIR)/shadow-fd.c \
Expand Down
27 changes: 27 additions & 0 deletions scripts/drgn/kbox_tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# scripts/drgn/kbox_tasks.py
# 走訪 LKL task list,印 PID / COMM / STATE,用於與 lx-ps / kbox-task-walk 交叉驗證。
from drgn.helpers.linux.pid import for_each_task

STATE_NAMES = {
0x0000: "RUNNING",
0x0001: "INTERRUPTIBLE",
0x0002: "UNINTERRUPTIBLE",
0x0004: "STOPPED",
0x0008: "TRACED",
0x0402: "IDLE", # TASK_UNINTERRUPTIBLE | TASK_NOLOAD
}

def state_name(task):
try:
s = task.member_("__state").value_()
except Exception:
return "?"
return STATE_NAMES.get(s, hex(s))

print(f"{'PID':>5} {'COMM':<18} STATE")
print("-" * 42)
count = 0
for task in for_each_task(prog):
print(f"{task.pid.value_():>5} {task.comm.string_().decode():<18} {state_name(task)}")
count += 1
print(f"\n共 {count} 個 task")
87 changes: 87 additions & 0 deletions scripts/gdb/kbox-events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# scripts/gdb/kbox-events.py
# 事件式條件斷點:用 Python 的 stop() 取代 GDB 原生條件,
# 支援原生條件做不到的判斷(字串比對、走訪 task 結構)。
# 載入方式:GDB 內 source scripts/gdb/kbox-events.py

import gdb


def _safe_eval(expr):
"""求值失敗(prologue 中、符號不可見)時回 None,不丟例外。"""
try:
return gdb.parse_and_eval(expr)
except gdb.error:
return None


class KboxBreakOnPid(gdb.Breakpoint):
"""在 FUNC 停,但只有當 TASK_EXPR->pid == 目標 PID 時才真的中斷。"""
def __init__(self, func, pid, task_expr):
super().__init__(func)
self.target_pid = int(pid)
self.task_expr = task_expr # 例如 __schedule 內的 "prev"

def stop(self):
task = _safe_eval(self.task_expr)
if task is None:
return False # 引數尚不可見(prologue)就放行
try:
return int(task["pid"]) == self.target_pid
except (gdb.error, gdb.MemoryError):
return False


class KboxBreakPidCmd(gdb.Command):
"""kbox-break-pid PID FUNC TASK_EXPR
例:kbox-break-pid 42 __schedule prev"""
def __init__(self):
super().__init__("kbox-break-pid", gdb.COMMAND_USER)

def invoke(self, arg, from_tty):
parts = arg.split()
if len(parts) != 3:
print("用法:kbox-break-pid PID FUNC TASK_EXPR")
return
pid, func, task_expr = parts
bp = KboxBreakOnPid(func, pid, task_expr)
print(f"Breakpoint {bp.number}: 停在 {func},當 {task_expr}->pid == {pid}")


class KboxBreakOnOpen(gdb.Breakpoint):
"""在 do_sys_openat2 停,但只有開啟路徑含指定子字串時才中斷。"""
def __init__(self, needle):
super().__init__("do_sys_openat2")
self.needle = needle

def stop(self):
fn = _safe_eval("filename")
if fn is None:
return False
try:
path = fn.string()
except (gdb.error, gdb.MemoryError):
return False
if self.needle in path:
print(f"[kbox-events] openat 命中: {path}")
return True
return False


class KboxBreakOpenCmd(gdb.Command):
"""kbox-break-openat SUBSTR
例:kbox-break-openat /etc/hostname"""
def __init__(self):
super().__init__("kbox-break-openat", gdb.COMMAND_USER)

def invoke(self, arg, from_tty):
needle = arg.strip()
if not needle:
print("用法:kbox-break-openat SUBSTR(路徑子字串)")
return
bp = KboxBreakOnOpen(needle)
print(f"Breakpoint {bp.number}: 停在 do_sys_openat2,當開啟路徑含 '{needle}'")


KboxBreakPidCmd()
KboxBreakOpenCmd()
print("kbox-events.py 已載入:kbox-break-pid、kbox-break-openat")
33 changes: 33 additions & 0 deletions src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ enum {
OPT_WEB_BIND,
OPT_SYSCALL_MODE,
OPT_TRACE_FORMAT,
OPT_FTRACE,
OPT_FTRACE_FILTER,
OPT_FTRACE_DUMP,
OPT_FTRACE_EVENTS,
OPT_FTRACE_OUTDIR,
OPT_SQPOLL,
OPT_HELP,
};
Expand All @@ -46,6 +51,11 @@ static const struct option longopts[] = {
{"syscall-mode", required_argument, NULL, OPT_SYSCALL_MODE},
{"sqpoll", no_argument, NULL, OPT_SQPOLL},
{"trace-format", required_argument, NULL, OPT_TRACE_FORMAT},
{"ftrace", required_argument, NULL, OPT_FTRACE},
{"ftrace-filter", required_argument, NULL, OPT_FTRACE_FILTER},
{"ftrace-dump", required_argument, NULL, OPT_FTRACE_DUMP},
{"ftrace-events", required_argument, NULL, OPT_FTRACE_EVENTS},
{"ftrace-outdir", required_argument, NULL, OPT_FTRACE_OUTDIR},
{"help", no_argument, NULL, OPT_HELP},
{NULL, 0, NULL, 0},
};
Expand Down Expand Up @@ -85,6 +95,14 @@ void kbox_usage(const char *argv0)
" --web-bind ADDR Bind address for web (default: "
"127.0.0.1)\n"
" --trace-format FMT Trace output format (json)\n"
" --ftrace=TRACER Enable LKL ftrace "
"(function/function_graph)\n"
" --ftrace-filter=SYM Restrict ftrace to symbol SYM\n"
" --ftrace-dump=PATH Dump LKL trace to host file PATH\n"
" --ftrace-events=LIST Enable tracepoints cat/ev,... (event "
"mode)\n"
" --ftrace-outdir=DIR Event-mode output dir (ftrace.log + "
"start_ts)\n"
" -h, --help Show this help\n",
argv0);
}
Expand Down Expand Up @@ -260,6 +278,21 @@ int kbox_parse_args(int argc, char *argv[], struct kbox_image_args *img)
}
break;
case 'h':
case OPT_FTRACE:
img->ftrace_tracer = optarg;
break;
case OPT_FTRACE_FILTER:
img->ftrace_filter = optarg;
break;
case OPT_FTRACE_DUMP:
img->ftrace_dump = optarg;
break;
case OPT_FTRACE_EVENTS:
img->ftrace_events = optarg;
break;
case OPT_FTRACE_OUTDIR:
img->ftrace_outdir = optarg;
break;
case OPT_HELP:
kbox_usage(argv[0]);
return -1;
Expand Down
Loading