首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分享一种定位linux 下程序闪退的思路

分享一种定位linux 下程序闪退的思路

原创
作者头像
qsjs
修改2020-06-11 10:15:13
3K0
修改2020-06-11 10:15:13
举报

这两天把自己的linux 系统升级了,但是遇到了一个比较大的坑,在此分享下解决方法(主要是定位程序闪退的其中一种思路),希望对阅读此文的你有所帮助,也欢迎留言更好的解决方法. 废话不多少,进入正题.

问题发生的过程:

升级系统的过程中,发生了中断,然后重新尝试升级,提示大量的软件包有multi-version(400+) 导致conflicting的存在,然后就有点MB了,关机肯定是不能的,万一reboot之后系统网络不能正常起来,岂不是更麻烦. 所以首先要解决 无法升级的问题, 解决此问题的大致过程如下:

A.

首先把系统中的软件列表导出(包含package name, arch, version)到文件,然后对结果进行分析,查看有哪些重名,并且cpu架构相同,但是版本不同的软件包。

导出上述信息的命令如下:

rpm -qa --qf "%{name}\t%{arch}\t%{version}\n"  >/tmp/installed_pkg.txt

对结果进行分析的命令如下(相信你一定有更简单的方法,以下命令仅供参考):

cat /tmp/installed_pkg.txt |sed 's/\t/-/' | awk '{if(a[$1]++)print $1}'

B.

找到上述符合条件的软件包之后,强制移除高版本的软件包. 用rpm -ev --nodeps <PKGNAME>, 因为整个升级过程因为中断而破坏,所以 卸载包的时候,可能会提示依赖,而用--nodeps 就是强制卸载对应的包.

C.

完成上述包的卸载之后,重新进行update. 成功完成了升级. 至此,看似解决了这个问题。 然后对系统做一个基本的check, reboot 系统进行验证.

D.

成功进入系统,也没有什么明显的错误,但是当要运行一个比较大的java程序的时候,这个应用程序居然一闪而过,什么错误也没有提示. 对于这种情况一般都是查找对应的程序log,然后看看到底什么原因导致程序闪退.

遗憾的是:鄙人对此软件根本不了解,仅仅停留在用户层,根本都不清楚到底日志都分布在哪里,更不用说应该重点看哪些日志了。所以最好的办法是:找vendor 进行解决。

作为一个运维人员,难道就没有好的办法来简单排查下吗?

在经过一番卸载重装以及依赖检查等一系列的操作之后,依然很困惑,没有弄好,也没有找到解决办法。

翻看以前笔记,看到了strace, 既然程序异常退出,那么肯定发生了异常,所以可以考虑用strace看看结果,说不定有所发现呢?

可问题是,程序因为退出比较快,运行程序后,没有时间来得及用strace命令就退出了,看起来是没有办法去trace systemcall.

strace 可以跟踪命令执行时候的系统调用,尝试用 strace -f "COMMAND" 的方式,可是发现 该程序不能在root 身份下运行,而不是root 身份的情况下,该命令又报如下的错误,这个错误在直接运行的时候并不存在,看来用 strace -f "COMMAND" 的方式并不好用.

write(2, "strace: exec: Exec format error\n", 32strace: exec: Exec format error
) = 32
exit_group(1)                           = ?
+++ exited with 1 +++

既然 strace -f "COMMAND" 并不好用,那么依然考虑 strace -p PID的方式,手动获取PID 是没有办法了,毕竟程序是 闪退. 既然手动不可以,思索了好久,那么就用脚本来自动获取PID吧,基本的解决思路如下:

1.

创建一个监控进程pid的脚本(示例如下),然后运行该脚本,假定该session 为1. 该简单脚本会在monitor到PID之后,退出循环并用strace -f -p 进行trace跟踪.

#!/bin/bash
get_pid=""
while [ 1 -gt 0 ];do   #如下的PROCESS_KEYSTRING 需要替换你程序的启动命令中的关键字.
	get_pid=`ps -ef | grep PROCESS_KEYSTRING | grep -Evi grep | awk '{print $2}'`
	if [ -n "$get_pid" ];then 
		break
	fi
done
echo $get_pid
strace -f -p $get_pid

2.

新开一个session 2, 运行出现问题的程序,如果是图形程序,那么直接运行就可以 3.

返回session 1, 查看输出的结果, 在这里确实发现了如下的异常.

 {": ", 2}, {"error while loading shared libra"..., 36}, {": ", 2}, {"libavahi-glib.so.1", 18}, {": ", 2}, {"cannot open shared object file", 30}, {": ", 2}, {"No such file or directory", 25}, {"\n", 1}], 10) = 138
[pid  3310] exit_group(127)             = ?
[pid  3310] +++ exited with 127 +++
<... rt_sigtimedwait resumed> )         = -1 EAGAIN (Resource temporarily unavailable)
open("/proc/3310", O_RDONLY)            = -1 ENOENT (No such file or directory)
exit_group(0)                           = ?
+++ exited with 0 +++

至此,闪退的原因看起来是缺少了库文件libavahi-glib.so.1, 然后找到这个库文件对应的软件包,安装软件包,然后再次验证, 问题成功修复.

如果你有更好的方法,欢迎留言评论!

本文原创,转载请著名出处.

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题发生的过程:
  • 如果你有更好的方法,欢迎留言评论!
  • 本文原创,转载请著名出处.
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档