﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-to myself 的分类学习日志-随笔分类-linux programming</title><link>http://www.cppblog.com/toMyself/category/9702.html</link><description>做自己想做的事</description><language>zh-cn</language><lastBuildDate>Sat, 12 Sep 2015 01:44:58 GMT</lastBuildDate><pubDate>Sat, 12 Sep 2015 01:44:58 GMT</pubDate><ttl>60</ttl><item><title>example main function of linux server program</title><link>http://www.cppblog.com/toMyself/archive/2015/09/10/211800.html</link><dc:creator>kongkongzi</dc:creator><author>kongkongzi</author><pubDate>Thu, 10 Sep 2015 10:11:00 GMT</pubDate><guid>http://www.cppblog.com/toMyself/archive/2015/09/10/211800.html</guid><wfw:comment>http://www.cppblog.com/toMyself/comments/211800.html</wfw:comment><comments>http://www.cppblog.com/toMyself/archive/2015/09/10/211800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/toMyself/comments/commentRss/211800.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/toMyself/services/trackbacks/211800.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: example 1:https://github.com/paulran/test/blob/master/c%2B%2B/sample-server/src/AppMain.cppexample 2:Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/...&nbsp;&nbsp;<a href='http://www.cppblog.com/toMyself/archive/2015/09/10/211800.html'>阅读全文</a><img src ="http://www.cppblog.com/toMyself/aggbug/211800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/toMyself/" target="_blank">kongkongzi</a> 2015-09-10 18:11 <a href="http://www.cppblog.com/toMyself/archive/2015/09/10/211800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux程序调试</title><link>http://www.cppblog.com/toMyself/archive/2010/10/23/130963.html</link><dc:creator>kongkongzi</dc:creator><author>kongkongzi</author><pubDate>Sat, 23 Oct 2010 01:49:00 GMT</pubDate><guid>http://www.cppblog.com/toMyself/archive/2010/10/23/130963.html</guid><wfw:comment>http://www.cppblog.com/toMyself/comments/130963.html</wfw:comment><comments>http://www.cppblog.com/toMyself/archive/2010/10/23/130963.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/toMyself/comments/commentRss/130963.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/toMyself/services/trackbacks/130963.html</trackback:ping><description><![CDATA[<h3><br>Linux下的段错误产生的原因及调试方法</h3>
<p>&nbsp;&nbsp;&nbsp;原文地址：<a href="http://www.upsdn.net/html/2006-11/775.html">http://www.upsdn.net/html/2006-11/775.html</a>&nbsp;<br>&nbsp;&nbsp;&nbsp;参考地址：<a href="http://www.cnblogs.com/khler/archive/2010/09/16/1828349.html">http://www.cnblogs.com/khler/archive/2010/09/16/1828349.html</a>&nbsp;</p>
<p>简而言之,产生段错误就是访问了错误的内存段，一般是你没有权限，或者根本就不存在对应的物理内存,尤其常见的是访问0地址.<br><br>一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间，通常这个值是由gdtr来保存的，他是一个48位的寄存器，其中的32位是保存由它指向的gdt表，后13位保存相应于gdt的下标，最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表，在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问，cpu就会产生相应的异常保护，于是segmentation fault就出现了.<br><br>在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的<br><br>1)访问系统数据区，尤其是往&nbsp; 系统保护的内存地址写数据<br>&nbsp;&nbsp; 最常见就是给一个指针以0地址<br>2)内存越界(数组越界，变量类型不一致等) 访问到不属于你的内存区域<br><br>解决方法<br><br>我们在用C/C++语言写程序的时侯，内存管理的绝大部分工作都是需要我们来做的。实际上，内存管理是一个比较繁琐的工作，无论你多高明，经验多丰富，难 免会在此处犯些小错误，而通常这些错误又是那么的浅显而易于消除。但是手工&#8220;除虫&#8221;（debug），往往是效率低下且让人厌烦的，本文将就"段错误"这个 内存访问越界的错误谈谈如何快速定位这些"段错误"的语句。<br>下面将就以下的一个存在段错误的程序介绍几种调试方法：<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp; dummy_function (void)<br>&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *ptr = 0x00;<br>&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ptr = 0x00;<br>&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp; 6<br>&nbsp;&nbsp;&nbsp;&nbsp; 7&nbsp; int main (void)<br>&nbsp;&nbsp;&nbsp;&nbsp; 8&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp; 9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dummy_function ();<br>&nbsp;&nbsp;&nbsp; 10<br>&nbsp;&nbsp;&nbsp; 11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>&nbsp;&nbsp;&nbsp; 12&nbsp; }<br></td>
        </tr>
    </tbody>
</table>
作为一个熟练的C/C++程序员，以上代码的bug应该是很清楚的，因为它尝试操作地址为0的内存区域，而这个内存区域通常是不可访问的禁区，当然就会出错了。我们尝试编译运行它:<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>xiaosuo@gentux test $ ./a.out<br>段错误<br></td>
        </tr>
    </tbody>
</table>
果然不出所料，它出错并退出了。<br><span style="FONT-WEIGHT: bold">1.利用gdb逐步查找段错误:</span><br>这种方法也是被大众所熟知并广泛采用的方法，首先我们需要一个带有调试信息的可执行程序，所以我们加上&#8220;-g -rdynamic"的参数进行编译，然后用gdb调试运行这个新编译的程序,具体步骤如下:<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>xiaosuo@gentux test $ gcc -g -rdynamic d.c<br>xiaosuo@gentux test $ gdb ./a.out<br>GNU gdb 6.5<br>Copyright (C) 2006 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 "show copying" to see the conditions.<br>There is absolutely no warranty for GDB.&nbsp; Type "show warranty" for details.<br>This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".<br><br>(gdb) r<br>Starting program: /home/xiaosuo/test/a.out<br><br>Program received signal SIGSEGV, Segmentation fault.<br>0x08048524 in dummy_function () at d.c:4<br>4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ptr = 0x00;<br>(gdb)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br></td>
        </tr>
    </tbody>
</table>
哦？！好像不用一步步调试我们就找到了出错位置d.c文件的第4行，其实就是如此的简单。<br>从这里我们还发现进程是由于收到了SIGSEGV信号而结束的。通过进一步的查阅文档(man 7 signal)，我们知道SIGSEGV默认handler的动作是打印&#8221;段错误"的出错信息，并产生Core文件，由此我们又产生了方法二。<br><span style="FONT-WEIGHT: bold">2.分析Core文件：</span><br>Core文件是什么呢？<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>The&nbsp; default action of certain signals is to cause a process to terminate and produce a core dump file, a disk file containing an image of the process's memory&nbsp; at the time of termination.&nbsp; A list of the signals which cause a process to dump core can be found in signal(7).</td>
        </tr>
    </tbody>
</table>
以 上资料摘自man page(man 5 core)。不过奇怪了，我的系统上并没有找到core文件。后来，忆起为了渐少系统上的拉圾文件的数量（本人有些洁癖，这也是我喜欢Gentoo的原因 之一），禁止了core文件的生成，查看了以下果真如此，将系统的core文件的大小限制在512K大小，再试:<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>xiaosuo@gentux test $ ulimit -c<br>0<br>xiaosuo@gentux test $ ulimit -c 1000<br>xiaosuo@gentux test $ ulimit -c<br>1000<br>xiaosuo@gentux test $ ./a.out<br>段错误 (core dumped)<br>xiaosuo@gentux test $ ls<br>a.out&nbsp; core&nbsp; d.c&nbsp; f.c&nbsp; g.c&nbsp; pango.c&nbsp; test_iconv.c&nbsp; test_regex.c<br></td>
        </tr>
    </tbody>
</table>
core文件终于产生了，用gdb调试一下看看吧:<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>xiaosuo@gentux test $ gdb ./a.out core<br>GNU gdb 6.5<br>Copyright (C) 2006 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 "show copying" to see the conditions.<br>There is absolutely no warranty for GDB.&nbsp; Type "show warranty" for details.<br>This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".<br><br><br>warning: Can't read pathname for load map: 输入/输出错误.<br>Reading symbols from /lib/libc.so.6...done.<br>Loaded symbols for /lib/libc.so.6<br>Reading symbols from /lib/ld-linux.so.2...done.<br>Loaded symbols for /lib/ld-linux.so.2<br>Core was generated by `./a.out'.<br>Program terminated with signal 11, Segmentation fault.<br>#0&nbsp; 0x08048524 in dummy_function () at d.c:4<br>4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ptr = 0x00;<br></td>
        </tr>
    </tbody>
</table>
哇，好历害，还是一步就定位到了错误所在地，佩服一下Linux/Unix系统的此类设计。<br>接着考虑下去，以前用windows系统下的ie的时侯，有时打开某些网页，会出现&#8220;运行时错误&#8221;，这个时侯如果恰好你的机器上又装有windows的编译器的话，他会弹出来一个对话框，问你是否进行调试，如果你选择是，编译器将被打开，并进入调试状态，开始调试。<br>Linux下如何做到这些呢？我的大脑飞速地旋转着，有了，让它在SIGSEGV的handler中调用gdb，于是第三个方法又诞生了:<br><span style="FONT-WEIGHT: bold">3.段错误时启动调试:</span><br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;signal.h&gt;<br>#include &lt;string.h&gt;<br><br>void dump(int signo)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char buf[1024];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char cmd[1024];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILE *fh;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; snprintf(buf, sizeof(buf), "/proc/%d/cmdline", getpid());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!(fh = fopen(buf, "r")))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!fgets(buf, sizeof(buf), fh))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fclose(fh);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(buf[strlen(buf) - 1] == '\n')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf[strlen(buf) - 1] = '\0';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; snprintf(cmd, sizeof(cmd), "gdb %s %d", buf, getpid());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; system(cmd);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(0);<br>}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void<br>dummy_function (void)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *ptr = 0x00;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ptr = 0x00;<br>}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int<br>main (void)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signal(SIGSEGV, &amp;dump);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dummy_function ();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}<br></td>
        </tr>
    </tbody>
</table>
编译运行效果如下:<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>xiaosuo@gentux test $ gcc -g -rdynamic f.c<br>xiaosuo@gentux test $ ./a.out<br>GNU gdb 6.5<br>Copyright (C) 2006 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 "show copying" to see the conditions.<br>There is absolutely no warranty for GDB.&nbsp; Type "show warranty" for details.<br>This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".<br><br>Attaching to program: /home/xiaosuo/test/a.out, process 9563<br>Reading symbols from /lib/libc.so.6...done.<br>Loaded symbols for /lib/libc.so.6<br>Reading symbols from /lib/ld-linux.so.2...done.<br>Loaded symbols for /lib/ld-linux.so.2<br>0xffffe410 in __kernel_vsyscall ()<br>(gdb) bt<br>#0&nbsp; 0xffffe410 in __kernel_vsyscall ()<br>#1&nbsp; 0xb7ee4b53 in waitpid () from /lib/libc.so.6<br>#2&nbsp; 0xb7e925c9 in strtold_l () from /lib/libc.so.6<br>#3&nbsp; 0x08048830 in dump (signo=11) at f.c:22<br>#4&nbsp; &lt;signal handler called&gt;<br>#5&nbsp; 0x0804884c in dummy_function () at f.c:31<br>#6&nbsp; 0x08048886 in main () at f.c:38<br></td>
        </tr>
    </tbody>
</table>
怎么样？是不是依旧很酷？<br>以上方法都是在系统上有gdb的前提下进行的，如果没有呢？其实glibc为我们提供了此类能够dump栈内容的函数簇，详见/usr/include/execinfo.h（这些函数都没有提供man page，难怪我们找不到），另外你也可以通过<a href="http://www.gnu.org/software/libc/manual/html_node/Backtraces.html" target=_blank><strong><font color=#cc3333>gnu的手册</font></strong></a>进行学习。<br><span style="FONT-WEIGHT: bold">4.利用backtrace和objdump进行分析:</span><br>重写的代码如下:<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>#include &lt;execinfo.h&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;signal.h&gt;<br><br>/* A dummy function to make the backtrace more interesting. */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void<br>dummy_function (void)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *ptr = 0x00;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ptr = 0x00;<br>}<br><br>void dump(int signo)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *array[10];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t size;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char **strings;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t i;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = backtrace (array, 10);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strings = backtrace_symbols (array, size);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf ("Obtained %zd stack frames.\n", size);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; size; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf ("%s\n", strings[i]);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free (strings);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(0);<br>}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int<br>main (void)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signal(SIGSEGV, &amp;dump);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dummy_function ();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}<br></td>
        </tr>
    </tbody>
</table>
编译运行结果如下：<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>xiaosuo@gentux test $ gcc -g -rdynamic g.c<br>xiaosuo@gentux test $ ./a.out<br>Obtained 5 stack frames.<br>./a.out(dump+0x19) [0x80486c2]<br>[0xffffe420]<br>./a.out(main+0x35) [0x804876f]<br>/lib/libc.so.6(__libc_start_main+0xe6) [0xb7e02866]<br>./a.out [0x8048601]<br></td>
        </tr>
    </tbody>
</table>
这次你可能有些失望,似乎没能给出足够的信息来标示错误,不急,先看看能分析出来什么吧,用objdump反汇编程序,找到地址0x804876f对应的代码位置:<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>xiaosuo@gentux test $ objdump -d a.out<br></td>
        </tr>
    </tbody>
</table>
<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>&nbsp;8048765:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e8 02 fe ff ff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp; 804856c &lt;signal@plt&gt;<br>&nbsp;804876a:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e8 25 ff ff ff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp; 8048694 &lt;dummy_function&gt;<br>&nbsp;<span style="COLOR: rgb(255,1,2)">804876f</span>:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b8 00 00 00 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp; $0x0,%eax<br>&nbsp;8048774:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leave<br></td>
        </tr>
    </tbody>
</table>
我们还是找到了在哪个函数(dummy_function)中出错的,信息已然不是很完整,不过有总比没有好的啊!<br><span style="FONT-WEIGHT: bold">后记:</span><br>本文给出了分析"段错误"的几种方法,不要认为这是与孔乙己先生的"回"字四种写法一样的哦,因为每种方法都有其自身的适用范围和适用环境,请酌情使用,或遵医嘱。<br><br>部分资料来源于xiaosuo @ cnblog.cn, 特此致谢 </p>
<p>作者:upsdn整理 &nbsp; 更新日期:2006-11-03<br>来源:upsdn.net &nbsp; 浏览次数: <br><br><br><br><strong>其它调试办法</strong></p>
<ul>
    <li><strong>添加日志&nbsp;</strong></li>
</ul>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在Linux上的使用开源C++<font color=#cc0033>日志库</font>---log4cplus<strong>&nbsp;</strong></p>
<p><br><br><strong>linux下追踪函数调用堆栈<br></strong><span><br>一般察看函数运行时堆栈的方法是使用</span><span>GDB</span><span>之类的外部调试器</span><span>,</span><span>但是</span><span>,</span><span>有些时候为了分析程序的</span><span>BUG,(</span><span>主要针对长时间运行程序的分析</span><span>),</span><span>在程序出错时打印出函数的调用堆栈是非常有用的。</span></p>
<p>&nbsp;<span>在头文件</span><span>"execinfo.h"</span><span>中声明了三个函数用于获取当前线程的函数调用堆栈</span></p>
<p>&nbsp;<span>Function: int backtrace(void **buffer,int size)</span></p>
<p>&nbsp;<span>该函数用与获取当前线程的调用堆栈</span><span>,</span><span>获取的信息将会被存放在</span><span>buffer</span><span>中</span><span>,</span><span>它是一个指针列表。参数</span><span> size </span><span>用来指定</span><span>buffer</span><span>中可以保存多少个</span><span>void* </span><span>元素。函数返回值是实际获取的指针个数</span><span>,</span><span>最大不超过</span><span>size</span><span>大小</span></p>
<p>&nbsp;<span>在</span><span>buffer</span><span>中的指针实际是从堆栈中获取的返回地址</span><span>,</span><span>每一个堆栈框架有一个返回地址</span></p>
<p>&nbsp;<span>注意某些编译器的优化选项对获取正确的调用堆栈有干扰</span><span>,</span><span>另外内联函数没有堆栈框架</span><span>;</span><span>删除框架指针也会使无法正确解析堆栈内容</span></p>
<p>&nbsp;<span>Function: char ** backtrace_symbols (void *const *buffer, int size)</span></p>
<p>&nbsp;<span>backtrace_symbols</span><span>将从</span><span>backtrace</span><span>函数获取的信息转化为一个字符串数组</span><span>. </span><span>参数</span><span>buffer</span><span>应该是从</span><span>backtrace</span><span>函数获取的数组指针</span><span>,size</span><span>是该数组中的元素个数</span><span>(backtrace</span><span>的返回值</span><span>) </span></p>
<p>&nbsp;<span>函数返回值是一个指向字符串数组的指针</span><span>,</span><span>它的大小同</span><span>buffer</span><span>相同</span><span>.</span><span>每个字符串包含了一个相对于</span><span>buffer</span><span>中对应元素的可打印信息</span><span>.</span><span>它包括函数名，函数的偏移地址</span><span>,</span><span>和实际的返回地址</span></p>
<p>&nbsp;<span>现在</span><span>,</span><span>只有使用</span><span>ELF</span><span>二进制格式的程序和苦衷才能获取函数名称和偏移地址</span><span>.</span><span>在其他系统</span><span>,</span><span>只有</span><span>16</span><span>进制的返回地址能被获取</span><span>.</span><span>另外</span><span>,</span><span>你可能需要传递相应的标志给链接器</span><span>,</span><span>以能支持函数名功能</span><span>(</span><span>比如</span><span>,</span><span>在使用</span><span>GNU ld</span><span>的系统中</span><span>,</span><span>你需要传递</span><span>(-rdynamic))</span></p>
<p>&nbsp;<span>该函数的返回值是通过</span><span>malloc</span><span>函数申请的空间</span><span>,</span><span>因此调用这必须使用</span><span>free</span><span>函数来释放指针</span><span>.</span></p>
<p>&nbsp;<span>注意</span><span>:</span><span>如果不能为字符串获取足够的空间函数的返回值将会为</span><span>NULL</span></p>
<p>&nbsp;<span>Function:void backtrace_symbols_fd (void *const *buffer, int size, int fd)</span></p>
<p>&nbsp;<span>backtrace_symbols_fd</span><span>与</span><span>backtrace_symbols </span><span>函数具有相同的功能</span><span>,</span><span>不同的是它不会给调用者返回字符串数组</span><span>,</span><span>而是将结果写入文件描述符为</span><span>fd</span><span>的文件中</span><span>,</span><span>每个函数对应一行</span><span>.</span><span>它不需要调用</span><span>malloc</span><span>函数</span><span>,</span><span>因此适用于有可能调用该函数会失败的情况。</span></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">execinfo.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;<br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;<br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdlib.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;<br><br></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;Obtain&nbsp;a&nbsp;backtrace&nbsp;and&nbsp;print&nbsp;it&nbsp;to&nbsp;stdout.&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000">&nbsp;<br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;print_trace&nbsp;(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">array[</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">];&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;size;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">strings;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;i;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;backtrace&nbsp;(array,&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strings&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;backtrace_symbols&nbsp;(array,&nbsp;size);&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Obtained&nbsp;%zd&nbsp;stack&nbsp;frames.\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;size);&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;size;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;strings[i]);&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free&nbsp;(strings);&nbsp;<br>}&nbsp;<br><br></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;A&nbsp;dummy&nbsp;function&nbsp;to&nbsp;make&nbsp;the&nbsp;backtrace&nbsp;more&nbsp;interesting.&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000">&nbsp;<br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;dummy_function&nbsp;(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_trace&nbsp;();&nbsp;<br>}&nbsp;<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main&nbsp;(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dummy_function&nbsp;();&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;<br>}</span></div>
编译运行的结果如下： <br># gcc bt.c -rdynamic -o bt <br># ./bt <br><script src="http://www.upsdn.net/view.php?id=775" type=text/javascript></script>Obtained 5 stack frames.<br>./bt(_Z11print_tracev+0x19) [0x804870d]<br>./bt(_Z14dummy_functionv+0xb) [0x8048779]<br>./bt(main+0x16) [0x8048792]<br>/lib/libc.so.6(__libc_start_main+0xdc) [0x116e9c]<br>./bt(__gxx_personality_v0+0x31) [0x8048641]<br><br><br>注： addr2line - convert addresses into file names and line numbers.<br><br>
<img src ="http://www.cppblog.com/toMyself/aggbug/130963.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/toMyself/" target="_blank">kongkongzi</a> 2010-10-23 09:49 <a href="http://www.cppblog.com/toMyself/archive/2010/10/23/130963.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux signal</title><link>http://www.cppblog.com/toMyself/archive/2010/09/30/128136.html</link><dc:creator>kongkongzi</dc:creator><author>kongkongzi</author><pubDate>Thu, 30 Sep 2010 07:42:00 GMT</pubDate><guid>http://www.cppblog.com/toMyself/archive/2010/09/30/128136.html</guid><wfw:comment>http://www.cppblog.com/toMyself/comments/128136.html</wfw:comment><comments>http://www.cppblog.com/toMyself/archive/2010/09/30/128136.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/toMyself/comments/commentRss/128136.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/toMyself/services/trackbacks/128136.html</trackback:ping><description><![CDATA[<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;sig_handler(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;signo);<br><br><br></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;sigaction&nbsp;sact;<br><br>sigemptyset(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sact.sa_mask);<br><br>sact.sa_flags&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>sact.sa_handler&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sig_handler;<br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;for&nbsp;handle&nbsp;crash</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">sigaction(SIGSEGV,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sact,&nbsp;NULL);<br>sigaction(SIGABRT,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sact,&nbsp;NULL);<br>sigaction(SIGBUS,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sact,&nbsp;NULL);<br><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;for&nbsp;handle&nbsp;kill</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">sigaction(SIGINT,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sact,&nbsp;NULL);<br>sigaction(SIGTSTP,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sact,&nbsp;NULL);<br>sigaction(SIGTERM,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">sact,&nbsp;NULL);<br></span></div>
<br><br><br>
<img src ="http://www.cppblog.com/toMyself/aggbug/128136.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/toMyself/" target="_blank">kongkongzi</a> 2010-09-30 15:42 <a href="http://www.cppblog.com/toMyself/archive/2010/09/30/128136.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>