AIX+下的+core+dump+分析
- 格式:doc
- 大小:198.50 KB
- 文档页数:23
AIX内存使用情况(windows 尽量少的用内存aix尽量多的用内存)svmon -Gsize inuse free pin virtualmemory 4046848 3758845 288003 935436 1816226pg space 2097152 4651work pers clntpin 935174 0 262in use 1815740 0 1943105用vmstat 1 11111查看内存瓶颈。
ps aux 显示内存使用svmon -G 查看内存泄露谢提供vmstat -v。
从上面显示看来,我想应该是这样:1、numperm、numclient都是perm或client相对lruable的比值。
内存只有部分是lruable的。
2、当只用jfs或者jfs2用量不大时,client基本上是小于perm,因为jfs cache类型算perm不算client,这部分往往在非计算内存中是最大的。
client只是nfs、cdrfs所用,这部分不算file page,也不算noncomputational,因为没有本地硬盘数据对应,但这部分内存可以被steal,被steal时也不需要占用paging space,因为也只是cache而已,noncomputational从文档用语的理解看来,我的理解是只包含本机硬盘有对应数据的内容,对于远程有的(NFS、CDRFS)的。
而一般来说,NFS和CDRFS的访问量远远比不上本地JFS的访问量,其cache占用也就很少。
3、如果JFS2用量很大,client可能超过noncomp比较多,因为JFS2 CACHE算client不算perm,而noncomp一般来说就是perm。
其实我觉得造成疑惑的应当是IBM对noncomp在实践中的定义不清,到底是内存只有comp与noncomp组成,还是不是?按理说应当是所有的noncomp+comp=lruable,但如果发生numclient>numperm,而系统性能检查命令把perm当作noncomp,这就有偷换概念的嫌疑:某些cache性质的不算noncomp,而显然这些也不能算comp。
Ldd 可以查看程序调用了哪些库文件。
当进程在异常终止运行时,系统会把该进程对应的地址空间中的数据写到core文件中(这个过程被称为dump),以便程序员对其进行分析,找出进程异常终止的原因。
缺省情况下,异常终止的进程在启动它的当前目录下产生core文件。
在AIX 4.3.3中,所有的core文件的文件名都是core,如果不只一个程序产生dump或者相同的程序dump多次,它们都会产生相同文件名的core文件,那么就会丢失比较早的core 文件。
从AIX 5.1开始,改变了core文件的命名方法,使得每一个core文件拥有惟一的文件名,从而避免了新的core文件覆盖旧的core文件,这个特色更加有助于程序员调试和跟踪运行失败的程序。
默认情况下,一个core文件的文件名是core。
要使用AIX 5L中core文件命名的新方法,就要把CORE_NAMING环境变量的值设置为yes。
在AIX 5L中,把当前用户的CORE_NAMING环境变量的值设置成yes之后,随后启动的进程产生的core文件名才能惟一的。
新的core文件名的格式是core.pid.ddhhmmss。
其中pid是进程号,dd是当前月份中的日子,hh表示小时,mm表示分,ss表示秒。
对于一个占用内存资源很大的进程产生的core文件也非常大,因此如果经常有进程产生core文件,而core文件名都不相同,那么产生的core就会占用非常多的文件系统空间,所以系统管理员要定期为程序员收集这些core文件,并删除这些文件。
在AIX 5.3中,用户可以设置产生压缩的core文件和指定一个目录来保存core文件,用lscore命令查看当前用户或指定用户的core设置,例如:$ lscore compression: off path specification: off corefile location: not set naming specification: off $要查看peter用户的core设置,命令是lscore peter。
使用DBX分析AIX 下的CoreDumpPS:Where can you get dbx?It is part of bos.adt.debug# lslpp -w /usr/bin/dbxFile Fileset Type-------------------------------------------/usr/bin/dbx bos.adt.debug Symlink以下转自/?6141/viewspace-18882I core dump 分析入门AIX专家俱乐部E ?!CR8Z#S)[环境变量设置`#X`4\]9h|8]0;Uy%D]6sQ.i9O0 可以通过/etc/security/limits 文件对各用户的基本配置参数包括core 大小进行限制。
或者通过ulimit 更改当前环境下的core 大小限制。
AIX专家俱乐部vF?I9u:B1@]!HCc\!v_J-r)r3U0 默认情况下应用进程生成core dump 时都使用文件名core。
为了避免同一工作目录下的进程core 相互覆盖可以定义环境变量CORE_NAMING=true然后启动进程这样将生成名为core.pid.ddhhmmss 的文件。
可以使用file core 命令查看core 是哪个进程产生的。
:EvFu#O@$n*s)g0AIX专家俱乐部0U(p#k2_:J/} G"v$D.E默认情况下应用进程dump 时会包含所有的共享内存如果dump 时想排除共享内存内容可以在启动进程之前设置环境变量CORE_NOSHM=true.R1I rjg09kkS%v!@6o0 系统有一个参数fullcore 用于控制是否在程序coredump 时生成完整的core。
为避免信息丢失建议打开fullcore。
可以使用lsattr –El sys0 查询是否将fullcore 打开使用chdev -l sys0 -a fullcore=true 将fullcore 状态更改为打开。
应用程序运行时产生coredump故障处理环境:操作系统:AIX Common 数据库:无关应用程序:32-bit症状:客户应用结息程序在运行过程中产生coredump。
程序故障与处理数据量有关,当把结息网点分成两批,可以顺利完成。
解决方法:应用程序的问题本来不属于我们维保的范畴,因为客户关系比较好,开发商太极公司也是我们的友军,抱着试试看的态度来解决。
用svmon跟踪程序的执行,发现其在运行期间,work process private部分的内存增长速度非常快,并且很明显地,接近65536页的时候即发生core dump。
这表明程序故障与内存的过度使用有关,达到256MB阀值时溢出。
work process private与用户程序的堆、栈有关,其中堆常为malloc系统调用分配的内存空间。
这里与ulimit设置无关(已经设置为unlimited),与AIX 32位程序的内存分配行为有关。
32位程序最多可以使用16个内存段,其中segment 2~C用户可用作堆栈和共享内存,默认仅使用segment 2存放程序堆栈数据,最大值为256MB,所以默认情况下用户程序最多只能分配256MB的堆内存。
而这个默认行为,可以通过在执行程序前,设置LDR_CNTRL环境变量来调节堆栈部分和共享内存的比例,例如:LDR_CNTRL=MAXDATA=0x30000000,设置了堆栈内存空间最多可使用3个内存段,共768MB 内存。
下面是一个测试的例子:# include <stdio.h>main (){int i;unsigned char *p;i=0;while ( i < 20 ){printf ( "i=%d\n", i );/* 32M */p=(unsigned char *)malloc(33554432);memset(p,'\0',33554432);i=i+1;sleep(1);}sleep(120);}直接运行该程序,在i=7之后产生coredump,采用下面的方式执行命令:# LDR_CNTRL=MAXDATA=0x3000000 ./testmalloc程序能够正常执行结束运行,同时运行的svmon显示程序已经使用到了256MB以上的堆空间。
AIX中测试端口的方法下面以80端口为例,介绍测试某一个端口是否工作的方法:1. 编辑/etc/services文件,找到如下两行http 80/tcp # World Wide Web HTTPhttp 80/udp # World Wide Web HTTP用#将这两行注释掉,并添加新的两行,即如下:#http 80/tcp # World Wide Web HTTP#http 80/udp # World Wide Web HTTPtelnet2 80/tcptelnet2 80/udp2. 编辑/etc/inetd.conf文件,找到如下一行telnet stream tcp6 nowait root /usr/sbin/telnetd telnetd -a在其下添加一行telnet2 stream tcp6 nowait root /usr/sbin/telnetd telnetd -a3. # refresh -s inetd4. # lssrc -ls inetd在输出中确认有一行telnet2 /usr/sbin/telnetd telnetd -a active5. # netstat -an该命令的输出中能看到80端口在侦听,即tcp 0 0 *.80 *.* LISTEN6. 尝试从别的AIX机器上用如下命令登陆这个服务器,如果能正常登陆,说明80端口工作正常。
# telnet <ip_address> 807. # netstat -an | grep 80可以看到通过80端口建立了连接,类似如下输出:tcp4 0 0 9.181.50.90.80 9.181.50.107.3750 ESTABLISHED8. 测试完成。
请注意,测试完成后,请将/etc/services和/etc/inetd.conf文件修改回之前的状态,并刷新inetd服务:# refresh -s inetd拨号访问RS/6000的快速配置方法AIX/RS6000 支持多种拨号访问的方法.如PPP/SLIP等,但其配置较为复杂.现介绍一种使用WIN95的超级终端Hyper Terminal访问RS/6000的方法RS/6000 端:1. 定义tty, 并设置enable login , flow control=rts2. 编辑/etc/uucp/Devices, 加入一行:Direct tty# - 9600 direct3. 连接Modem到tty# port4. #pdisable tty#5. #cu -ml tty#6. at<---/7. ats0=18. ~.<----/9. penable tty#WIN95/98 端:拨号方问RS/6000关于/etc/security/limits的中文解释前一阵子,跟公司的数据库工程师为新机器P560Q和P55A安装系统和数据库,AIX为5304,oracle9207,在oracle建库是总是在jvm处失败,并报了一堆错,经查与/etc/security/limits限制有关,下面是这个文件的解释:time(seconds) unlimited此用户的一个进程能占用的CPU处理时间file(blocks) unlimited此用户的进程可以生成和扩展的最大文件大小data(kbytes) 131072此用户的进程可分配使用的最大数据段大小(数据段可以有多个)stack(kbytes) 32768此用户的进程可使用的最大堆栈段大小memory(kbytes) 32768一个用户进程可以使用的最大物理内存数量(系统并不强制限制)coredump(blocks) 2097151可生成的最大coredump文件大小nofiles(descriptors) 2000一个用户进程可同时打开的文件描述符数量(基本等同于可打开文件数量)将这几个值都改成了-1,安装成功!Oracle的网络参数的设置/usr/sbin/no –p -o udp_sendspace=65536/usr/sbin/no –p -o udp_recvspace=655360/usr/sbin/no –p -o tcp_sendspace=65536/usr/sbin/no –p -o tcp_recvspace=65536word格式-可编辑-感谢下载支持/usr/sbin/no –p -o rfc1323=1卷组问题问题:由于操作失误(chdev -l hdiskx -a pv=yes) 使得hdiskx 的PVID发生改变,硬盘上的内容尽管没被破坏,但由于与VGDA区的描述不一致,造成卷组无法访问, 该怎么办?可用recreatevg命令来重新创建一内容相同的卷组, 以达到修复的目的。
UNIX一、如何修改系统对用户使用资源的默认限制?用户使用系统资源都有一定的限制,在/etc/security/limits文件中限制着用户使用系统资源的多少,系统管理员(root用户)通过修改这个文件的内容可以限制某个用户对系统资源的使用,例如修改某个用户的fsize属性的值来限制用户进程最大可以产生多大的文件。
在/etc/security/limits文件中可以为每个用户所能使用的资源做出明确的限定。
该文件以形式为每个用户记录限制资源的属性。
右表所列的就是这些限制属性的含义。
这些限制属性分为软限制和硬限制,通常软限制的值应该小于或等于硬限制的值,也就是说硬限制的值是上限。
这些限制属性的值都是十进制的整数,是32位的整数,因此这些整数的最大值就是2147483647,除了cpu、nofiles、cpu_hard和nofiles_hard之外,其他属性值的单位都是512字节块。
如果为用户设置了硬限制的值而没有设置软限制的值,则二者相同。
如果某个值为-1,则表示没有限制。
二、如何确定逻辑设备的物理位置?IBM的pSeries服务器使用物理位置编码(Physical Location Codes)和AIX位置编码来确定失败的现场可替换部件(Field Replaceable Unit,简称FRU)。
物理位置编码作用是映射逻辑设备在实际物理结构中具体位置。
物理位置编码是分层的、分级的,能够标示出特定适配器卡在机架、扩展笼、底板(Backplane)以及卡槽的详细位置。
物理位置编码的格式是一个由字母、数字和符号构成的字符串,其中符号有减号(-)、斜线(/)、井号(#)和句点号(.)。
例如物理位置编码P3-Z1-A2.1标示一个SCSI设备,它位于底板3上的SCSI总线1上,SCSI地址是SCSI ID 2、LUN 1。
物理位置编码U1.5-P1-I2标示某个适配器位于第一个机架的5号扩展笼,第一个底板的2 号I/O 插槽中。
gdb调试coredump原理GDB调试coredump原理引言:在开发过程中,我们经常会遇到程序崩溃的情况。
为了定位程序崩溃的原因,我们需要进行调试。
而在调试过程中,有一种特殊的情况,叫做coredump。
当一个程序发生严重错误或崩溃时,操作系统会生成一个core文件,记录程序崩溃时的内存状态。
通过调试这个core文件,我们可以更加方便地找到程序的问题所在。
本文将以gdb调试coredump为主题,详细介绍其原理和使用方法。
一、什么是coredump?Coredump指的是当一个程序因为错误而异常终止时,操作系统将程序的内存状态保存到一个特殊的文件中,即core文件。
这个core文件包含了程序崩溃时的内存状态、寄存器的状态以及函数、变量的信息。
对于GDB 来说,这个core文件就是一个可调试的文件,我们可以使用GDB来调试这个文件,进一步定位程序错误的原因。
二、生成coredump文件的配置生成coredump文件的配置主要涉及到操作系统的配置和程序的编译配置。
1. 操作系统配置大多数Unix-like系统默认是开启coredump功能的,但有时会被禁用。
我们可以通过下面的命令来查看系统是否开启了coredump功能:ulimit -c如果输出为0,则表示未开启,大于0则表示开启。
我们可以通过下面的命令来开启coredump功能,并设置生成的core文件大小:ulimit -c unlimitedulimit -c <size>其中,<size>指的是core文件的大小,单位为字节。
2. 编译配置在编译程序时,我们需要添加-g选项来启用调试信息的产生。
例如,我们可以使用gcc编译C程序时,添加如下的命令行选项:gcc -g -o program program.c通过以上配置,就可以在程序崩溃时生成core文件。
三、使用GDB调试coredump文件1. 命令行方式通过命令行方式使用GDB调试coredump文件非常简单,只需指定coredump文件和可执行文件即可。
coredump文件生成过程
生成core dump文件通常发生在程序发生严重错误或崩溃时,
它记录了程序在崩溃时的内存状态和调用栈信息,有助于开发人员
分析问题并进行调试。
下面我会从多个角度来解释core dump文件
生成的过程。
1. 产生原因,当程序发生严重错误,比如访问非法内存、除零
错误、段错误等,操作系统会向程序发送一个信号,通常是SIGSEGV(段错误)或SIGABRT(异常终止),程序在收到信号后会
尝试生成core dump文件。
2. 操作系统设置,在大多数操作系统中,生成core dump文件
需要进行相应的设置。
在Linux系统中,可以使用ulimit命令设置core文件大小限制,使用sysctl命令设置core文件的名称格式和
存储路径。
在Windows系统中,可以通过控制面板中的系统属性进
行设置。
3. 内存转储,当程序接收到信号时,操作系统会将程序的内存
状态以及相关信息写入core dump文件中。
这包括程序的内存布局、寄存器状态、堆栈信息等。
4. 存储位置,生成的core dump文件通常会被存储在当前工作目录或指定的路径下,具体存储位置取决于系统设置和程序运行时的环境变量。
5. 调试分析,生成core dump文件后,开发人员可以使用调试工具(如gdb、windbg等)加载core dump文件,重现程序崩溃时的状态,并进行分析和调试,以找出程序中的错误和异常。
总的来说,生成core dump文件是程序在发生严重错误时的一种自我保护机制,它记录了程序崩溃时的状态信息,为开发人员提供了重要的调试和分析数据,有助于快速定位和解决问题。
⼜见OutOfMemory——⼀次内存溢出故障诊断全过程聚沙成塔-⼩哈的记事薄这是⼀个⼏⽉前的案例,问题⽐较典型,在分析和事后学习的过程中让我对本地内存溢出有了⼀定的了解。
在此和⼤家分享。
先说⼀下背景,应⽤环境是AIX5.3+WebSphere6.0.2.37。
在今年的⼀季度曾发⽣过⼏次OOM故障,当时通过⼏次内存参数优化,最后确定为“-Xgcprolicy:gencon –Xms512m –Xmx1280m –Xmn200m”,此后稳定了半年,直到此次再发⽣应⽤宕机。
赶到现场,发现profiles⽬录下⽣成有javacore和heapdump⽂件,Javacore的第⼀⾏“Cause of thread dump : Dump Event "systhrow" (00040000) Detail "java/lang/OutOfMemoryError" received”表明了宕机的原因是OOM,但是令我困惑的是这段内容:0SECTION MEMINFO subcomponent dump routineNULL =================================1STHEAPFREE Bytes of Heap Space Free: 818cb701STHEAPALLOC Bytes of Heap Space Allocated: 20000000在分配的512MB(⼗六进制20000000)的堆空间中,有129MB(818cb70)空闲空间,按理说,这种情况下不该发⽣OutOfMemory。
就算有申请⼀个⼤对象,同时JVM堆的新⽣代由于碎⽚原因没有连续空间满⾜要求,那么应该发⽣堆扩展,所以此次内存溢出不是堆(Heap)溢出,GC⽇志的分析也⽀持了这⼀点。
既然Javacore⽆法得到有⽤信息,我把⽬光转向了SystemErr.log,在对应⽇期的地⽅,我发现了⼤量如下报错:[8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr R Exception in thread "WebContainer : 1"ng.RuntimeException: ng.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 11 [8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr R atcom.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:801)[8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr R atcom.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)[8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr R atcom.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)[8/26/10 14:12:57:860 GMT+08:00] 0000002f SystemErr R Caused by: ng.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 11at ng.Thread.startImpl(Native Method)at ng.Thread.start(Thread.java:980)at com.ibm.ws.util.ThreadPool.addThread(ThreadPool.java:630)at com.ibm.ws.util.ThreadPool$3.run(ThreadPool.java:1148)at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:63)at com.ibm.ws.util.ThreadPool.execute(ThreadPool.java:1146)at com.ibm.ws.util.ThreadPool.execute(ThreadPool.java:1040)at com.ibm.ws.runtime.WSThreadPool.execute(WSThreadPool.java:151)at com.ibm.io.async.ResultHandler.startHandler(ResultHandler.java:248)at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:570)at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)在事后的学习中,我知道“ng.OutOfMemoryError: unable to create native thread” 这样的异常是在说,本地内存耗尽,从⽽新的线程⽆法创建。
CoreDump详解1. 什么是Core:Sam之前一直以为Core Dump中Core是Linux Kernel的意思. 今天才发现在这里,Core是另一种意思:在使用半导体作为内存的材料前,人类是利用线圈当作内存的材料(发明者为王安),线圈就叫作core ,用线圈做的内存就叫作core memory。
如今,半导体工业澎勃发展,已经没有人用core memory 了,不过,在许多情况下,人们还是把记忆体叫作core 。
2. 什么是Core Dump:我们在开发(或使用)一个程序时,最怕的就是程序莫明其妙地当掉。
虽然系统没事,但我们下次仍可能遇到相同的问题。
于是这时操作系统就会把程序当掉时的内存内容dump 出来(现在通常是写在一个叫core 的file 里面),让我们或是debugger 做为参考。
这个动作就叫作core dump。
3. Core Dump时会生成何种文件:Core Dump时,会生成诸如core.进程号的文件。
4. 为何有时程序Down了,却没生成Core文件。
Linux下,有一些设置,标明了resources available to the shell and to processes。
可以使用#ulimit -a来看这些设置。
(ulimit是bash built-in Command)-a All current limits are reported-c The maximum size of core files created-d The maximum size of a process鈥檚data segment-e The maximum scheduling priority ("nice")-f The maximum size of files written by the shell and its children-i The maximum number of pending signals-l The maximum size that may be locked into memory-m The maximum resident set size (has no effect on Linux)-n The maximum number of open file descriptors (most systems do not allow this value to be set)-p The pipe size in 512-byte blocks (this may not be set)-q The maximum number of bytes in POSIX message queues -r The maximum real-time scheduling priority-s The maximum stack size-t The maximum amount of cpu time in seconds-u The maximum number of processes available to a single user-v The maximum amount of virtual memory available to the shell-x The maximum number of file locks从这里可以看出,如果-c是显示:core file size (blocks, -c)如果这个值为0,则无法生成core文件。
AIX操作系统工作手册文件编号版 本0.1作成日2023年10月24日修订日发布日修 改 履 历序号版本修改日期章节号修改记录修改人批准人10.12023/10/23创建修游书目1引言 (5)1.1编写目的 (5)1.2适用范围 (5)1.3预期读者 (5)1.4文档说明 (5)2操作系统健康性检查 (6)2.1系统日志 (6)系统硬件错误日志检查 (6)系统全部错误日志检查 (7)系统错误日志Core_dump检查 (8)系统错误日志DELAYED_INT检查 (9)系统邮件日志内容检查 (9)系统邮件日志大小检查 (11)登录失败日志文件大小检查 (11)登录日志文件大小检查 (12)su日志文件大小检查 (13)异样终止的vi日志文件大小检查 (13)2.2系统性能 (14)系统CPU运用率检查 (14)查看占用CPU资源最多的进程 (17)系统内存运用率检查 (18)系统占用内存资源最多的进程 (20)系统磁盘繁忙程度检查 (22)2.3交换空间 (23)交换空间运用率检查 (23)2.4进程状态 (24)僵尸进程检查 (24)2.5网络状态 (24)网卡状态检查 (24)路由状态检查 (25)网络传输检查 (26)网络连接数量及状态检查 (30)主机解析检查 (32)2.6存储状态 (32)HBA卡状态检查 (32)2.7文件系统状态 (33)文件系统运用率检查 (33)文件系统挂载检查 (34)NFS文件系统挂载检查 (35)dump设备空间检查 (35)2.8逻辑卷状态 (36)Rootvg的剩余空间检查 (36)PV状态检查 (37)是否存在stale的pp检查 (37)2.9系统平安 (38)系统登录状况检查 (38)特权用户检查 (39)Su操作次数检查 (40)失败登录记录检查 (40)2.10双机状态 (41)双机心跳状态检查 (41)Hacmp.out日志检查 (42)Cluster.log日志检查 (42)双机节点状态检查 (43)2.11其它 (44)操作系统时间检查 (44)3操作系统异样快速排查规范 (44)3.1系统日志检查 (45)3.2CPU运用率检查 (45)3.3内存运用率检查 (45)3.4I/O运用率检查 (46)3.5网络检查 (46)3.6交换区检查 (47)3.7文件系统检查 (47)3.8双机检查 (48)1引言1.1编写目的为了保证项目组所运维系统的持续健康运行,降低操作系统的出错几率,并在出现问题时刚好且有效的进行排查、处理,故编写本手册。
coredump文件考出解析Core Dump文件是指在计算机程序运行时,出现异常情况导致程序崩溃时所生成的一种文件。
这个文件记录了程序在崩溃时的内存状态信息,包含了程序运行时的堆栈信息、寄存器状态以及其他相关的调试信息等。
通过分析Core Dump文件,可以帮助开发人员定位和解决程序崩溃的问题。
Core Dump文件的解析对于软件开发人员来说是一项非常重要的技能,可以帮助他们快速定位和修复程序中的bug。
下面就让我们来了解一下Core Dump文件的解析过程吧。
要解析Core Dump文件,我们需要借助一些调试工具。
常用的调试工具有GDB(GNU Debugger)、LLDB(LLVM Debugger)等。
这些工具可以加载Core Dump文件,并提供一系列命令和功能来分析和调试程序。
解析Core Dump文件的第一步是加载文件。
使用调试工具加载Core Dump文件后,我们可以查看文件中的各种信息。
比如,我们可以查看程序崩溃时的堆栈信息,了解程序在崩溃前的执行路径。
通过分析堆栈信息,我们可以确定程序崩溃的位置,找出导致程序崩溃的原因。
除了堆栈信息,Core Dump文件还包含了程序崩溃时的内存状态信息。
我们可以通过查看内存状态,了解程序在崩溃前的变量值、函数调用等信息。
这对于定位程序崩溃的原因非常有帮助。
在解析Core Dump文件时,我们还可以使用调试工具提供的其他功能,比如查看变量的值、设置断点、单步执行等。
这些功能可以帮助我们进一步分析和调试程序。
在进行Core Dump文件解析时,我们需要注意以下几点。
首先,要保证使用的调试工具版本与生成Core Dump文件的程序版本一致,以免出现兼容性问题。
其次,要注意文件的大小,如果Core Dump 文件过大,可能需要分析工具支持加载大文件。
此外,要注意保护好Core Dump文件的安全,避免泄露敏感信息。
除了使用调试工具解析Core Dump文件,还有一些第三方工具和库可以帮助我们更方便地分析Core Dump文件。
Linux上CoreDump⽂件的形成和分析原⽂:/4114344/904419Core,⼜称之为Core Dump⽂件,是Unix/Linux操作系统的⼀种机制,对于线上服务⽽⾔,Core令⼈闻之⾊变,因为出Core的过程意味着服务暂时不能正常响应,需要恢复,并且随着吐Core进程的内存空间越⼤,此过程可能持续很长⼀段时间(例如当进程占⽤60G+以上内存时,完整Core⽂件需要15分钟才能完全写到磁盘上),这期间产⽣的流量损失,不可估量。
凡事皆有两⾯性,OS在出Core的同时,虽然会终⽌掉当前进程,但是也会保留下第⼀⼿的现场数据,OS仿佛是⼀架被按下快门的相机,⽽照⽚就是产出的Core⽂件。
⾥⾯含有当进程被终⽌时内存、CPU寄存器等信息,可以供后续开发⼈员进⾏调试。
关于Core产⽣的原因很多,⽐如过去⼀些Unix的版本不⽀持现代Linux上这种GDB直接附着到进程上进⾏调试的机制,需要先向进程发送终⽌信号,然后⽤⼯具阅读core⽂件。
在Linux上,我们就可以使⽤kill向⼀个指定的进程发送信号或者使⽤gcore命令来使其主动出Core并退出。
如果从浅层次的原因上来讲,出Core意味着当前进程存在BUG,需要程序员修复。
从深层次的原因上讲,是当前进程触犯了某些OS层级的保护机制,逼迫OS向当前进程发送诸如SIGSEGV(即signal 11)之类的信号, 例如访问空指针或数组越界出Core,实际上是触犯了OS的内存管理,访问了⾮当前进程的内存空间,OS需要通过出Core来进⾏警⽰,这就好像⼀个⼈⾝体内存在病毒,免疫系统就会通过发热来警⽰,并导致⼈体发烧是⼀个道理(有意思的是,并不是每次数组越界都会出Core,这和OS的内存管理中虚拟页⾯分配⼤⼩和边界有关,即使不出Core,也很有可能读到脏数据,引起后续程序⾏为紊乱,这是⼀种很难追查的BUG)。
说了这些,似乎感觉Core很强势,让⼈感觉缺乏控制⼒,其实不然。
Coredump关于程序core dump的调试方法简述:首先,在程序不正常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。
使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。
这个能给debug带来极大方便。
查看core dump位置方法:"gdb ./app core".故,我们需要gdb,可执行文件app,以及core文件。
下面将根据这3个需求,依次得到它们;一、1,得到gdb;其实这个是最简单的,Linux PC上gdb不用说了。
Android的是~/opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/b in/arm-linux-androideabi-gdb(其中~/opt/,与个人设置有关;android-ndk-r7与编译器版本有关,貌似android-ndk-r4没有toolchains目录,不知是否可以用gdbserver调试程序,当然这就不在本文档的讨论范围之内了).2,得到可执行文件app由于要使用gdb,所以app必须是"not stripped".Linux PC上"gcc hello.c"编译出来的a.out默认就是"not stripped".Android工程中jni目录下,我们使用"ndk-build"默认是"stripped"的。
因此需要更改编译脚本:在~/opt/android-ndk-r7/build/core/中打开default-build-commands.mk文件,将"cmd-strip = $(PRIVATE_STRIP) --strip-unneeded $(call host-path,$1)"这一行注释掉.这一行就是做的"strip"操作。
本文简要介绍了AIX 平台下core dump 产生的原理以及相关定位方法。
Core dump 基本知识本节主要探讨core dump 产生的背景知识。
对这部分不感兴趣的读者可以直接阅读第二章,了解基本的core dump 定位手段。
起源软件是人思维的产物。
智者千虑,必有一失,人的思维总有缺陷,反映到软件层面上就是程序bug。
程序bug 的终极体现就是core dump,core dump 是软件错误无法恢复的产物。
生成过程进程core dump 与系统dump 的产生,从程序原理上来说是基本一致的。
dump 的生成一般是在系统进行中断处理时进行的,下面简单介绍一下中断机制。
操作系统的中断机制操作系统是由中断驱动的。
广义的中断一般分为两类,中断(Interrupts) 和异常(Exceptions)。
中断可在任何时候发生,与CPU 正在执行什么指令无关,中断主要由I/O 设备、处理器时钟(分时系统依赖时钟中断划分时间片)或定时器等硬件引发,可以被允许或取消。
而异常是由于CPU 执行了某些指令引起的,可以包括存储器存取违规、除0 或者特定调试指令等,内核也将系统服务视为异常。
系统对这两类中断的处理基本上是相同的。
每个中断都会唯一对应到一个中断处理程序,在该中断触发时,相应的处理程序就会被执行。
例如应用进程进行系统调用时,就会触发一个软件异常,进入中断处理函数,完成从用户态到系统态的迁移并进入相应系统调用的入口点。
应用进程coredump 也是一个类似的过程。
应用进程core dump 生成过程在进程运行出现异常行为时,例如无效地址访问、浮点异常、指令异常等,将导致系统转入内核态进行异常处理(即中断处理),向相应的进程发出特定信号例如SIGSEGV、SIGFPE、SIGILL 等。
如果应用进程注册了相应信号的处理函数(例如可通过sigaction 注册信号处理函数),则调用相应处理函数进行处理(应用程序可以选择记录信息后生成core dump 并退出);否则将采取默认动作,例如SIGSEGV 的默认动作是生成core dump 并退出程序。
进程coredump 的时候,操作系统会将进程终止并释放其占用的资源,正常情况下,应用进程coredump 不会对系统本身的运行造成危害。
当然如果系统中存在与此进程相关的其他进程,则这些进程会受到影响,至于后果则视其对此异常的具体处理而定。
由于相关指令已经包含在可执行文件中,core 文件一般只包含进程异常时相关的内存信息。
其格式可参考/usr/include/sys/core.h 或者AIX 帮助文档的“Files Reference”章节。
我们一般需要结合core 文件以及可执行程序,来分析问题所在。
注:由于进程信号处理本质上是异步的,应用进程注册的信号处理函数中使用的例程需要保证是异步信号安全的,例如不能使用诸如pthread_ 开头的例程。
系统dump 生成过程系统异常dump 的具体过程与应用进程类似,但由于更接近底层,为了避免问题所在的资源(例如文件系统)正好包含在生成dump 需要使用的资源中,造成dump 无法生成,操作系统一般会用最简单的方式来生成dump。
例如系统内存小于4G 的情况下,一般直接将dump 生成在pagingspace 中;大于4G 时,会建专门的lg_dumplv 逻辑卷(裸设备)保存dump 信息。
在系统重启的时候,如果设置的DUMP 转存目录(文件系统中的目录)有足够空间,它将会转存成一个文件系统文件,缺省情况下,是/var/adm/ras/ 下的vmcore* 这样的文件。
系统dump 一般可以通过升级微码、提高系统补丁级别、升级驱动等方式解决。
应用进程core dump 分析上一章我们介绍了core dump 产生的基本原理。
本章我们将针对AIX 操作系统,介绍core dump 定位相关的背景知识。
环境变量设置可以通过/etc/security/limits 文件对各用户的基本配置参数包括core 大小进行限制。
或者通过ulimit 更改当前环境下的core 大小限制。
默认情况下,应用进程生成core dump 时都使用文件名core。
为了避免同一工作目录下的进程core 相互覆盖,可以定义环境变量CORE_NAMING=true,然后启动进程,这样将生成名为core.pid.ddhhmmss 的文件。
可以使用file core 命令查看core 是哪个进程产生的。
默认情况下,应用进程dump 时会包含所有的共享内存,如果dump 时想排除共享内存内容,可以在启动进程之前设置环境变量CORE_NOSHM=true.系统有一个参数fullcore 用于控制是否在程序coredump 时生成完整的core。
为避免信息丢失,建议打开fullcore。
可以使用lsattr –El sys0 查询是否将fullcore 打开,使用chdev -l sys0 -a fullcore=true 将fullcore 状态更改为打开。
也可以在程序内部调用sigaction 例程设置fullcore,参考如下测试程序:fullcore 设置示例//test.C#include <iostream>#include <signal.h>int main(int argc, char* argv[]){char str[10];struct sigaction s;s.sa_handler = SIG_DFL;s.sa_mask.losigs = 0;s.sa_mask.hisigs = 0;s.sa_flags = SA_FULLDUMP;sigaction(SIGSEGV,&s,(struct sigaction*) NULL);std::cout << " input str!\n" << std::endl;std::cin >> str;return 0;}寻找core dump应用进程的core 产生在其当前工作目录下,可以在应用程序内部使用chdir 函数切换当前工作目录。
使用procwdx 命令可以查看进程的当前工作目录。
系统的core 生成在lg_dumplv 下,并在重启时转移到/var/adm/ras/ 目录下(如果有足够空间的话,否则继续保留在lg_dumplv,并随时有可能被覆盖)。
可以使用errpt -a 查看标识C0AA5338 SYSDUMP(系统core)、B6048838 CORE_DUMP(进程core)的详细错误信息,获取生成core 的进程以及core 文件位置。
使用snap –ac 收集系统的dump 信息。
core dump 信息收集如果可能, 直接在发生coredump 的机器上用dbx 分析出结果, 这样是最方便的分析方法 . 这种情况下注意不要直接以root 用户登录然后用dbx 分析, 而必须在应用程序所属的用户下进行此操作,因为core 可能需要依赖应用程序运行时对应环境下的某些库, 这样就要借助应用程序的环境变量 .如果需取回生产机上的core 信息在实验室分析, 则需要搜集一些相关信息 . 进程core 分析一般至少需要依赖应用可执行程序,有时还需要包括一些运行时动态库信息。
如果需要收集core 相关的完整信息,可运行snapcore <core 路径以及名称> < 可执行文件以及名称>,例如snapcore ./core ./a.out,然后在/tmp/snapcore 下取下相应的 .pax.Z 文件。
正常的收集过程应该如下:snap core 收集过程# snapcore ./core ./a.outCore file "./core" created by "a.out"pass1() in progress ....Calculating space required .Total space required is 14130 kbytes ..Checking for available space ...Available space is 807572 kbytespass1 complete.pass2() in progress ....Collecting fileset information .Collecting error report of CORE_DUMPerrors ..Creating readme file ..Creating archive file ...Compressing archive file ....pass2 completed.Snapcore completed successfully. Archivecreated in /tmp/snapcore.# cd /tmp/snapcore# lssnapcore_352276.pax.Z# uncompress snapcore_352276.pax.Z# lssnapcore_352276.pax# pax -r -f snapcore_352276.pax# ls 注意需要保证有类似如下文件 ( 可执行文件,/core/errpt/lslpp/usr 目录等 ):README errpt.out usra.out lslpp.outcore snapcore_352276.pax#使用dbx 分析core dump 的例子dbx 是AIX 下基于命令行界面的源码级调试工具。
本文档只提供一些基本的dbx 分析指令,详细内容请参考“General Programming Concepts: Writing and Debugging Programs”关于dbx 的描述。
初步分析示例:显示出core 发生时,当前进程执行到的位置(-g 编译的情况下能够看到具体的行):注意:如果分析的是异地core 文件,需要采用snapcore 收集相关core 信息。
对于依赖链接库的情况,注意需要增加-p oldpath=newpath:... 重新设置链接库路径(只有所有依赖的库都已经被链接,才能完整的复现core dump 故障现场),参考dbx 的帮助文档获取更多信息。
列举源码信息列举程序源码(list,需要在运行dbx 命令时使用-I 指明源码搜索路径,并使用-g 编译)或者汇编码(listi):(dbx) listi main0x10001924 (main) 7c0802a6 mflr r00x10001928 (main+0x4) bfa1fff4 stmwr29,-12(r1)0x1000192c (main+0x8) 90010008 stwr0,0x8(r1)0x10001930 (main+0xc) 9421ffa0 stwur1,-96(r1)0x10001934 (main+0x10) 83e20064 lwzr31,0x64(r2)0x10001938 (main+0x14) 90610078 stwr3,0x78(r1)0x1000193c (main+0x18) 9081007c stwr4,0x7c(r1)0x10001940 (main+0x1c) 83a20068 lwzr29,0x68(r2)列举变量内容示例代码:para++;return 0;}int main(int argc, char* argv[]){struct sigaction s;s.sa_handler = SIG_DFL;s.sa_mask.losigs = 0;s.sa_mask.hisigs = 0;s.sa_flags = SA_FULLDUMP;sigaction(SIGSEGV,&s,(struct sigaction*) NULL);char str[10];g_test =0;testfunc(g_test);abort();}# xlC test.C -g以全局变量g_test 举例:#print g_test 显示g_test 的取值#print sizeof(g_test) 显示g_test 的大小#whatis g_test 显示g_test 的类型#print &g_test 显示g_test 的地址#&g_test/16x 显示从g_test 的地址开始处,连续16 个WORD(?byte)的取值如果没有使用-g 编译,则不能动态获取g_test 的类型、大小等信息,但能够得到g_test 的地址,并查询该地址所在区域存储空间的值。