<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[[实践OK]Linux CentOs6.2下下如何生成core dump文件及用GDB调试方法及设置，修改Linux操作系统生成core dump文件的默认路径？]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Wed, 04 Jul 2012 14:11:41 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	背景：调一个多进程程序，发现中间挂了，可我自己写的代码的父亲进程又拉起来了，无法调试到挂的原因，在当前目录下找不到coredump文件怎么办？修改Linux操作系统生成core dump文件的默认路径？最后，子进程死了父亲进程拉起，crack这块可能是return退出了，自己打印是crack，导致并不是真正的crack了，也就不是coredump了，特别注意这个问题。<br/><br/>gdb --core=core.9128<br/>(gdb) file ./a.out<br/><br/>巡视：再看看默认的一些参数，注意core file size是个0，程序出错时不会产生core文件了， 如下：<br/>[root@test log]# ulimit -a<br/>core file size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(blocks, -c) 0<br/>实践：没有找到core文件，我们改改ulimit的设置，让它产生。1024是随便取的，要是core文件大于1024个块，就产生不出来了。<br/>$ ulimit -c 1024<br/><br/>$ ulimit -a<br/>core file size (blocks, -c) 1024<br/>ulimit -S -c unlimited &gt; /dev/null 2&gt;&amp;1<br/><br/>[root@test multepoolserver]# ulimit -c 1024<br/>[root@test multepoolserver]# ulimit -a<br/>core file size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(blocks, -c) 1024<br/>修改路径：<br/>/sbin/sysctl -w kernel.core_pattern=/var/log/%e.core.%p<br/>kernel.core_pattern = /var/log/%e.core.%p<br/><br/>————————————————————————————————————————————————————————————————<br/>经过分析发现系统默认的core文件生成路径是/var/logs，但/var/logs目录并非系统自带的，系统初始安装默认自带的是/var/log，最终导致该系统出现core dump后并没能生成core文件，因此如何查询和修改系统默认的core dump文件生产路径呢？方法如下：<br/>一. 查询core dump文件路径： <br/>方法1：<br/># cat /proc/sys/kernel/core_pattern<br/><br/>方法2：<br/># /sbin/sysctl kernel.core_pattern<br/><br/>二. 修改core dump文件路径： <br/>方法1：<br/>临时修改：修改/proc/sys/kernel/core_pattern文件，但/proc目录本身是动态加载的，每次系统重启都会重新加载，因此这种方法只能作为临时修改。<br/>/proc/sys/kernel/core_pattern<br/>例：echo ‘/var/log/%e.core.%p’ &gt; /proc/sys/kernel/core_pattern<br/><br/>方法2：<br/>永久修改：使用sysctl -w name=value命令。<br/>例：/sbin/sysctl -w kernel.core_pattern=/var/log/%e.core.%p为了更详尽的记录core dump当时的系统状态，可通过以下参数来丰富core文件的命名：<br/>%% 单个%字符<br/>摘自：http://m.blog.csdn.net/blog/bytxl/9786347<br/>http://www.nginx.cn/1521.html<br/><br/><br/><br/>Linux CentOs6.2下下如何生成core dump文件及用GDB调试方法及设置<br/>http://baidutech.blog.51cto.com/4114344/904419<br/><br/>在软件开发的过程中，无论如何努力，bug几乎都是必不可少的。当某些bug发生时，该进程会产生coredump文件。通过这个coredump文件，开发人员可以找到bug的原因。但是coredump的产生，大都是因为程序crash了。<br/>1. 死锁 <br/>&nbsp;&nbsp; 有些bug是不会导致进程crash的，比如死锁——这时，程序已经不正常了，可是却没有coredump产生。如果环境又不允许gdb调试，难道我们就束手无策了吗？针对这种情况，一般情况下，对于这样的进程，可以利用watchdog监控它们，当发现这些进程很长时间没有更新其heartbeat时，可以给这些进程发送可以导致其产生coredump的信号。根据linux的信号默认的处理行为，SIGQUIT，SIGABRT, SIGFPE和SIGSEGV都可以让该进程产生coredump文件。这样我们可以通过coredump来得知死锁是否发生。当然，如果进程添加了这些信号的处理函数，那么就不会产生coredump了。<br/>2.获取指定位置快照:<br/>&nbsp;&nbsp; 还有一种情况，进程并没有死锁或者block在某个位置，但是我们需要在某个指定位置进行调试，获取某些变量或者其它信息。但是，有可能是客户环境或者生产环境，不允许我们进行长时间的检测。那么，我们就需要通过coredump来获得进程在运行到该点时的快照。<br/>这个时候，可以利用gdb来产生手工产生coredump。在attach上这个进程时，在指定位置打上断点，当断点触发时，使用gdb的命令gcore，可以立即产生一个coredump。这样，我们就拿到了这个位置的进程快照。1. 欲查看多线程程序中所有线程的调用栈信息====================================<br/>&nbsp;&nbsp;&nbsp;&nbsp; gdb attach xxx<br/>&nbsp;&nbsp;&nbsp;&nbsp; set height 0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread apply all bt<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detach<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q<br/>2. CPU占用率过高问题分析方法<br/>====================================<br/>shell下执行:ps -eLfP 找出cpu占用率高的线程<br/>UID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PID&nbsp;&nbsp;PPID&nbsp;&nbsp; LWP PSR&nbsp;&nbsp;C NLWP STIME TTY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME <br/>root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1431&nbsp;&nbsp;1270&nbsp;&nbsp;1751&nbsp;&nbsp; 5 90&nbsp;&nbsp; 64 Dec24 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;00:00:00 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^^^^&nbsp;&nbsp;^^ ^^<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread core cpurate<br/>使用gdb:<br/>gdb attach 1431&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;==== 登录cpu占用率高的进程<br/>set height 0 <br/>i thread&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;==== 打印该进程的所有线程<br/>找到 : LWP 1751 线程<br/>17 Thread 855356656 (LWP 1751)&nbsp;&nbsp;0x2ac30994 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0<br/>^^&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ^^^^^^^^<br/>打出cpu占用率高的 任务的调用栈:<br/>thread 17&nbsp;&nbsp; &lt;============&nbsp;&nbsp;切换到该线�<br/><br/>Linux生成core文件、core文件路径设置：<br/>——————————————————————————————————————————————————————————————<br/>在Linux下产生并调试core文件 先看看我用的是个什么机器：<br/><br/>$ uname -a<br/>Linux dev 2.4.21-9.30AXsmp #1 SMP Wed May 26 23:37:09 EDT 2004 i686 i686 i386 GNU/Linux<br/><br/>再看看默认的一些参数，注意core file size是个0，程序出错时不会产生core文件了。<br/><br/><br/>$ ulimit -a<br/>core file size (blocks, -c) 0<br/>data seg size (kbytes, -d) unlimited<br/>file size (blocks, -f) unlimited<br/>max locked memory (kbytes, -l) 4<br/>max memory size (kbytes, -m) unlimited<br/>open files (-n) 2048<br/>pipe size (512 bytes, -p) 8<br/>stack size (kbytes, -s) 10240<br/>cpu time (seconds, -t) unlimited<br/>max user processes (-u) 7168<br/>virtual memory (kbytes, -v) unlimited<br/><br/>写个简单的程序，看看core文件是不是会被产生。<br/><br/>$ more foo.c<br/><br/>#include &lt;stdio.h&gt;<br/><br/>static void sub(void);<br/><br/>int main(void)<br/>&#123;<br/>sub();<br/>return 0;<br/>&#125;<br/><br/>static void sub(void)<br/>&#123;<br/>int *p = NULL;<br/><br/>/* derefernce a null pointer, expect core dump. */<br/>printf(&quot;%d&quot;, *p);<br/>&#125;<br/><br/>$ gcc -Wall -g foo.c<br/>$ ./a.out<br/>Segmentation fault<br/><br/>$ ls -l core.*<br/>ls: core.*: No such file or directory<br/><br/>没有找到core文件，我们改改ulimit的设置，让它产生。1024是随便取的，要是core文件大于1024个块，就产生不出来了。<br/><br/>$ ulimit -c 1024<br/><br/>$ ulimit -a<br/>core file size (blocks, -c) 1024<br/>data seg size (kbytes, -d) unlimited<br/>file size (blocks, -f) unlimited<br/>max locked memory (kbytes, -l) 4<br/>max memory size (kbytes, -m) unlimited<br/>open files (-n) 2048<br/>pipe size (512 bytes, -p) 8<br/>stack size (kbytes, -s) 10240<br/>cpu time (seconds, -t) unlimited<br/>max user processes (-u) 7168<br/>virtual memory (kbytes, -v) unlimited<br/><br/>$ ./a.out<br/>Segmentation fault (core dumped)<br/>$ ls -l core.*<br/>-rw------- 1 uniware uniware 53248 Jun 30 17:10 core.9128<br/><br/>注意看上述的输出信息，多了个(core dumped)。确实产生了一个core文件，9128是该进程的PID。我们用GDB来看看这个core。<br/><br/>$ gdb --core=core.9128<br/>GNU gdb Asianux (6.0post-0.20040223.17.1AX)<br/>Copyright 2004 Free Software Foundation, Inc.<br/>GDB is free software, covered by the GNU General Public License, and you are<br/>welcome to change it and/or distribute copies of it under certain conditions.<br/>Type &quot;show copying&quot; to see the conditions.<br/>There is absolutely no warranty for GDB. Type &quot;show warranty&quot; for details.<br/>This GDB was configured as &quot;i386-asianux-linux-gnu&quot;.<br/>Core was generated by `./a.out&#039;.<br/>Program terminated with signal 11, Segmentation fault.<br/>#0 0x08048373 in ?? ()<br/>(gdb) bt<br/>#0 0x08048373 in ?? ()<br/>#1 0xbfffd8f8 in ?? ()<br/>#2 0x0804839e in ?? ()<br/>#3 0xb74cc6b3 in ?? ()<br/>#4 0x00000000 in ?? ()<br/><br/>此时用bt看不到backtrace，也就是调用堆栈，原来GDB还不知道符号信息在哪里。我们告诉它一下：<br/><br/>(gdb) file ./a.out<br/>Reading symbols from ./a.out...done.<br/>Using host libthread_db library &quot;/lib/tls/libthread_db.so.1&quot;.<br/>(gdb) bt<br/>#0 0x08048373 in sub () at foo.c:17<br/>#1 0x08048359 in main () at foo.c:8<br/><br/>此时backtrace出来了。<br/><br/>(gdb) l<br/>8 sub();<br/>9 return 0;<br/>10 &#125;<br/>11<br/>12 static void sub(void)<br/>13 &#123;<br/>14 int *p = NULL;<br/>15<br/>16 /* derefernce a null pointer, expect core dump. */<br/>17 printf(&quot;%d&quot;, *p);<br/>(gdb)<br/><br/>在程序不寻常退出时，内核会在当前工作目录下生成一个core文件（是一个内存映像，同时加上调试信息）。使用gdb来查看core文件，可以指示出导致程序出错的代码所在文件和行数。<br/><br/>1.core文件的生成开关和大小限制<br/>---------------------------------<br/>1）使用ulimit -c命令可查看core文件的生成开关。若结果为0，则表示关闭了此功能，不会生成core文件。<br/>2）使用ulimit -c filesize命令，可以限制core文件的大小（filesize的单位为kbyte）。若ulimit -c unlimited，则表示core文件的大小不受限制。如果生成的信息超过此大小，将会被裁剪，最终生成一个不完整的core文件。在调试此core文件的时候，gdb会提示错误。<br/><br/>2.core文件的名称和生成路径<br/>----------------------------<br/>core文件生成路径:<br/>输入可执行文件运行命令的同一路径下。<br/>若系统生成的core文件不带其他任何扩展名称，则全部命名为core。新的core文件生成将覆盖原来的core文件。<br/><br/>1）/proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作为扩展。文件内容为1，表示添加pid作为扩展名，生成的core文件格式为core.xxxx；为0则表示生成的core文件同一命名为core。<br/>可通过以下命令修改此文件：<br/>echo &quot;1&quot; &gt; /proc/sys/kernel/core_uses_pid<br/><br/>2）proc/sys/kernel/core_pattern可以控制core文件保存位置和文件名格式。<br/>可通过以下命令修改此文件：<br/>echo &quot;/corefile/core-%e-%p-%t&quot; &gt; core_pattern，可以将core文件统一生成到/corefile目录下，产生的文件名为core-命令名-pid-时间戳<br/>以下是参数列表:<br/>%p - insert pid into filename 添加pid<br/>%u - insert current uid into filename 添加当前uid<br/>%g - insert current gid into filename 添加当前gid<br/>%s - insert signal that caused the coredump into the filename 添加导致产生core的信号<br/>%t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间<br/>%h - insert hostname where the coredump happened into filename 添加主机名<br/>%e - insert coredumping executable name into filename 添加命令名<br/><br/>3.core文件的查看<br/>-----------------<br/>core文件需要使用gdb来查看。<br/>gdb ./a.out<br/>core-file core.xxxx<br/>使用bt命令即可看到程序出错的地方。<br/>以下两种命令方式具有相同的效果，但是在有些环境下不生效，所以推荐使用上面的命令。<br/>1）gdb -core=core.xxxx<br/>file ./a.out<br/>bt<br/>2）gdb -c core.xxxx<br/>file ./a.out<br/>bt<br/><br/>4.开发板上使用core文件调试<br/>-----------------------------<br/>如果开发板的操作系统也是linux，core调试方法依然适用。如果开发板上不支持gdb，可将开发板的环境（依赖库）、可执行文件和core文件拷贝到PC的linux下。<br/>在 PC上调试开发板上产生的core文件，需要使用交叉编译器自带的gdb，并且需要在gdb中指定solib-absolute-prefix和 solib-search-path两个变量以保证gdb能够找到可执行程序的依赖库路径。有一种建立配置文件的方法，不需要每次启动gdb都配置以上变量，即：在待运行gdb的路径下建立.gdbinit。<br/>配置文件内容：<br/>set solib-absolute-prefix YOUR_CROSS_COMPILE_PATH<br/>set solib-search-path YOUR_CROSS_COMPILE_PATH<br/>set solib-search-path YOUR_DEVELOPER_TOOLS_LIB_PATH<br/>handle SIG32 nostop noprint pass<br/>来自：http://www.nginx.cn/1521.html
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [实践OK]Linux CentOs6.2下下如何生成core dump文件及用GDB调试方法及设置，修改Linux操作系统生成core dump文件的默认路径？]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>