[20260922]bpftrace能否探测点内调用外部命令2.txt
[20260922]bpftrace能否探测点内调用外部命令2.txt
--//deepseek给出的解答:
方法一:使用 system() 函数(推荐)
你可以在断点触发的探针动作中使用 system() 函数来执行 /bin/sleep 3。
sudo bpftrace -e '
kprobe:你的断点函数 {
printf("断点命中,开始休眠 3 秒...\n");
system("/bin/sleep 3"); // 阻塞 3 秒
printf("休眠结束\n");
}
' --unsafe
关键说明:
必须加 --unsafe 参数:出于安全考虑,bpftrace 默认禁止 system() 这类可能产生副作用的调用,所以需要显式启用。
system() 是阻塞的:它会同步等待命令执行完毕,在这 3 秒内,bpftrace 的事件处理线程会被阻塞,可能导致后续事件丢失或延迟处理。
并非真正"暂停内核":system("/bin/sleep 3") 只是让 bpftrace 用户态程序等待 3 秒,并不会让被追踪的内核函数或进程真正暂停。
如果你想在断点处真正暂停被追踪进程,应使用方法二。
方法二:使用 signal() 暂停被追踪进程
如果你的目标是让被追踪的进程在断点处真正暂停 3 秒(例如等待 GDB 附加),可以向目标进程发送 SIGSTOP 信号,然后由外部控制恢
复。
sudo bpftrace -e '
kprobe:你的断点函数 {
signal(19); // 发送 SIGSTOP,暂停目标进程
printf("进程 %d 已暂停,PID: %d\n", pid, pid);
// 注意:无法在 bpftrace 内部"定时"恢复,需外部手动 kill -CONT
}
' --unsafe
关键说明:
signal(19) 对应 SIGSTOP,会让目标进程真正进入暂停状态。
bpftrace 本身没有内置的定时恢复机制,你需要在另一个终端手动执行 kill -CONT <pid> 来恢复进程。
这种方法常用于调试场景:暂停进程 → 用 GDB 附加 → 调试完成后手动恢复。
--//按照介绍方法1调用外部命令,但是不会被追踪的内核函数或进程真正暂停。也许真正有用的方法2.通过例子说明问题。
--//实际上就是命令行加入--unsafe才能调用外部命令。
1.环境:
SCOTT@book01p> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
2.建立测试脚本:
$ cat shmdt.bt
//tracepoint:syscalls:sys_enter_shmdt
tracepoint:syscalls:sys_exit_shmdt
/ pid == $1 || $1 == 0 /
{
system("ipcs -m;sleep 2");
}
--//连接数据库,记录下spid,执行如下命令后,出现Attached 1 probe后,执行quit退出。
# ipcs -m ;bpftrace --unsafe shmdt.bt 3357
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 56
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
Attached 1 probe
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
--//注意看ipcs -m的nattch列,调用4次shmdt全部4次都是55.说明当执行quit时,在探测点处快速执行完成,而带有外部命令在quit才开
--//始执行。
3.采用第2种方式:
$ cat shmdt1.bt
//tracepoint:syscalls:sys_enter_shmdt
tracepoint:syscalls:sys_exit_shmdt
/ pid == $1 || $1 == 0 /
{
signal(19);
system("ipcs -m;sleep 2");
printf("进程 %d 已暂停,PID: %d\n", pid, pid);
}
--//连接数据库,记录下spid,执行如下命令后,出现Attached 1 probe后,执行quit退出。
# ipcs -m ;bpftrace --unsafe shmdt1.bt 3523
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 56
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
Attached 1 probe
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
进程 3523 已暂停,PID: 3523
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0xafa94c20 3 oracle 600 2097152 56
进程 3523 已暂停,PID: 3523
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 56
进程 3523 已暂停,PID: 3523
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
进程 3523 已暂停,PID: 3523
^C
--//注意看nattch列的变化。
--//另外打开会话,执行如下 18对应SIGCONT,可以使用kill -l查询确定:
$ kill -18 3523
$ kill -18 3523
$ kill -18 3523
$ kill -18 3523
$ kill -18 3523
-bash: kill: (3523) - No such process
4.顺便贴一个使用gdb的测试例子:
$ grep -v "^#" test2.gdb
set pagination off
set logging overwrite on
set logging on
break shmdt
commands
silent
shell sleep 3; ipcs -m
printf "break shmdt %016x\n",$rdi
c
end
$ gdb -f -p 3784 -x test2.gdb
...
Breakpoint 1 at 0x7f53dad11d20: file ../sysdeps/unix/sysv/linux/shmdt.c, line 28.
(gdb) c
Continuing.
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 56
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
break shmdt 0000000061000000
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
break shmdt 00000000a5000000
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 56
break shmdt 0000000060000000
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 56
break shmdt 00000000a6000000
[Inferior 1 (process 3784) exited normally]
--//deepseek给出的解答:
方法一:使用 system() 函数(推荐)
你可以在断点触发的探针动作中使用 system() 函数来执行 /bin/sleep 3。
sudo bpftrace -e '
kprobe:你的断点函数 {
printf("断点命中,开始休眠 3 秒...\n");
system("/bin/sleep 3"); // 阻塞 3 秒
printf("休眠结束\n");
}
' --unsafe
关键说明:
必须加 --unsafe 参数:出于安全考虑,bpftrace 默认禁止 system() 这类可能产生副作用的调用,所以需要显式启用。
system() 是阻塞的:它会同步等待命令执行完毕,在这 3 秒内,bpftrace 的事件处理线程会被阻塞,可能导致后续事件丢失或延迟处理。
并非真正"暂停内核":system("/bin/sleep 3") 只是让 bpftrace 用户态程序等待 3 秒,并不会让被追踪的内核函数或进程真正暂停。
如果你想在断点处真正暂停被追踪进程,应使用方法二。
方法二:使用 signal() 暂停被追踪进程
如果你的目标是让被追踪的进程在断点处真正暂停 3 秒(例如等待 GDB 附加),可以向目标进程发送 SIGSTOP 信号,然后由外部控制恢
复。
sudo bpftrace -e '
kprobe:你的断点函数 {
signal(19); // 发送 SIGSTOP,暂停目标进程
printf("进程 %d 已暂停,PID: %d\n", pid, pid);
// 注意:无法在 bpftrace 内部"定时"恢复,需外部手动 kill -CONT
}
' --unsafe
关键说明:
signal(19) 对应 SIGSTOP,会让目标进程真正进入暂停状态。
bpftrace 本身没有内置的定时恢复机制,你需要在另一个终端手动执行 kill -CONT <pid> 来恢复进程。
这种方法常用于调试场景:暂停进程 → 用 GDB 附加 → 调试完成后手动恢复。
--//按照介绍方法1调用外部命令,但是不会被追踪的内核函数或进程真正暂停。也许真正有用的方法2.通过例子说明问题。
--//实际上就是命令行加入--unsafe才能调用外部命令。
1.环境:
SCOTT@book01p> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
2.建立测试脚本:
$ cat shmdt.bt
//tracepoint:syscalls:sys_enter_shmdt
tracepoint:syscalls:sys_exit_shmdt
/ pid == $1 || $1 == 0 /
{
system("ipcs -m;sleep 2");
}
--//连接数据库,记录下spid,执行如下命令后,出现Attached 1 probe后,执行quit退出。
# ipcs -m ;bpftrace --unsafe shmdt.bt 3357
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 56
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
Attached 1 probe
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
--//注意看ipcs -m的nattch列,调用4次shmdt全部4次都是55.说明当执行quit时,在探测点处快速执行完成,而带有外部命令在quit才开
--//始执行。
3.采用第2种方式:
$ cat shmdt1.bt
//tracepoint:syscalls:sys_enter_shmdt
tracepoint:syscalls:sys_exit_shmdt
/ pid == $1 || $1 == 0 /
{
signal(19);
system("ipcs -m;sleep 2");
printf("进程 %d 已暂停,PID: %d\n", pid, pid);
}
--//连接数据库,记录下spid,执行如下命令后,出现Attached 1 probe后,执行quit退出。
# ipcs -m ;bpftrace --unsafe shmdt1.bt 3523
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 56
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
Attached 1 probe
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
进程 3523 已暂停,PID: 3523
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0xafa94c20 3 oracle 600 2097152 56
进程 3523 已暂停,PID: 3523
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 56
进程 3523 已暂停,PID: 3523
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
进程 3523 已暂停,PID: 3523
^C
--//注意看nattch列的变化。
--//另外打开会话,执行如下 18对应SIGCONT,可以使用kill -l查询确定:
$ kill -18 3523
$ kill -18 3523
$ kill -18 3523
$ kill -18 3523
$ kill -18 3523
-bash: kill: (3523) - No such process
4.顺便贴一个使用gdb的测试例子:
$ grep -v "^#" test2.gdb
set pagination off
set logging overwrite on
set logging on
break shmdt
commands
silent
shell sleep 3; ipcs -m
printf "break shmdt %016x\n",$rdi
c
end
$ gdb -f -p 3784 -x test2.gdb
...
Breakpoint 1 at 0x7f53dad11d20: file ../sysdeps/unix/sysv/linux/shmdt.c, line 28.
(gdb) c
Continuing.
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 56
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
break shmdt 0000000061000000
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
break shmdt 00000000a5000000
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 56
break shmdt 0000000060000000
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 55
0x00000000 1 oracle 600 1140850688 55
0x00000000 2 oracle 600 8388608 55
0xafa94c20 3 oracle 600 2097152 56
break shmdt 00000000a6000000
[Inferior 1 (process 3784) exited normally]
浙公网安备 33010602011771号