Linux学习----gdb调试(留了一个暂时没解决的问题,大佬们来看看是什么问题)

 昨天遇到一个很奇怪的问题,如下:

按照理论,最后*p的值应该是99,不知为什么是15了,所以今天记录用gdb调试的过程,并熟悉gdb的使用。

开始:

1.

2.(用list从第1行开始列出源码)

3.(一次只列10行,如果要从第11行开始继续列源代码可以输入list)

4.(也可以什么都不输直接敲回车,gdb提供了一个很方便的功能,在提示符下直接敲回车表示重复上一条命令。)

5.(gdb的很多常用命令有简写形式,例如list命令可以写成l,要列一个函数的源代码也可以用函数名做参数:)

6.(退出gdb环境)

7.(现在将niuke.cpp改名,然后gdb就列不出源码了)

说明:gcc-g选项并不是把源代码嵌入到可执行文件中的,在调试时也需要源文件。

8.(源码文件恢复,重新开始)

gdb停在main函数中变量定义之后的第一条语句处等待我们发命令,gdb列出的这条语句是即将执行的下一条语句。

9.(我们可以用next命令(简写为n)控制这些语句一条一条地执行)

说明:用n函数f()中的结果一下就打印出来了

 10.(现在用start重新开始,用step命令(简写s)进入f()中去跟踪执行)

现在进入了f()函数。

 11.(在函数中有几种查看状态的办法,backtrace命令(简写为bt)可以查看函数调用的栈帧)

可见当前f()是被main()调用的,传入指针p传给ret=0xbfffee94

12.(查看当前f()函数内局部变量的值i locals 或者info locals)

13.(如果想查看main函数当前局部变量的值也可以做到,先用frame命令(简写为f)选择1号栈帧然后再查看局部变量,i locals, info locals)

 

14.(继续运行,然后用p+变量名查看变量的值)

 

这里......$5,$6,$7,$8......分别保存了查看的中间值:

未执行*ret = &a时:

ret: 0xbfffee94(为&p)  *ret:0xbfffef54(p)  **ret:-1073745577

执行*ret = &a后:

ret: 0xbfffee94  *ret:0xbfffee68 = &a:0xbfffee68(值为99)  **ret:99(等于a)

15.(finish命令让程序一直运行到当前函数结束) 

返回值是ret=0xbfffee94(&p)

16.(现在继续运行)

注意:A &p address : 0xbfffee94(&p未改变)  A p address : 0xbfffee68(与&a相同)  A *p value   : 15(奇怪的地方,为什么不是99)

17.(换一种思路:在执行 cout << "A &p address : " << &p << endl; 之前直接查看*p)

 

这里可以看到*p=99,是正确的,地址也与上面相同

18.(继续调试)

这里发现*p=15,被改变了。

 也就是说:在执行cout << "A &p address : " << &p << endl;后, *p的值被改变了,从99变为15了。

 19.(注释掉输出&p和p两行再次执行)

 

这次发现结果正确了,那为什么呢?为什么呢?????

20.(用printf实验)

 

与注释输出&p,p两行的结果对比:

结果也会出现上面的问题,but,why??????

我猜问题应该与输出函数cout和printf还有缓冲区有关,这个问题。待解决吧。。

猜你喜欢

转载自www.cnblogs.com/Brickert/p/10740856.html