系统活动一抓留存!深入 Linux C/C++ 调试工具之 sysdig

一、前言------sysdig 工具简介

1.1 什么是 sysdig

sysdig 是开源的 Linux 系统可见性与取证工具 ,通过内核探针捕获 系统调用(syscall)及 OS 事件 ,支持 实时观察 、强大过滤 、离线分析 ,并可用 Chisel(Lua 脚本) 做聚合统计。

一句话定位:

sysdig 是系统活动的 「抓包器 + 分析器」 ------ 像 Wireshark 抓网络包一样,把 syscall 流抓进 .scap,随时回放、过滤、统计。

1.2 与 strace / perf / Falco 的对比

工具 定位 输出 典型场景
strace 跟踪单个进程 syscall 终端文本 开发调试、快速看某程序行为
sysdig 捕获整机/容器事件流 实时流 / .scap 文件 取证、容器排查、离线分析
perf CPU/性能采样 热点、计数器 性能瓶颈
ltrace 库函数调用 libc API API 层行为
Falco 安全规则引擎(基于同类事件) 告警 运行时威胁检测

关系:

复制代码
内核 syscall 事件
    ├─ strace  →  attach 单进程,即时打印
    ├─ sysdig  →  全机捕获 + 过滤 + 存盘 + Chisel 分析
    └─ Falco   →  对同类事件跑安全规则("谁读了 /etc/shadow")

1.3 核心能力

能力 说明
实时流 sysdig proc.name=nginx 像 tail -f 看事件
捕获文件 sysdig -w trace.scap 离线回放
过滤语言 proc.name、evt.type、fd.name、container.id 等
Chisel 内置 Lua 脚本:topprocs_cpu、netstat、spy_users
容器原生 无需改容器即可按 container.name 过滤
eBPF 模式 --modern-bpf 免传统内核模块(视版本)

二、使用场景------何时使用 sysdig

1、问题已过去,需要「事后复盘」

典型现象: 凌晨告警,早上进程已重启,日志不全。

复制代码
# 若之前有捕获
sysdig -r incident.scap "proc.name=myapp and evt.type=open"

sysdig 价值: .scap 保留 完整事件流 + 上下文,比 strace 临时跟踪更适合取证。

2、容器 / K8s 环境排查

典型现象: 某 Pod 偷偷访问敏感文件、异常出站连接。

复制代码
sysdig container.name=payment-svc and evt.type=connect
sysdig -c netstat container.name=payment-svc

3、整机谁在读某个文件 / 谁占 CPU

复制代码
sysdig -c topfiles_bytes
sysdig -c topprocs_cpu
sysdig "fd.name contains /etc/shadow"

4、对比 strace:单进程 vs 全系统

需求 工具
只关心 ./myapp 启动过程 strace ./myapp 更简单
谁(任意进程)在动 /etc/passwd sysdig
抓一段窗口留证据 sysdig -w
统计 top 进程/文件/连接 sysdig -c chisel

5、C/C++ 开发调试

复制代码
# 跟踪自己的程序
sudo sysdig proc.name=my_server and evt.type=open

# 只看文件与网络
sudo sysdig proc.name=my_server and (evt.type=open or evt.type=connect)

# 捕获后慢慢分析
sudo sysdig -w my_server.scap -z proc.name=my_server
./my_server   # 另一终端跑业务
# Ctrl+C 停止捕获
sudo sysdig -r my_server.scap

6、不适合 sysdig 的场景

场景 更合适的工具
单进程快速跟踪 strace
库函数层(printf/malloc) ltrace
源码级断点 gdb
CPU 火焰图 perf
内存越界 ASan
长期 7×24 安全运营 Falco / SIEM

三、核心原理------工作原理深度解析

3.1 架构:内核捕获 → 用户态丰富 → 过滤/Chisel

复制代码
┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│ Linux 内核   │────►│ sysdig 探针   │────►│ 用户态引擎   │
│ syscall/事件 │     │ (kmod/eBPF)  │     │ 解析+上下文  │
└─────────────┘     └──────────────┘     └──────┬──────┘
                                                 │
                    ┌────────────────────────────┼────────────────┐
                    ▼                            ▼                ▼
              实时打印                     写入 .scap          Chisel 聚合
              sysdig filter               sysdig -r           sysdig -c

与 strace 差异:

strace sysdig
附着方式 ptrace 单进程 内核级捕获(可见多进程)
开销模型 被跟踪进程变慢 全机事件流,需过滤
持久化 需自己重定向 原生 .scap
容器 需进容器 exec container.* 字段直接过滤

3.2 探针:内核模块 vs eBPF

模式 说明
传统 加载 sysdig 内核模块(需匹配内核头)
--modern-bpf 使用 eBPF,免编译 kmod(新发行版推荐)
复制代码
sudo sysdig --modern-bpf -V

3.3 事件默认输出格式

复制代码
%evt.num %evt.time %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info

示例:

复制代码
12345 12:34:56.789101234 2 sysdig_demo (12340) > open /tmp/sysdig_demo_test.txt
字段 含义
evt.num 事件序号
evt.time 时间戳
evt.cpu CPU 编号
proc.name 进程名
evt.dir > 进入 syscall,< 返回
evt.type 事件类型(open、read、connect...)
evt.info 参数/返回值等详情

3.4 过滤表达式

过滤器写在命令末尾,支持 and / or / not:

复制代码
sysdig proc.name=nginx and evt.type=write
sysdig fd.type=ipv4 and evt.type=connect
sysdig proc.pid=1234
sysdig container.id=abc123

常用字段:

字段 含义
proc.name 进程名
proc.pid PID
proc.cmdline 完整命令行
evt.type 事件类型
evt.dir 方向 > / <
fd.name 文件路径 / socket
fd.type file、ipv4、pipe...
container.name 容器名
k8s.pod.name K8s Pod(需元数据)

3.5 Chisel(Lua 脚本)

Chisel 对事件流做 聚合、排序、格式化,类似「可编程报表」:

复制代码
sysdig -cl              # 列出所有 chisel
sysdig -i topprocs_cpu  # 查看说明
sysdig -c topprocs_cpu  # 运行

3.6 与 Falco 的关系

  • sysdig:捕获 + 分析(开发/运维/取证)

  • Falco :基于同类内核事件的 安全规则引擎(「若某进程打开 /etc/shadow 则告警」)

二者同源技术栈(CNCF),可理解为 sysdig 负责看清楚,Falco 负责判定可疑。

四、命令参数------常用选项详解

4.1 基本用法

复制代码
sysdig [选项] [过滤器]
csysdig                    # 交互式 TUI(更易用)

4.2 常用选项

选项 说明
-r file 从 .scap 回放
-w file 写入捕获文件
-z 与 -w 联用,压缩 scap
-s len 打印字符串最大长度(默认 256)
-n num 只处理前 num 个事件
-A 打印事件数据缓冲(如 read/write 内容)
-p fmt 自定义输出格式
-c chisel 运行 Chisel
-cl 列出 Chisel
-i chisel Chisel 详情
-l 列出可用 -p 字段
-d filter 将过滤器设为 display filter(仅显示)
-t 不带日期,仅时间
-a 绝对时间戳
-S 简单输出(时间+内容)
--modern-bpf 使用 eBPF 探针
-V 版本与驱动信息

4.3 捕获与回放

复制代码
# 捕获 60 秒全机事件
sudo timeout 60 sysdig -w full.scap -z

# 只捕获某进程
sudo sysdig -w app.scap -z proc.name=myapp

# 回放并过滤
sudo sysdig -r app.scap evt.type=open
sudo sysdig -r app.scap -c topfiles_bytes

4.4 自定义输出格式

复制代码
sysdig -p "%proc.name %evt.type %fd.name" proc.name=nginx
sysdig -p "%evt.time %proc.name %evt.dir %evt.type %evt.args" evt.type=open

4.5 帮助选项中文对照

复制代码
-r, --readfile=FILE          从捕获文件读取事件
-w, --writefile=FILE         将事件写入捕获文件
-z, --compress               压缩捕获文件
-s, --snaplen=LEN            事件打印缓冲上限
-n, --numevents=NUM          处理事件数量上限
-A, --printevtdata           打印 read/write 等数据缓冲
-p, --print=FORMAT           自定义输出格式
-c, --chisel=CHISEL          运行指定 chisel
-cl, --list-chisels          列出 chisel
-i, --chisel-info=CHISEL     显示 chisel 帮助
-l, --list                   列出可用字段
-d, --displayflt=FILTER      设置 display filter
-t, --timetype=TYPE          时间格式
-S, --simpleoutputs          简化输出
--modern-bpf                 使用 eBPF 驱动
-V, --version                版本信息
-h, --help                   帮助

五、使用实战------实际案例分析

示例程序 sysdig_demo

复制代码
/*
 * sysdig_demo.c - 演示 sysdig 可捕获的系统调用与事件
 *
 * 编译:
 *   gcc -g -O0 sysdig_demo.c -o sysdig_demo
 *
 * 跟踪(需 root):
 *   sudo sysdig proc.name=sysdig_demo
 *   sudo sysdig -w demo.scap proc.name=sysdig_demo &
 *   ./sysdig_demo
 *   sudo killall sysdig
 *   sudo sysdig -r demo.scap
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

#define DEMO_FILE "/tmp/sysdig_demo_test.txt"

static void demo_file_io(void)
{
	int fd;
	char buf[128];
	ssize_t n;

	printf("[1] open / read / write / close\n");

	fd = open(DEMO_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (fd < 0) {
		perror("open");
		return;
	}

	if (write(fd, "hello sysdig demo\n", 18) < 0)
		perror("write");

	if (lseek(fd, 0, SEEK_SET) < 0)
		perror("lseek");

	n = read(fd, buf, sizeof(buf) - 1);
	if (n < 0) {
		perror("read");
	} else {
		buf[n] = '\0';
		printf("    read back: %s", buf);
	}

	if (close(fd) < 0)
		perror("close");
}

static void demo_malloc_mmap(void)
{
	char *p1, *p2;

	printf("[2] malloc / free (可能触发 brk 或 mmap)\n");

	p1 = malloc(64);
	p2 = malloc(1024 * 1024);
	if (!p1 || !p2) {
		perror("malloc");
		free(p1);
		free(p2);
		return;
	}

	strcpy(p1, "sysdig malloc demo");
	memset(p2, 0x5a, 1024 * 1024);
	printf("    p1 = %s\n", p1);

	free(p1);
	free(p2);
}

static void demo_fork(void)
{
	pid_t pid;
	int status;

	printf("[3] fork / wait\n");

	pid = fork();
	if (pid < 0) {
		perror("fork");
		return;
	}

	if (pid == 0) {
		int fd = open("/tmp/sysdig_demo_child.txt",
			      O_WRONLY | O_CREAT | O_TRUNC, 0644);
		if (fd >= 0) {
			write(fd, "from child\n", 11);
			close(fd);
		}
		_exit(9);
	}

	if (waitpid(pid, &status, 0) < 0) {
		perror("waitpid");
		return;
	}

	if (WIFEXITED(status))
		printf("    child exit = %d\n", WEXITSTATUS(status));
}

static void demo_stat(void)
{
	printf("[4] access / stat\n");

	if (access(DEMO_FILE, F_OK) == 0)
		printf("    %s exists\n", DEMO_FILE);
	else
		printf("    %s missing: %s\n", DEMO_FILE, strerror(errno));
}

int main(void)
{
	printf("=== sysdig demo start (pid=%d) ===\n", getpid());

	demo_file_io();
	demo_malloc_mmap();
	demo_stat();
	demo_fork();

	printf("=== sysdig demo end ===\n");
	return 0;
}

cd examples/sysdig_demo
make && make check

案例 1:实时过滤单进程

复制代码
# 终端 1
sudo sysdig proc.name=sysdig_demo

# 终端 2
./sysdig_demo

典型输出:

复制代码
1 10:00:01.123 0 sysdig_demo (4567) > open /tmp/sysdig_demo_test.txt
2 10:00:01.124 0 sysdig_demo (4567) < open fd=3
3 10:00:01.125 0 sysdig_demo (4567) > write fd=3 size=18
...

案例 2:捕获 + 离线回放(核心用法)

复制代码
make sysdig-capture
# 或手动:
sudo sysdig -w demo.scap -z proc.name=sysdig_demo &
./sysdig_demo
sudo killall sysdig

sudo sysdig -r demo.scap
sudo sysdig -r demo.scap evt.type=open

价值: 可多次回放、换不同过滤器,无需复现问题。

案例 3:Chisel 统计文件访问

复制代码
make sysdig-chisel
# 等价:
sudo sysdig -r demo.scap -c topfiles_bytes proc.name=sysdig_demo

典型输出:

复制代码
Bytes   Name
18      /tmp/sysdig_demo_test.txt
11      /tmp/sysdig_demo_child.txt

案例 4:查谁在读敏感文件(安全排查)

复制代码
sudo sysdig "fd.name contains /etc/shadow"
sudo sysdig -c spy_users fd.name contains /etc/passwd

案例 5:网络连接监控

复制代码
sudo sysdig fd.type=ipv4 and evt.type=connect
sudo sysdig -c netstat proc.name=my_server
sudo sysdig -c topconns

案例 6:容器内进程

复制代码
# 列出容器相关字段
sysdig -l | grep container

sudo sysdig container.name=web and evt.type=open
sudo sysdig -c topprocs_cpu container.name=web

案例 7:与 strace 对照

操作 strace sysdig
跟踪 ./app strace ./app sysdig proc.name=app(需另开终端启动 app)
存盘 strace -o log sysdig -w app.scap
统计 strace -c sysdig -c topprocs_time
看 write 内容 strace -s 200 -e write sysdig -A evt.type=write and proc.name=app

案例 8:自定义输出 + 组合过滤

复制代码
sudo sysdig -p "%evt.time %proc.name %evt.type %fd.name %evt.args" \
  "proc.name=sysdig_demo and (evt.type=open or evt.type=read or evt.type=write)"

六、常见问题------疑难解答

问题 原因 解决
sysdig: command not found 未安装 见下方安装
需要 root 捕获 syscall 需特权 sudo sysdig 或 CAP_SYS_ADMIN
内核模块编译失败 无 kernel headers apt install linux-headers-$(uname -r)
事件太多看不清 未加过滤器 proc.name=...、evt.type=...
.scap 很大 捕获全机太久 缩短时间、加过滤、用 -z
容器字段为空 无 container 运行时元数据 确认 Docker/k8s 环境、驱动版本
与 strace 选哪个 场景不同 单进程即时 → strace;取证/全机 → sysdig
--modern-bpf 失败 内核/权限不支持 回退传统 kmod 或升级 sysdig

6.1 安装

复制代码
# Debian / Ubuntu(官方仓库或 sysdig 文档)
curl -s https://download.sysdig.com/stable/install-sysdig | sudo bash
sudo apt install sysdig

# 或
sudo apt install sysdig

# 验证
sudo sysdig -V

6.2 权限说明

复制代码
# 通常需要 root
sudo sysdig -V

# 非 root 可尝试(视系统配置)
sysdig --modern-bpf ...

6.3 常用 Chisel 速查

Chisel 用途
topprocs_cpu CPU 占用最高进程
topprocs_mem 内存占用最高进程
topfiles_bytes 读写最多的文件
topconns 网络连接最多
netstat 类 netstat 视图
spy_users 某用户的活动
spy_ip 与某 IP 的通信
stderr 标准错误输出
fdcount_by_proc 各进程 fd 数量

七、总结------要点回顾

7.1 三句话

  1. sysdig 在内核层捕获 syscall/OS 事件,比 strace 视野更广,支持容器与全机分析。

  2. -w存 .scap、 -r回放 是取证核心;过滤器 + Chisel 让海量事件可分析。

  3. C/C++ 调试:单进程快速看行为用 strace;要留证、查全机、容器里谁干了什么用 sysdig。

7.2 推荐工作流

复制代码
怀疑某服务异常
  → sudo sysdig -w incident.scap -z container.name=svc &
  → 复现问题
  → sudo sysdig -r incident.scap "evt.type=open"
  → sudo sysdig -r incident.scap -c topfiles_bytes

7.3 最小命令清单

复制代码
sudo sysdig -V                              # 检查安装
sudo sysdig proc.name=app                   # 实时过滤
sudo sysdig -w trace.scap -z proc.name=app  # 捕获
sudo sysdig -r trace.scap                   # 回放
sudo sysdig -r trace.scap evt.type=connect  # 回放+过滤
sudo sysdig -c topprocs_cpu                 # Chisel 统计
sudo sysdig -cl                             # 列出 chisel
csysdig                                     # 交互 TUI

7.4 调试工具链位置

工具 回答的问题
strace 这个进程 正在 调哪些 syscall?
ltrace 这个进程调了哪些 库函数?
sysdig 整机/容器 发生了什么?能否 存盘回放?
perf CPU 时间花在哪?
ASan 内存合法吗?
Falco 行为是否 违反安全规则?
gdb 运行时断点与变量
相关推荐
g3voip1 小时前
工业防水电话到底怎么选?隧道、管廊与码头的需求差异
服务器·网络·信息与通信·ip
qetfw1 小时前
Bash 变量:export、位置参数与默认值展开验证
linux·开发语言·chrome·bash
智能运维指南2 小时前
企业 IT 运维自动化平台怎么选?从场景匹配到 POC 验证的完整评估框架
运维·自动化·自动化运维·嘉为蓝鲸
其实防守也摸鱼2 小时前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全
.Bryce.2 小时前
从强化学习到Agentic RL:让Agent在“干活“中自己变聪明
服务器·网络·agent·rag·agentic rl
ZYH_06012 小时前
rhcsa课程复习题
服务器·bash
用户565190394492 小时前
高危 编号99999漏洞情报(26年8-10月) 多个严重漏洞:PHP执行远程控制代码 / Linux虚拟机-宿主越界(CVE-2026-99999...
服务器
toooooop82 小时前
CentOS 7 内核 3.10.0-1160.119.1 升级指南
linux·运维·centos
云飞云共享云桌面2 小时前
广东东莞制造工厂10人共享一台三维设计服务器
运维·服务器·3d·自动化·制造