当前位置:首页 > 嵌入式linux应用程序调试方法
Remote debugging using 172.16.51.143:15000 ……
0x40002a90 in ??()
同时在连接目标版的串口输出中出现以下提示:
Remote debugging from host 172.16.51.130
回到linux服务器,gdb等待输入命令。 (gdb)
连接成功,这时候就可以输入各种gdb命令如list、run、next、step、break等进行程序调试了。 这个时候就可以利用gdb进行调试了。
四 内存工具
您肯定不想陷入类似在几千次调用之后发生分配溢出这样的情形。
许多小组花了许许多多时间来跟踪稀奇古怪的内存错误问题。应用程序在有的开发工作站上能运行,但在新的产品工作站上,这个应用程序在调用 malloc() 两百万次之后就不能运行了。真正的问题是在大约一百万次调用之后发生了溢出。新系统之所有存在这个问题,是因为被保留的 malloc() 区域的布局有所不同,从而这些零散内存被放置在了不同的地方,在发生溢出时破坏了一些不同的内容。
我们用多种不同技术来解决这个问题,其中一种是使用调试器,另一种是在源代码中添加跟踪功能。在我职业生涯的大概也是这个时候,我便开始关注内存调试工具,希望能更快更有效地解决这些类型的问题。在开始一个新项目时,我最先做的事情之一就是运行 MEMWATCH 和 YAMD,看看它们是不是会指出内存管理方面的问题。
内存泄漏是应用程序中常见的问题,不过您可以使用本文所讲述的工具来解决这些问题。
内存调试工具
C 语言作为 Linux 系统上标准的编程语言给予了我们对动态内存分配很大的控制权。然而,这种自由可能会导致严重的内存管理问题,而这些问题可能导致程序崩溃或随时间的推移导致性能降级。
内存泄漏(即 malloc() 内存在对应的 free() 调用执行后永不被释放)和缓冲区溢出(例如对以前分配到某数组的内存进行写操作)是一些常见的问题,它们可能很难检测到。这一部分将讨论几个调试工具,它们极大地简化了检测和找出内存问题的过程。
4.1 MEMWATCH
MEMWATCH 由 Johan Lindh 编写,是一个开放源代码 C 语言内存错误检测工具,您可以自己下载它(请
参阅本文后面部分的参考资料)。只要在代码中添加一个头文件并在 gcc 语句中定义了 MEMWATCH 之后,您就可以跟踪程序中的内存泄漏和错误了。MEMWATCH 支持 ANSI C,它提供结果日志纪录,能检测双重释放(double-free)、错误释放(erroneous free)、没有释放的内存(unfreed memory)、溢出和下溢等等。
? 快速上手:
在MEMWATCH的源代码包中包含有三个程序文件:memwatch.c, memwatch.h, test.c; 可以利用这三个程序,按照你的编译环境对makefile修改后,就可是简单使用memwatch来检测test.c这个文件中的内存问题;
当然你可以根据自己的需要修改test.c文件,不过需要注意的是:
1)如果你的程序是永远不会主动退出的话,建议深入看看memwatch,因为memwatch默认情况下,在程序退出的时,将有关内存检测的结果写入到某个日志文件中;所以针对你永远不会退出的程序,你需要自己动手调用MEMWATCH的结果函数。
2)如果你要使用memwatch来检测内存问题的话,必须将memwatch.h头文件包含在你需要检测文件中;并且把memwatch.c加入编译。在编译时记得加-DMEMWATCH -DMW_STDIO选项;在主文件中最好包含以下信息,
//在linux下需要包含signal.h这个头文件
#ifndef SIGSEGV
#error \#endif
//防止你在编译时没有加 -DMEMWATCH #ifndef MEMWATCH
#error \#endif
//防止你在编译时候没有加 -DMEMWATCH_STDIO,在一些指针错误的时候,会弹出 //Abort/Retry/Ignore 让你选择处理方法。
#if !defined(MW_STDIO) && !defined(MEMWATCH_STDIO) #error \#endif
//多线程程序需要定义MW_PTHREADS,虽然它并不一定能够保证多线程安全,zpf #if !defined(MW_PTHREADS) && !defined(HAVE_PTHREAD_H) #error \#error \#endif
3)刚开始还是找一个简单的单线程程序来上手吧?.
? 样例讲解
清单 1. 内存样本(test1.c) #include
现在我们编译清单 1 的 memwatch.c。下面是一个 makefile 示例: test1 gcc -DMEMWATCH -DMW_STDIO test1.c memwatch c -o test1 当您运行 test1 程序后,它会生成一个关于泄漏的内存的报告。清单 2 展示了示例 memwatch.log 输出文件。
清单 2. test1 memwatch.log 文件
MEMWATCH 2.67 Copyright (C) 1992-1999 Johan Lindh ... double-free: <4> test1.c(15), 0x80517b4 was freed from test1.c(14) ... unfreed: <2> test1.c(11), 512 bytes at 0x80519e4 {FE FE FE FE FE FE FE FE FE FE FE FE ..............} Memory usage statistics (global): N)umber of allocations made: 2 L)argest memory usage : 1024 T)otal of all alloc() calls: 1024
U)nfreed bytes totals : 512 MEMWATCH 为您显示真正导致问题的行。如果您释放一个已经释放过的指针,它会告诉您。对于没有释放的内存也一样。日志结尾部分显示统计信息,包括泄漏了多少内存,使用了多少内存,以及总共分配了多少内存。
建议:
建议在你需要测试的主文件中加入以下函数信息 //在linux下需要包含signal.h这个头文件 #ifndef SIGSEGV #error \#endif //防止你在编译时没有加 -DMEMWATCH #ifndef MEMWATCH #error \#endif //防止你在编译时候没有加 -DMEMWATCH_STDIO,在一些指针错误的时候,会弹出 //Abort/Retry/Ignore 让你选择处理方法。 #if !defined(MW_STDIO) && !defined(MEMWATCH_STDIO) #error \#endif //多线程程序需要定义MW_PTHREADS,虽然它并不一定能够保证多线程安全,zpf #if !defined(MW_PTHREADS) && !defined(HAVE_PTHREAD_H) #error \#error \#endif
另外需要说明的是,在源代码附带的<
MEMWATCH程序使用中通过简单的加入memwatch.h头文件,并且将memwatch.c加入编译,就可以在程序正常结束的时候,输出日志文件,在日志文件中给出系统中的内存问题;但是有一个问题,在我们的终端中应用程序是永远不会退出的,并且可能系统根本就没有充分考虑良好的收尾工作;那么如果使用MEMWATCH来检测我们的程序是否存在内存问题哪?
? 仔细阅读memwatch.h文件会发现,MEMWATCH提供了两个比较有用的函数: void mwInit( void ); void mwTerm( void );
共分享92篇相关文档