Linux程序崩溃(segment fault)原因的调试 gdb, valgrind

来源:互联网 发布:ntt数据英特玛 编辑:程序博客网 时间:2024/05/23 16:08
 主要有两种方法:
一是用gdb,二是用valgrind

-----------------
 一个有错误的 C 源程序 bugging.c 代码:

-----------------
static char buff [256];
static char* string;
int main ()
{
  printf ("Please input a string: ");
  gets (string);  
  printf ("/nYour string is: %s/n", string);
 }

-----------------
  上面这个程序非常简单,其目的是接受用户的输入,然后将用户的输入打印出来。该程序使用了一个未经过初始化的字符串地址 string,因此,编译并运行之后,将出现 Segment Fault 错误:
$ gcc -o bugging -g bugging.c
$ ./bugging
Please input a string: asfd
Segmentation fault (core dumped)
为了查找该程序中出现的问题,我们利用 gdb,并按如下的步骤进行:
1.运行 gdb bugging 命令,装入 bugging 可执行文件;
2.执行装入的 bugging 命令 run;
3.使用 where 命令查看程序出错的地方;
4.利用 list 命令查看调用 gets 函数附近的代码;
5.唯一能够导致 gets 函数出错的因素就是变量 string。用print命令查看 string 的值;
6.在 gdb 中,我们可以直接修改变量的值,只要将 string 取一个合法的指针值就可以了,为此,我们在第8行处设置断点 break 8;
7.程序重新运行到第 8行处停止,这时,我们可以用 set variable 命令修改 string 的取值;
8.然后继续运行,将看到正确的程序运行结果。


还有一个专用工具valgrind ,专门用来检查c++内存泄漏等问题,http://valgrind.org/

以下是valgrind --leak-check=yes ./UserStatsControl的输出:

UserStatsControl[14440]: userCollectD connected(20.38): 192.168.14.11
==14440== Invalid read of size 4
==14440== at 0x402C470: SP_EventCallback::onRead(int, short, void*) (speventcb.cpp:106)
==14440== by 0x400D53F: event_base_loop (event.c:315)
==14440== by 0x402E3EC: SP_Server::start() (spserver.cpp:236)
==14440== by 0x402DF16: SP_Server::eventLoop(void*) (spserver.cpp:118)
==14440== by 0x402DEF0: SP_Server::runForever() (spserver.cpp:109)
==14440== by 0x804BB32: main (UserStatsControl.cpp:71)
==14440== Address 0x63373C8 is 0 bytes inside a block of size 8 free'd
==14440== at 0x400518E: operator delete(void*) (vg_replace_malloc.c:246)
==14440== by 0x4029AEE: SP_DefaultMsgDecoder::~SP_DefaultMsgDecoder()

(spmsgdecoder.cpp:29)
==14440== by 0x402ACFF: SP_Request::setMsgDecoder(SP_MsgDecoder*) (sprequest.cpp:31)
==14440== by 0x804C065: UserStatsHandler::start(SP_Request*, SP_Response*)

(UserStatsHandler.cpp:22)
==14440== by 0x402D5FE: SP_EventHelper::start(void*) (speventcb.cpp:472)
==14440== by 0x402AEF0: SP_SimpleTask::run() (spexecutor.cpp:56)
==14440== by 0x402B501: SP_Executor::worker(void*) (spexecutor.cpp:158)
==14440== by 0x40280DE: SP_ThreadPool::wrapperFunc(void*) (spthreadpool.cpp:154)
==14440== by 0x38E370: start_thread (in /lib/tls/libpthread-2.3.4.so)
==14440== by 0x2F8FFD: clone (in /lib/tls/libc-2.3.4.so)
pure virtual method called
terminate called without an active exception
原创粉丝点击