How*_*owy 24 c java linux ubuntu java-native-interface
10月25日更新:
现在我发现了导致问题的原因.
1)子进程自杀,这就是strace/perf/auditctl无法跟踪它的原因.
2)从Java线程触发创建进程的JNI调用.当线程最终死亡时,它也会破坏它创建的进程.
3)在我的代码fork和execve()子进程中,我有代码来监视父进程死亡并使用以下行终止我的子进程:prctl(PR_SET_PDEATHSIG,SIGKILL); 我的错,我没有特别注意这个标志在b/c之前它被认为是我的其他项目的最佳实践,其中子进程从主线程分叉.
4)如果我注释掉这一行,问题就消失了.最初的目的是在父进程消失时终止子进程.即使没有这个标志,它仍然是正确的行为.好像是ubuntu框的默认行为.
5)最后发现它是一个内核bug,在内核版本3.4.0中修复,我在AWS上的ubuntu框是内核版本3.13.0-29-generic.
这些问题有几个有用的链接:
a)http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
b)在父线程退出时调用prctl(PR_SET_PDEATHSIG,SIGNAL),而不是父进程退出.
c)https://bugzilla.kernel.org/show_bug.cgi?id=43300
10月15日更新:
非常感谢所有的建议.我正在调查系统的一个区域到另一个区域.很难找到理由.
我想知道两件事.1)为什么像strace,auditctl和perf脚本这样强大的工具无法追踪导致杀戮的人?
2)被SIGKILL +++杀死的+++真的意味着它被信号杀死了吗?
原始邮政
我从Ubuntu 12中的Java应用程序服务器通过JNI接口启动了一个长时间运行的C进程.我使用JNI接口来启动进程而不是通过Java的进程构建器的原因是b/c的性能原因.对于java进程构建器来说,使用IPC非常低效,特别是b/c额外的缓冲引入了很长的延迟.
它会定期被SIGKILL神秘地终止.我发现的方式是通过strace,它说:"+++被SIGKILL +++杀死"
我检查了以下内容:
我被它终止的原因感到困惑.有没有人有一个很好的建议如何追踪它?
PS
在我的ubuntu限制 - 结果是:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7862
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7862
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Run Code Online (Sandbox Code Playgroud)
我试图增加限制,但仍然没有解决问题.
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) unlimited
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Run Code Online (Sandbox Code Playgroud)当我运行cat/proc/$$$/status时,这是proc状态
Name: mimi_coso
State: S (Sleeping)
Tgid: 2557
Ngid: 0
Pid: 2557
PPid: 2229
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 256
Groups: 0
VmPeak: 146840 kB
VmSize: 144252 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 36344 kB
VmRSS: 34792 kB
VmData: 45728 kB
VmStk: 136 kB
VmExe: 116 kB
VmLib: 23832 kB
VmPTE: 292 kB
VmSwap: 0 kB
Threads: 1
SigQ: 0/7862
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000004
SigIgn: 0000000000011001
SigCgt: 00000001c00064ee
CapInh: 0000000000000000
CapPrm: 0000001fffffffff
CapEff: 0000001fffffffff
CapBnd: 0000001fffffffff
Seccomp: 0
Cpus_allowed: 7fff
Cpus_allowed_list: 0-14
Mems_allowed: 00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 16978
nonvoluntary_ctxt_switches: 52120
Run Code Online (Sandbox Code Playgroud)strace显示:
$ strace -p 22254 -s 80 -o /tmp/debug.lighttpd.txt
read(0, "SGI\0\1\0\0\0\1\0c\0\0\0\t\0\0T\1\2248\0\0\0\0'\1\0\0(\0\0"..., 512) = 113
read(0, "SGI\0\1\0\0\0\1\0\262\1\0\0\10\0\1\243\1\224L\0\0\0\0/\377\373\222D\231\214"..., 512) = 448
sendto(3, "<15>Oct 10 18:34:01 MixCoder[271"..., 107, MSG_NOSIGNAL, NULL, 0) = 107
write(1, "SGO\0\0\0\0 \272\1\0\0\t\0\1\253\1\243\273\0\0\0\0'\1\0\0\0\0\0\1\242"..., 454) = 454
sendto(3, "<15>Oct 10 18:34:01 MixCoder[271"..., 107, MSG_NOSIGNAL, NULL, 0) = 107
write(1, "SGO\0\0\0\0 \341\0\0\0\10\0\0\322\1\254Z\0\0\0\0/\377\373R\4\0\17\21!"..., 237) = 237
read(0, "SGI\0\1\0\0\0\1\0)\3\0\0\t\0\3\32\1\224`\0\0\0\0'\1\0\0\310\0\0"..., 512) = 512
read(0, "\344u\233\16\257\341\315\254\272\300\351\302\324\263\212\351\225\365\1\241\225\3+\276J\273\37R\234R\362z"..., 512) = 311
read(0, "SGI\0\1\0\0\0\1\0\262\1\0\0\10\0\1\243\1\224f\0\0\0\0/\377\373\222d[\210"..., 512) = 448
sendto(3, "<15>Oct 10 18:34:01 MixCoder[271"..., 107, MSG_NOSIGNAL, NULL, 0) = 107
write(1, "SGO\0\0\0\0 %!\0\0\t\0\0+\1\243\335\0\0\0\0\27\0\0\0\0\1B\300\36"..., 8497) = 8497
sendto(3, "<15>Oct 10 18:34:01 MixCoder[271"..., 107, MSG_NOSIGNAL, NULL, 0) = 107
write(1, "SGO\0\0\0\0 \341\0\0\0\10\0\0\322\1\254t\0\0\0\0/\377\373R\4\0\17\301\31"..., 237) = 237
read(0, "SGI\0\1\0\0\0\1\0\262\1\0\0\10\0\1\243\1\224\200\0\0\0\0/\377\373\222d/\200"..., 512) = 448
sendto(3, "<15>Oct 10 18:34:01 MixCoder[271"..., 107, MSG_NOSIGNAL, NULL, 0) = 107
write(1, "SGO\0\0\0\0 \341\0\0\0\10\0\0\322\1\254\216\0\0\0\0/\377\373R\4\0\17\361+"..., 237) = 237
read(0, "SGI\0\1\0\0\0\1\0\221\0\0\0\t\0\0\202\1\224\210\0\0\0\0'\1\0\0P\0\0"..., 512) = 159
read(0, unfinished ...)
+++ killed by SIGKILL +++
Run Code Online (Sandbox Code Playgroud)小智 16
假设您在计算机上具有root访问权限,则可以在kill(2)系统调用上启用审计以收集此类信息.
root # auditctl -a exit,always -F arch=b64 -S kill -F a1=9
root # auditctl -l
LIST_RULES: exit,always arch=3221225534 (0xc000003e) a1=9 (0x9) syscall=kill
root # sleep 99999 &
[2] 11688
root # kill -9 11688
root # ausearch -sc kill
time->Tue Oct 14 00:38:44 2014
type=OBJ_PID msg=audit(1413272324.413:441376): opid=11688 oauid=52872 ouid=0 oses=20 ocomm="sleep"
type=SYSCALL msg=audit(1413272324.413:441376): arch=c000003e syscall=62 success=yes exit=0 a0=2da8 a1=9 a2=0 a3=0 items=0 ppid=6107 pid=6108 auid=52872 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsg
id=0 tty=pts2 ses=20 comm="bash" exe="/bin/bash" key=(null)
Run Code Online (Sandbox Code Playgroud)
另一种方法是设置内核跟踪,当审计系统可以执行相同的工作时,可能会过度终止.
终于我明白了原因。
子进程自行终止,这是一个 Linux 内核错误。
细节:
1)子进程自行终止,这就是 strace/perf/auditctl 无法追踪它的原因。
2)创建进程的JNI调用是由Java线程触发的。当线程最终终止时,它也会破坏它创建的进程。
3)在我的 fork 和 execve() 子进程的代码中,我有代码来监视父进程死亡并使用以下行杀死我的子进程: prctl( PR_SET_PDEATHSIG, SIGKILL ); 在 b/c 被认为是我的其他项目的最佳实践之前,我没有特别注意这个标志,其中子进程是从主线程分叉的。
4)如果我注释掉这一行,问题就消失了。最初的目的是当父进程消失时杀死子进程。即使没有这个标志,它仍然是正确的行为。似乎是 ubuntu 框的默认行为。
5)从这篇文章中,https://bugzilla.kernel.org/show_bug.cgi ?id=43300 。这是一个内核错误,已在内核版本 3.4.0 中修复,我来自 AWS 的 ubuntu 盒子是内核版本 3.13.0-29-generic。
我的机器配置: ===>Ubuntu 14.04 LTS ===>3.13.0-29-generic
一些有用的问题链接:
a) http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
b) prctl(PR_SET_PDEATHSIG, SIGNAL) 在父线程退出时调用,而不是在父进程退出时调用
c) https://bugzilla.kernel.org/show_bug.cgi?id=43300
| 归档时间: |
|
| 查看次数: |
9046 次 |
| 最近记录: |