linux程序调试补充(gdb ) (2)
来源:互联网 发布:机打收据软件 编辑:程序博客网 时间:2024/06/12 20:44
http://blog.chinaunix.net/uid-21123336-id-1830540.html
后来一段时间,对linux下的程序调试有了一些新的认识,所以补充出了这一篇,前一篇文章可以查看这里 Linux下程序的调式(gdb) 。
后来一段时间,对linux下的程序调试有了一些新的认识,所以补充出了这一篇,前一篇文章可以查看这里 Linux下程序的调式(gdb) 。
1 gdb,快速高效,功能强大,相对操作复杂。
2 DDD,gdb图形前端,提供了比gdb更好的界面操作,直观的界面,更友好的鼠标操作之类。同时保留了gdb的命令行终端。
3 eclipse,界面更加完善,对用户友好的功能丰富,够多的傻瓜式操作。操作简单,但一些功能可能没有提供操作接口。(据说可以直接启用gdb线程在终端下操作)。
二 gdb的几则使用
1 watchpointer [(条件)]/变量名,观察点,在设置的变量(或者是条件)发生时,中断执行(据说在大型循环内部,基于条件的观察点可能导致调试器很慢)。使用如:
gdb>watch (num >30) #当num的值大于30时中断
2 frame,切换当前执行栈(即函数栈),一般编号0为当前执行栈,它的父调用函数栈依次为1,2...,使用下面的命令,可以切换想要查看的栈空间,但该操作不会改变进程的执行序列。
gdb>frame 栈编号
3 continue,继续执行到下一个断点(或者到程序结束)。
三 信号与段错误
1 segment fault(段错误),一般是因为进程访问了非法内存地址,操作系统为了保护系统会中断该进程的执行,但不是所有的非法内存访问会导致段错误
1)内存管理的基本单元是页,所以访问权限也是以页为单位来标识的,那么有些情况,一些操作虽然已经访问了允许之外的内存空间,但因为该页对它具有访问权限,所以不会发生错误。
2)非法访问内存应该是说进程访问了超出它访问权限之外的内存空间,比如访问了内核保护空间等其他,但还有一种情况(我个人以为):就是进程对自身内存空间管理不善,导致一些内存区域被不正常的操作改写,丢失数据(此情况也可能是一些恶意的人为因素)。那么这种情况,内存管理系统是不可能探知到的,也更不会出现什么段错误之类,这个可能只能由用户自己小心严谨编程来保证可靠性。
所以没有发生段错误,不表示内存操作没有错误。断错误实质是默认的信号处理操作对SIGSEGV信号响应的结果。
2 signal(信号),一般系统会给我们的程序实现好了一套默认的信号处理函数,如段错误信号(SIGSEGV)发生时直接报错退出,中断信号(SIGINT,Ctrl+c操作对应)发生时中断运行,一些特殊情况下当需要特殊的信号处理操作时,可以使用signal函数搞定,signal函数符合POSIX规范,具体使用可以参考man手册。有一个特殊的现象:我试着使用下面的代码把段错误的处理函数定义为空:
signal(SIGSEGV, NULL);
执行程序后段错误发生时,程序报错”segment fault“并退出。
当修改SIGSEGV信号响应处理函数为自定义的非空函数时,该函数被反复调用执行执行,即程序不再继续执行。貌似这是系统为保证程序的可靠性和安全性而作了强制限制。
四 一些其他调试思路
功能调用跟踪调试,对于一些无法依附源码调试的软件,可以借助strace和ltrace工具来跟踪程序执行时的大概行为,strace可以跟踪每一个系统调用的详细情况,包括调用名,传递的参数和返回值。ltrace与strace类似,不同的是它用来跟踪库的调用情况。
其他内容:
1) 实际测试发现在不同的linux版本下(gcc版本不同),未赋值的指针值不确定,有些为NULL,而有些则为随机值。
五 数据内存存储
1 经测试intel e8400 cpu平台,linux 2.18 x86_64系统下,存储类型为小端存储,即数值位的低位存在内存较低的位置,高位存储在高位。
如:int num=0x1122;
实际内存情况是
0x***001 -- 0x22
0x***002 -- 0x11
2 数值存储形式
数值以补码形式存储,32位机上,数值与内存形式对应表如下:
int 1 0x00000001
int 0 0x00000000
int -1 0x11111111
int 100 0x00000064
3 非零值在c中表示真值。
TRUE,FALSE本质上是一个预处理宏,使用时需要小心。
六 gdb多进程调试方法
1 使用attach命令把gdb附加的目标进程,无参数启动gdb,使用attach命令后加pid的方式完成附加,如果你有该程序调试符号表文件,也可以使用file命令附加,这样就可以像正常调试一样操作了。调试完成后使用detach命令解除附加,使目标进程恢复正常允许。
2 较新版的gdb已经开始简单支持多进程调试了(貌似依赖于内核版本),通常在fork一个新进程后,gdb默认跟踪父进程往下执行,不会管子进程的存在。新的支持多进程的gdb可以使用set follow_fork_mode parent/child命令指定gdb在fork执行之后follow那个进程。
3 gdb warpper,没有试过,不了解。
参考:
使用 GDB 调试多进程程序 田 强 (tianq@cn.ibm.com), IBM中国软件开发中心
http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/index.html
- linux程序调试补充(gdb ) (2)
- gdb调试(待)补充
- linux GDB调试程序
- gdb 调试 linux程序
- Linux GDB调试++程序
- linux gdb调试程序
- Linux编程基础2 GDB程序调试
- linux GDB调试程序(一)
- linux用gdb调试程序(转载)
- gdb调试程序2
- Linux下gdb调试程序
- Linux下gdb调试程序
- gdb 调试linux c程序
- linux下gdb调试程序
- 【Linux学习】GDB程序调试
- linux GDB调试c++程序
- gdb调试linux可执行程序
- linux gdb调试程序 - 信号
- struts学习笔记6
- qlikview的整体操作
- NAnt与MSBuild使用(一)
- redo 和 undo 之四
- linux串口编程 非规范模式 read()问题
- linux程序调试补充(gdb ) (2)
- 抽象方法与接口
- win7+cuda4.1+VS2008配置
- 《Linux设备驱动程序》学习2—高级字符设备驱动ioctl
- javascript 怎样才能确定参数变量的个数呢?
- C++之面向对象
- typedef
- js中的var(声明局部变量)
- AIDL和远程Service调用