1. 内存检查
实际开发中经常出现的问题是内存泄漏,用开源的代码加入检测一下是个很实用的方法
比如用memwatch,它简单适用,只需要memwatch.h和memwatch.c两个文件加入源代码编译;另外记得需要检测的*.c加入memwatch.h这个头文件;最后编译选项加入MEMWATCH。重新编译代码,在memwatch.c目录下产生memwatch.log文件:
============= MEMWATCH 2.71 Copyright (C) 1992-1999 Johan Lindh =============
Started at Wed Jan 28 21:50:56 2008
Modes: __STDC__ 32-bit mwDWORD==(unsigned long)
mwROUNDALLOC==4 sizeof(mwData)==32 mwDataSize==32
Stopped at Wed Jan 28 21:51:59 2008
unfreed: <1> main.c(371), 8192 bytes at 0x805f7fc {00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................}
Memory usage statistics (global):
N)umber of allocations made: 1
L)argest memory usage : 8192
T)otal of all alloc() calls: 8192
U)nfreed bytes totals : 8192
上面log文件指出,在main.c被执行到第371行时所分配的内存仍未被释放,该段内存的大小为8192byte,查看第371行代码
char *commandBuf=(char *)malloc(MAX_INPUT_LEN);
这里没有释放,需要添加代码free。
2. Crash
另外一个问题就是系统crash问题,这个可以利用gdb连接到调试目标板上,当crash的时候用bt看栈信息;但是推荐在代码中直接利用加sigsegv.c和sigsegv.h,另外在main函数中加调用setup_sigsegv();即可,下面是写的一个测试crash函数,因为die函数中NULL指针赋值了,运行main的时候会直接挂掉的
......
/*
* Function: die
* Purpose: test for backtrace
* Arguments:
* Returns:
*/
int die()
{
char *err = NULL;
strcpy(err, "die");
return 0;
}
/*
* Function: main
* Purpose:
* Arguments:
* Returns:
*/
int main(int argc, char* argv[])
{
int rc;
pthread_t pid;
pthread_t pid_server;
setup_sigsegv();
rc = pthread_create(&pid, NULL, (void *) &dbg_entry, NULL);
if (rc < 0)
printf("error:%s/n", strerror(rc));
rc = pthread_create(&pid_server, NULL, (void *) &dbg_server1,
(void *) "/var/dbg.ipc");
if (rc < 0)
printf("error:%s/n", strerror(rc));
die();
while (1);
return 0;
}
这里是挂掉后打印出来的信息,在地址0x8049f49的地方挂掉的,此函数运行结束后PC的地址是0x8049fd9,
### BEGIN LOG - DATE: 081025, TIME: 145642 ###
./debug
Segmentation Fault!
info.si_signo = 11
info.si_errno = 0
info.si_code = 1 (SEGV_MAPERR)
info.si_addr = (nil)
reg[00] = 0x00000033
reg[01] = 0x00000000
reg[02] = 0x0000007b
reg[03] = 0x0000007b
reg[04] = 0xbffdd670
reg[05] = 0xbffdd6e4
reg[06] = 0xbffdd638
reg[07] = 0xbffdd638
reg[08] = 0x00d25ff4
reg[09] = 0x00000000
reg[10] = 0xb75df4c4
reg[11] = 0x00000000
reg[12] = 0x0000000e
reg[13] = 0x00000006
reg[14] = 0x08049f49
reg[15] = 0x00000073
reg[16] = 0x00010246
reg[17] = 0xbffdd638
reg[18] = 0x0000007b
Stack trace:
1: 0x8049f49 <(null)+134520649> (./debug)
2: 0x8049fd9 <(null)+134520793> (./debug)
3: 0xc15e23 <__libc_start_main+211> (/lib/tls/libc.so.6)
End of stack trace
[huangyonggang@localhost bin.x86]$
### END LOG - DATE: 081025, TIME: 145652 ###
于是
反汇编[huangyonggang@localhost bin.x86]$ objdump -D debug &>log
或者[huangyonggang@localhost bin.x86]$ strace debug &>log1
可以得到后面的,根据上面的栈信息,可以找到8049f49地址就是挂掉的位置,这里就是die函数中的串拷贝,接着找8049fd9地址,就是die函数结束后PC的地址
......
08049f46 <die>:
8049f46: 55 push