linux下coredump问题的定位分析方法

news/2024/11/29 11:50:32/

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

参考:https://blog.csdn.net/m0_73698480/article/details/130077852

最近定位了一段时间linux下的崩溃问题,又收集了一些思路,特整理记录一下。

常见coredump定位方法是:
首先,关注coredump是否有生成,如果有生成,先使用gdb调试coredump,看看堆栈异常信息,然后再做其它分析。
其次,尝试是否可以重现问题,如果可重现的话,定位也就比较简单了,编译debug版本,-g -O0编译出的版本,使用gdb运行,然后跟踪调测就可以了。

下面重点探讨除上述分析之外的方法,和一些定位经验。

第一关注 运行日志:

1. 程序或服务自身的运行日志

在这个程序或服务本身的运行日志中,我们至少可以得到服务运行崩溃的大致时间;
另外许多时候,基于崩溃前的日志,或许也可以看到一些出现问题的原因,这个具体问题具体分析。

2. 系统日志

对于一个service系统服务来说,如果有打印日志的话,可能会存储在服务的日志中,也可能存储在系统日志中,系统日志的位置位于:
系统日志: 查看系统日志(如 /var/log/messages 或 /var/log/syslog),寻找与应用程序崩溃相关的任何错误或警告消息。

$ ls -l /var/log/messages*
-rw------- 1 root root  46784308 410 16:27 /var/log/messages
-rw------- 1 root root 157145170 317 03:19 /var/log/messages-20240317
-rw------- 1 root root 185431621 324 03:20 /var/log/messages-20240324
-rw------- 1 root root 266501216 331 03:10 /var/log/messages-20240331
-rw------- 1 root root 117807682 47 03:37 /var/log/messages-20240407

第二关注 运行限制和系统运行信息:

1. 文件打开限额

通常缺省的文件打开限额,对于有些服务是不够的
可以使用prlimit查询系统限额,还可以使用prlimt -p $(pid)来查询进程的文件等限额。
NOFILE行就是的文件打开限额。

$ prlimit
RESOURCE   DESCRIPTION                             SOFT      HARD UNITS
AS         address space limit                unlimited unlimited 字节
CORE       max core file size                         0 unlimited 块
CPU        CPU time                           unlimited unlimited 秒数
DATA       max data size                      unlimited unlimited 字节
FSIZE      max file size                      unlimited unlimited 块
LOCKS      max number of file locks held      unlimited unlimited 
MEMLOCK    max locked-in-memory address space     65536     65536 字节
MSGQUEUE   max bytes in POSIX mqueues            819200    819200 字节
NICE       max nice prio allowed to raise             0         0 
NOFILE     max number of open files                1024      4096 
NPROC      max number of processes                 4096    514744 
RSS        max resident set size              unlimited unlimited 页数
RTPRIO     max real-time priority                     0         0 
RTTIME     timeout for real-time tasks        unlimited unlimited 毫秒数
SIGPENDING max number of pending signals         514744    514744 
STACK      max stack size                       8388608 unlimited 字节
2. 系统当前内存和cpu情况

使用top命令可以查询,当前的内存运行情况

$ top
top - 16:30:37 up 52 days,  4:45,  2 users,  load average: 0.00, 0.00, 0.00
Tasks: 419 total,   3 running, 416 sleeping,   0 stopped,   0 zombie
%Cpu(s):  5.6 us, 11.1 sy,  0.0 ni, 83.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :    896.0 total,     59.7 free,    299.9 used,    536.5 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.    459.1 avail Mem PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                            1 root      20   0  172636   6532   3768 S   0.0   0.7   2:39.47 systemd                                                                            2 root      20   0       0      0      0 S   0.0   0.0   0:00.15 kthreadd                                                                           3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp                                                                             4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_par_gp                                                                         
...
3. 文件系统的占用情况

使用df -h查看磁盘的占用情况

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        434M     0  434M   0% /dev
tmpfs           448M     0  448M   0% /dev/shm
tmpfs           448M  1.2M  447M   1% /run
tmpfs           448M     0  448M   0% /sys/fs/cgroup
/dev/vda1        40G   23G   16G  59% /
tmpfs            90M     0   90M   0% /run/user/0
tmpfs            90M     0   90M   0% /run/user/1000

第三关注 系统历史运行信息:

可以借助sar命令(system activity reportor)来获取展示,磁盘的历史占用情况,cpu历史占用情况,内存历史占用情况。

1. 查看内存历史占用情况
$ sar -r
Linux 4.18.0-348.7.1.el8_5.x86_64 (ls_CxhK1nVN)         04/10/2024      _x86_64_        (1 CPU)
12:00:01 AM kbmemfree   kbavail kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
12:10:01 AM    112160    483716    805348     87.78     72932    407936    730276     79.59    340308    318996       236
12:20:00 AM    108692    483164    808816     88.15     73016    410768    728728     79.42    340768    322076       376
12:30:01 AM    111088    486360    806420     87.89     73100    411484    727280     79.27    341208    320176       540
12:40:01 AM    101508    484024    816000     88.94     73132    418696    729800     79.54    341844    328008       468
12:50:01 AM     99068    481988    818440     89.20     73180    419052    727280     79.27    342384    330640       184
01:00:01 AM     98516    481724    818992     89.26     73196    419324    727280     79.27    342720    330656       348
01:10:01 AM     98312    481836    819196     89.28     73224    419612    727280     79.27    342988    330716       404
01:20:01 AM     98380    482412    819128     89.28     73240    420096    727280     79.27    343276    330872       388
01:30:00 AM     96780    483460    820728     89.45     73252    422716    722736     78.77    343520    332380       364
01:40:01 AM    255968    484972    661540     72.10     13756    327676    728184     79.37    167148    352508       372
2. 查看cpu历史占用情况
$ sar -u
Linux 4.18.0-348.7.1.el8_5.x86_64 (ls_CxhK1nVN)         04/10/2024      _x86_64_        (1 CPU)
12:00:01 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
12:10:01 AM     all      0.39      0.08      0.48      0.12      0.00     98.94
12:20:00 AM     all      0.41      0.03      0.33      0.11      0.00     99.13
12:30:01 AM     all      0.35      0.03      0.48      0.11      0.00     99.04
12:40:01 AM     all      0.54      0.03      0.36      0.09      0.00     98.99
12:50:01 AM     all      0.15      0.03      0.20      0.07      0.00     99.56
01:00:01 AM     all      0.11      0.03      0.16      0.06      0.00     99.65
01:10:01 AM     all      0.13      0.02      0.19      0.06      0.00     99.60
3. 查看磁盘历史占用情况
$ sar -d
Linux 4.18.0-348.7.1.el8_5.x86_64 (ls_CxhK1nVN)         04/10/2024      _x86_64_        (1 CPU)
12:00:01 AM       DEV       tps     rkB/s     wkB/s   areq-sz    aqu-sz     await     svctm     %util
12:10:01 AM  dev253-0      6.77      8.25     42.26      7.46      0.00      0.73      0.26      0.18
12:10:01 AM   dev11-0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:10:01 AM    dev7-0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:10:01 AM    dev7-1      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:10:01 AM    dev7-2      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:20:00 AM  dev253-0      5.62      0.00     35.80      6.37      0.00      0.69      0.28      0.16
12:20:00 AM   dev11-0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:20:00 AM    dev7-0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:20:00 AM    dev7-1      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:20:00 AM    dev7-2      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
4. 指定时间的历史占用情况

因为sar命令通常显示当天的,如果要显示之前日期的,可以基于当前日期往前,显示历史日期的文件数据。
sar命令所查询的就是下面文件的内容信息。01-31代表日期1号到31号,写入时,每天的覆盖写入到对应的日期文件中。

$ ls /var/log/sa/
sa01  sa04  sa07  sa10  sa14  sa17  sa20  sa23  sa26  sa29  sar01  sar04  sar07  sar11  sar14  sar17  sar20  sar23  sar26  sar29
sa02  sa05  sa08  sa12  sa15  sa18  sa21  sa24  sa27  sa30  sar02  sar05  sar08  sar12  sar15  sar18  sar21  sar24  sar27  sar30
sa03  sa06  sa09  sa13  sa16  sa19  sa22  sa25  sa28  sa31  sar03  sar06  sar09  sar13  sar16  sar19  sar22  sar25  sar28  sar31

查看9号的内存信息时,使用如下命令查看

$ sar -f /var/log/sa/sa09 -r
Linux 4.18.0-348.7.1.el8_5.x86_64 (ls_CxhK1nVN)         04/09/2024      _x86_64_        (1 CPU)
12:00:01 AM kbmemfree   kbavail kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
12:10:01 AM     95244    485752    822264     89.62     72800    426856    727016     79.24    354880    321344       200
12:20:01 AM    129448    486524    788060     85.89     68596    398684    724724     78.99    301844    342100       324
12:30:01 AM    123244    484756    794264     86.57     68720    402044    727016     79.24    329980    317968       232
12:40:01 AM    124768    486904    792740     86.40     68860    402496    727016     79.24    330908    316884       188
12:50:01 AM    124160    486660    793348     86.47     68984    402736    727016     79.24    331208    317040       200
01:00:01 AM    123608    486504    793900     86.53     69108    403008    727016     79.24    331496    317140       248
01:10:01 AM    122840    486192    794668     86.61     69260    403312    727016     79.24    332020    317068       264
01:20:01 AM    122256    485944    795252     86.68     69360    403548    727016     79.24    332312    317172       176
01:30:01 AM    110380    486188    807128     87.97     69564    415448    727016     79.24    340608    321304       448
01:40:01 AM    107620    485568    809888     88.27     69716    417436    727016     79.24    342620    321092       396
01:50:00 AM    106616    485792    810892     88.38     69796    418644    724992     79.02    345120    320092       636
02:00:01 AM    105004    485200    812504     88.56     69872    419572    727016     79.24    345848    320212       760
02:10:01 AM    105820    486688    811688     88.47     69928    420188    727016     79.24    346588    320092       268

一些常见问题项:

1. 关注内存分配、释放异常

使用c、c++写程序,本就要特别关心内存申请释放。
一般来看,重复释放一般都是要崩溃的,这个也是常见的情况。
还有不太常见的情况,因为c++支持重载,new/delete方法被重载了,使用malloc申请的内存,使用delete释放时走了重载,重载的方式可能时使用一些内存分配库做的,那就有问题了。

2. 类或结构体定义有多处定义引发的异常

因为linux下,结构体、类都是缺省导出的,那么,就有可能不同的库都定义了某个结构体,两者的结构体就有符号重复了。
但两个库都是不知道的,两者都是独立编译的。
但运行程序由于依赖两个库,两个库都加载了,那运行时,找类或结构体,就可能找到另一个库的类或结构体了。
这种情况下,运行就很容易发生崩溃了。

3. 新旧库的匹配问题

在linux下,库之间如果版本不匹配的话,该类问题不太容易被发现。
例如运行程序依赖的某个库的版本是比较老的版本,但是头文件有变更,其它库均已变更了;
因为头文件变更,导致部分内存分配大小上会有差异,这种情况问题就千奇百怪了,很大可能崩溃在内存分配处理的位置。
遇到这种内存是足够的,并且没有内存释放异常,却崩溃了,那么可能就要担心一下是不是有库的版本有问题导致。

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)


http://www.ppmy.cn/news/1418487.html

相关文章

java实现TCP交互

服务器端 import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.PriorityQueue; import java.util.Scanner;public class TCP_Serv…

k8s:kubectl 命令设置简写启用自动补全功能

k8s:kubectl 命令设置简写&启用自动补全功能 1、设置kubectl命令简写2、启用kubectl自动补全功能 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes(K8s)是一个强大的容器编排平台&#xff0…

模型训练-保存训练数据

1.目的 找到一个可运行的代码,可以每个epoch打印训练数据,但是不会保存。因为在改进模型需要这些训练数据进行对比,所以需要将每个epoch的训练数据保存下来,写到一个文件中。 2.解决方案1 直接问ChatGPT,提示词如下…

Vector - CAPL - XCP介绍_02

前面我们介绍了关于使用vector XCP License后,通过CAPL对XCP协议进行连接、断开和获取当前XCP连接状态的函数,本篇文章不做过多的其他赘述,我们继续介绍CAPL控制XCP相关的其他函数。 目录 xcpActivate 代码示例 xcpDeactivate xcpActiva…

Linux第86步_了解“阻塞和非阻塞IO”以及相关处理函数

1、IO “应用程序”对“驱动设备“进行输入/输出操作,简称IO操作,它是Input和Output的缩写。 2、阻塞IO 阻塞IO是“应用程序”对“驱动设备”进行操作,若不能获取到设备资源,则阻塞IO应用程序的线程会被“挂起”,直到…

探索NDVI:了解植被指数的意义与应用

随着科技的进步和遥感技术的发展,我们能够更深入地了解地球上的植被覆盖情况,而其中一项重要的工具就是NDVI(Normalized Difference Vegetation Index,归一化植被指数)。NDVI不仅仅是一个数值,更是一扇窥探…

【Golang学习笔记】从零开始搭建一个Web框架(二)

文章目录 模块化路由前缀树路由 前情提示: 【Golang学习笔记】从零开始搭建一个Web框架(一)-CSDN博客 模块化路由 路由在kilon.go文件中导致路由和引擎交织在一起,如果要实现路由功能的拓展增强,那将会非常麻烦&…

文心一言VSchatGPT4

文心一言和GPT-4各有优势,具体表现在不同的测试场景下。 在某些测试场景中心一言的表现优于GPT-4,例如在故事的完整度和情节吸引力方面,文心一言表现得更加符合指令,情节更吸引人。这可能得益于其模型在训练时对中文语境的深入理…