如何找出发生SEGV内存错误的程序

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

​问题
​18-Feb-2014 15:48:45] WARNING: [pool www] child 11274 exited on signal 11 (SIGSEGV) after 0.089068 seconds from start
显然11274进程运行过程中遇到了段错误导致进程异常退出了。继续追查发现是php的hsf扩展在启动初始化的时候遇到内存问题导致段错误。
沧老师这个段错误进程你怎么定位到是hsf扩展的问题?

分析过程
​发现段错误:
日志中的信息表明,进程号为11274的进程由于收到SIGSEGV信号而退出了。收到这个信号的时候,程序是可以生成core文件的。不过通过日志我们可以知道进程11274退出时没有生成core文件。因为在php-fpm的日志中,如果退出时生成了core文件,日志中会有“SIGSEGV - core dumped”字样。如:
​[20-Feb-2014 08:37:59] WARNING: [pool www] child 15845 exited on signal 11 (SIGSEGV - core dumped) after 1.051001 seconds from start
​生成core文件:
为啥没生成core文件?是因为我们的系统做了限制。执行如下命令可以查看限制情况:
ulimit

<img src="http://www.bo56.com/wp-content/uploads/2014/03/ulimit.jpg" alt="ulimit" width="424" height="300" class="alignnone size-full wp-image-338" /></a><br /> 可以看出,系统对于core文件大小默认限制是0.也就是说不能生成core文件。可以通过以下命令设置大小。
$ulimit -c unlimited
通过命令,我们就把系统对于core文件的大小限制去除了。
ulimit1
<img src="http://www.bo56.com/wp-content/uploads/2014/03/ulimit1.jpg" alt="ulimit1" width="400" height="215" class="alignnone size-full wp-image-339" /></a><br /> 设置完后,重启了php-fpm 进程。剩下的事情,就是坐等core文件生成了。
​第二天,查看php-fpm日志,发现了如下记录:
[20-Feb-2014 08:37:59] WARNING: [pool www] child 15845 exited on signal 11 (SIGSEGV - core dumped) after 1.051001 seconds from start
[20-Feb-2014 08:39:04] WARNING: [pool www] child 17803 exited on signal 11 (SIGSEGV - core dumped) after 0.927973 seconds from start
[20-Feb-2014 08:42:18] WARNING: [pool www] child 23491 exited on signal 11 (SIGSEGV - core dumped) after 0.798308 seconds from start
说明,core文件已经生成。
gdb分析core文件:
既然core文件生成了,现在该gdb上场了。通过如下命令查看程序退出时的栈信息。


$gdb -e /home/php/sbin/php-fpm -c core.15845
..............此处省略n多无关紧要的字
$info threads
  3 process 15850  0x0000003cf92d3f9a in epoll_ctl () from /lib64/libc.so.6
  2 process 15845  0x0000003cf92c4f65 in _xstat () from /lib64/libc.so.6
* 1 process 15851  0x00007fa94e230310 in ez_run (loop=0x2434c60, flags=0) at ez.c:2363
$thread 2
[Switching to thread 2 (process 15845)]#0  0x0000003cf92c4f65 in _xstat () from /lib64/libc.so.6
$bt
#0  0x0000003cf92c4f65 in _xstat () from /lib64/libc.so.6
#1  0x00007fa94df8fd8b in hsf::hsf_mkdir (path=0x7fa930001628 "/home/logs/hsfcpp") at /usr/include/sys/stat.h:436
#2  0x00007fa94df8feae in hsf::hsf_mkdirp (pathname=<value optimized out>) at utils/fileutils.cc:50
#3  0x00007fa94dfad7cc in hsf::hsf_stat_log_init (path=@0x7fa94e21f080, name=@0x7fffb607a620) at hsf/hsf_stat_file.cc:37
#4  0x00007fa94dfabb36 in hsf::hsf_stat_monitor::init (this=<value optimized out>) at hsf/hsf_stat_monitor.cc:231
#5  0x00007fa94dfa899a in hsf_core_bootstrap () at hsf/hsf.cc:104
#6  0x00007fa94dfa8cea in hsf::hsf_core::init () at hsf/hsf.cc:129
#7  0x00007fa94e448b52 in zm_activate_hsf (type=<value optimized out>, module_number=<value optimized out>) at /home/lingzhan/hsf_php_0.9/php_hsf.cpp:188
#8  0x000000000061d94c in ?? ()
#9  0x000000000226ee20 in ?? ()
#10 0x0000000000624c35 in ?? ()
#11 0x00000000024bc840 in ?? ()
#12 0x00000000024bc840 in ?? ()
#13 0x00000000024bc840 in ?? ()
#14 0x0000000000000000 in ?? ()

再继续分析其他的两个core文件,发现也都有这个栈信息。基本可以肯定是hsf的问题了。
另外,在/var/log/message 中也发现了如下记录:
Mar 13 14:40:07 s006132.cm6 kernel: : [5332900.567547] php-fpm[31017]: segfault at 30 ip 00007fdc74df3310 sp 00000000435b8040 error 4 in libeasy.so.0[7fdc74de3000+23000]
libeasy.so 正是hsf中调用的。进一步确认是执行hsf程序时出现问题的。
相关实践学习
日志服务之数据清洗与入湖
本教程介绍如何使用日志服务接入NGINX模拟数据,通过数据加工对数据进行清洗并归档至OSS中进行存储。
目录
相关文章
|
21天前
|
存储 Java C++
Java虚拟机(JVM)在执行Java程序时,会将其管理的内存划分为几个不同的区域
【6月更文挑战第24天】Java JVM管理内存分7区:程序计数器记录线程执行位置;虚拟机栈处理方法调用,每个线程有独立栈;本地方法栈服务native方法;Java堆存储所有对象实例,垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息;运行时常量池存储常量;直接内存不属于JVM规范,通过`java.nio`手动管理,不受GC直接影响。
27 5
|
21天前
|
算法 Java
垃圾回收机制(Garbage Collection,GC)是Java语言的一个重要特性,它自动管理程序运行过程中不再使用的内存空间。
【6月更文挑战第24天】Java的GC自动回收不再使用的内存,关注堆中的对象。通过标记-清除、复制、压缩和分代等算法识别无用对象。GC分为Minor、Major和Full类型,针对年轻代、老年代或整个堆进行回收。性能优化涉及算法选择和参数调整。
24 3
|
21天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
24 2
|
25天前
|
监控 算法 Java
Java虚拟机(JVM)使用多种垃圾回收算法来管理内存,以确保程序运行时不会因为内存不足而崩溃。
【6月更文挑战第20天】Java JVM运用多种GC算法,如标记-清除、复制、标记-压缩、分代收集、增量收集、并行收集和并发标记,以自动化内存管理,防止因内存耗尽导致的程序崩溃。这些算法各有优劣,适应不同的性能和资源需求。垃圾回收旨在避免手动内存管理,简化编程。当遇到内存泄漏,可以借助VisualVM、JConsole或MAT等工具监测内存、生成堆转储,分析引用链并定位泄漏源,从而解决问题。
30 4
|
26天前
|
编译器
程序的内存模型\栈区
程序的内存模型\栈区
25 4
|
26天前
|
C语言 C++
程序的内存模型\全局区
程序的内存模型\全局区
15 2
|
12天前
|
监控
LabVIEW程序内存泄漏分析与解决方案
LabVIEW程序内存泄漏分析与解决方案
18 0
|
18天前
|
Java UED 开发者
JVM逃逸分析原理解析:优化Java程序性能和内存利用效率
JVM逃逸分析原理解析:优化Java程序性能和内存利用效率
|
18天前
|
存储
程序与技术分享:C内存池的实现
程序与技术分享:C内存池的实现
|
21天前
|
程序员 C语言 C++
【C语言】:柔性数组和C/C++中程序内存区域划分
【C语言】:柔性数组和C/C++中程序内存区域划分
14 0