没有core的程序异常退出追查过程

        最近朋友项目发生了一件怪事,好好的进程,没有任何痕迹地退出,没有core文件,没有syslog痕迹,也不是进程主动退出,因为逻辑中exit都有日志。

现在记录一下追查过程:

1.先排除core生成条件不足的可能性

1)查看ulimit -c,

2)查看/proc/sys/kernel/core_pattern,

3)查看/etc/sysctl.conf中的

kernel.core_pattern = /var/core/core_%e_%p_%t
kernel.core_uses_pid = 0

这些设置都正常

2.排除程序自身exit

排查代码发现所有exit的地方都有日志,而现在进程退出没有任何exit相关的日志

3.查看syslog

在进程退出时间先后查看syslog没有发现任何异常

4.排除主动调用kill

查看机器的history,并没有发现有人调用过kill

        从上面的结果看,应该是进程主动退出,但是并非是程序中的exit,那么大概率只有一种可能是进程收到了某种信号,然后导致进程退出。其实kill本身也是信号。那么怎么追踪呢?祭出大杀器:gdb,进程退出,最后应该会进入exit接口处理收尾工作。那就gdb在exit函数这里打断点,同时因为不可能直接在终端开着gdb,如果终端断开的话就会终止gdb监控,而本身这个异常退出就是不定时的,所以必须是后台模式启动gdb。

最关键的操作如下:

1.生成一个gdb脚本文件:monitor

b exit
c
bt
q

2.nohup gdb -p server --command=monitor &

这样后台起一个任务,监控server程序退出时的exit的调用,在程序退出的时候会生成一个result文件nohup.out

两天后sevrer有挂掉了,查看gdb结果文件看到:

Thread 2 "GameRunner" received signal SIGPIPE, Broken pipe.
[Switching to Thread 0x7efc25351700 (LWP 2086776)]
__libc_write (nbytes=223, buf=0x7efc200012a0, fd=14)
    at ../sysdeps/unix/sysv/linux/write.c:26
26      ../sysdeps/unix/sysv/linux/write.c: No such file or directory.
#0  __libc_write (nbytes=223, buf=0x7efc200012a0, fd=14)
    at ../sysdeps/unix/sysv/linux/write.c:26
#1  __libc_write (fd=14, buf=0x7efc200012a0, nbytes=223)
    at ../sysdeps/unix/sysv/linux/write.c:24
#2  0x00007efc26aa55c5 in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.1
#3  0x00007efc26aa072a in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.1
#4  0x00007efc26a9f784 in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.1
#5  0x00007efc26a9fc43 in BIO_write ()
   from /lib/x86_64-linux-gnu/libcrypto.so.1.1
#6  0x00007efc26a9df01 in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.1
#7  0x00007efc26aa0116 in BIO_ctrl ()
   from /lib/x86_64-linux-gnu/libcrypto.so.1.1
#8  0x00007efc26d22f3d in ?? () from /lib/x86_64-linux-gnu/libssl.so.1.1
#9  0x00007efc26d31e8f in ?? () from /lib/x86_64-linux-gnu/libssl.so.1.1
#10 0x00007efc26d224a3 in ?? () from /lib/x86_64-linux-gnu/libssl.so.1.1
#11 0x0000562740764db0 in init_sslwebsocket_server_connection (
    con=0x7efc200066a0) at yknet_sslwebsocket_pipe.cpp:76
#12 0x0000562740763d03 in yknet_ssl_pipe_handshake (pe=pe@entry=0x7efc20021540)
    at yknet_pipe_base.cpp:1167
#13 0x0000562740763e2b in yknet_ssl_pipe_conn_sock_readcb (fd=14,
    event=<optimized out>, arg=0x7efc20021540) at yknet_pipe_base.cpp:1209
#14 0x0000562740775fd4 in event_process_active_single_queue (
    base=base@entry=0x56274325c200, activeq=0x56274325c650,
    max_to_process=max_to_process@entry=2147483647, endtime=endtime@entry=0x0)
    at event.c:1691
#15 0x0000562740776bcf in event_process_active (base=0x56274325c200)
    at event.c:1783
#16 event_base_loop (base=0x56274325c200, flags=flags@entry=1) at event.c:2006
#17 0x0000562740763b7e in yknet_pipe_base_process_send_data (
    base=b

原来是  Thread 2 "GameRunner" received signal SIGPIPE, Broken pipe,进程收到了信号SIGPIPE,该信号默认结束进程,而server代码中并没有忽略这个信号。问题最后找到了答案,就是对常见的应该屏蔽的信号没有处理,导致进程结束。最后从之前的老的代码库中抄了一段:

// ignore signals
 signal(SIGINT, SIG_IGN);
 signal(SIGHUP, SIG_IGN);
 signal(SIGQUIT, SIG_IGN);
 signal(SIGPIPE, SIG_IGN);
 signal(SIGTTOU, SIG_IGN);
 signal(SIGTTIN, SIG_IGN);
 signal(SIGTERM, SIG_IGN);

  问题解决!      

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值