这几天在做总结,把三年前写的一个定位案例,翻了出来。回想起定位这个问题时的场景,领导催得紧,自己对很多东西又不熟悉,所以当时面临的压力还是很大的。现在回想起来感慨还是很多的,我们在遇到任何一个问题,一定不要放弃。还记得在产品线做开发时,学到的一些项目知识,任何一个bug,他总有一天会爆发出来。任何一个问题,总有一天找到好的解决方案。当我们尝尽了所有可以尝试的方案,定位办法,解决思路后,往往这个问题也就迎刃而解了。
把工程上的事情放大看,其实生活中很多事情都是一样的,任何一个问题都有解决办法,但是这个办法不是摆在那里给我们用,他是藏在某个地方,等着我们去挖掘的。所以勤奋,努力,不气馁,找对方向都是很重要的。
好了,我们言归正传,说下我这个踩内存的问题。首先我们来看一下,公司常讲的编程规范:有一条是说,
结构体指针在使用前需要赋初值。
这是很简单的一条规则,很多时候,我们会觉着麻烦,或者我们在后面具体用到这个结构体时,我们再对结构体的成员赋值也可以,或者我们在使用时,仅对我们感兴趣的成员赋值就好了,其他的我们就不关心了。但是下面我来告诉大家,这是不行的,下面这个问题会告诉大家,编程规范都是用血的教训写出来的。遵守它,我们就可以避免很多不必要的debuging。
我们下面看下这种写法是否正确:
structmsghdr msg;
msg.msg_iov= &iov;
msg.msg_iovlen=iovlen;
ret= recvmsg(sockfd, &msg, int flags);
在函数中,我们定义了一个msg结构体,但是没有给这个结构体赋初值,仅对其中的两个我们关心的变量做了赋值。那么这样是否会带来问题呢?
在项目交付前,A同学需要完成对S系统的压力测试,上面会反复的重启虚拟机,反复的杀死大量服务进程,做cpu,内存加压。这样的压力测试大概执行一天到两天,就会出现异常,C服务出现了大量的coredump。
这个问题是怎么产生的,如何定位这个问题,下面请看具体的定位步骤:
1、coredump
应用程序由于各种异常或者bug导致在运行过程中异常退出或者中止,并且在满足一定条件下会产生一个叫做core的文件。通常情况下,core文件会包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等,我们可以理解为是程序工作当前状态存储生成第一个文件,许多的程序出错的时候都会产生一个core文件,通过分析这个文件,我们可以定位到程序异常退出的时候对应的堆栈调用等信息,找出问题所在并进行及时解决。
应用程序崩溃时能产生core文件,还需要做一些设置:
1) 修改ulimit –c
如下,ulimit -c设置core文件大小,一般设置为unlimited,让core文件不受大小限制。如果在当前会话设置,那么仅对当前会话的应用程序有效,即只有当前会话的程序崩溃才会有core文件生成。如果要想系统均有效,需要设置/etc/profile文件,在文件中加入ulimit –c unlimited,然后source /etc/profile,让配置生效。如果还是生成不了core文件,可以在拉起进程的脚本里加入ulimit –c unlimited。
2) 配置core文件生成路径
core文件默认的存储位置与对应的可执行程序在同一目录下,文件名为core,很多时候程序崩溃了,我们找不到core文件存放在什么位置,按照如下方法可以指定core文件的存放位置。
echo "/home/xx/core-%e-%p-%u-%g-%t" > /proc/sys/kernel/core_pattern
参数含义:%%:相当于%
%p