这是我的结构。
main.go 与 C 信号处理程序(参考:用 cgo 处理信号,go 无法处理信号)
使用
go build
并在 docker 中运行(在 docker-compose.yml 中使用 -v /:/rootfs:ro)
实验:
结果:
Received signal: 15
Sent by PID: 0
Signal code: 0
User ID: 0
Received signal: 15
Sent by PID: 0
Signal code: 0
User ID: 0
Received signal: 15
Sent by PID: 15
Signal code: 0
User ID: 230030
Name: kworker/1:0H
State: S (sleeping)
Tgid: 15
Ngid: 0
Pid: 15
PPid: 2
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 64
Groups:
NStgid: 15
NSpid: 15
NSpgid: 0
NSsid: 0
Threads: 1
SigQ: 1/7980
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: ffffffffffffffff
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Speculation_Store_Bypass: vulnerable
Cpus_allowed: 2
Cpus_allowed_list: 1
Mems_allowed: 1
Mems_allowed_list: 0
voluntary_ctxt_switches: 5
nonvoluntary_ctxt_switches: 0
我想知道如果我想打印出信号发送者的pid和ppid该怎么办
在您展示的示例中,Go 代码包装了标准 C 和 Unix 信号处理。 sigaction(2) 是注册信号处理程序的 C 函数,该手册页描述了传递给信号处理程序的
siginfo_t
结构。 不过,该结构中的大多数字段都是可选的
、si_signo
和si_errno
是为所有信号定义的。si_code
更具体地说
使用 kill(2) 和 sigqueue(3) 发送的信号填写
和si_pid
。si_uid
这似乎涵盖了您的前两种情况,即您发现主容器进程的主机进程 ID 并调用 kill(1) 或者您让
docker kill
为您发送相同的信号。 但是,容器有自己的进程 ID 空间 - 请注意,在最后 docker exec kill
情况下,发送方 pid 为 15,这可能是主机上的系统守护进程 - 因此主机 kill
进程的进程 ID,或者Docker 守护进程的未定义。 这可能就是你在那里得到零的原因。