GDB读取动态库中定义的全局变量错误
来源:互联网 发布:个人自动发卡平台源码 编辑:程序博客网 时间:2024/06/05 06:23
最近看了一篇getopt使用的文章,为了追踪其执行的逻辑,于是采用GDB挂载调试的方式进行查看。但却出现了GDB打印全局变量optind的时候出现错误。
问题发现和描述
首先optind是使用getopt时候的全局变量,表示使用getopt时候的下一个argv的指针索引。在应用程序调试的时候设置了多个参数,但是随着多次调用getopt,全局变量optind通过gdb打印出来的值却总是1, 但是通过程序打印出来的optind确实是逐步变化的。奇怪了,gdb怎么会有这么明显的bug呢?
于是我在程序中打印出optind的地址为0x600D60.
+++++++++++++++++++++
The optind address is 0x600d60.
+++++++++++++++++++++
那么我们看看gdb打印出来的optind的地址又是多少呢? 如下所示,OMG,他们的地址居然不一样!
+++++++++++++++++++++
(gdb) p &optind
$1 = (int *) 0x3bcfd5210c
+++++++++++++++++++++
问题的探讨
根据多方面的探索,后来查看到,这个涉及到一个“Copy Relocation”的技术。也就是动态库中存在全局变量的时候,在编译阶段已经在程序的.BSS段中预留了控件给动态库中的全局变量,然后当程序初始化的时候,会拷贝动态库中的全局变量到程序预留的.BSS段控件;其他所有的动态库,也将访问通过前面所说的.BSS段中的全局变量来访问原先动态库中定义的全局变量。 具体关于Copy Relocation的机制可以参考文章:http://www.shrubbery.net/solaris9ab/SUNWdev/LLM/p22.html#CHAPTER4-84604
回到原先的问题,那么GDB打印出来并不是程序中.BSS通过Copy Relocation产生的全局变量optind, 而是打印的libc.so中原有的变量的值。
那么怎么打印出正确的值呢?
首先我们通过"Info var optind"查看下optind相关的信息,可以看到两处指名了optind的出处,第一处其实说明了这个是在libc.so中定义的,而gdb默认打印的也是libc.so中定义的,第二处就是之前所说的通过"Copy Relocation"技术存储的optind的实际使用的地址,其地址也是"0x600D60"。
++++++++++++++++++++
(gdb) info var optind
All variables matching regular expression "optind":
File /usr/include/getopt.h:
static int optind;
Non-debugging symbols:
0x0000000000600d60 optind@@GLIBC_2.2.5
++++++++++++++++++++
现在我们就可以通过命令[p 'optind@@GLIBC_2.2.5']打印出实际使用的optind的值。
其实一个简单的问题背后,会隐藏着很多技术和机制。而要真正的明白问题产生的根本原因,目前所掌握的知识还远远不够,楼主一定还需再接再厉。以后还会针对这个问题引申出来的GOT,Copy Relocation等好好的研究研究。
参考
1. gdb does not print right value!
http://www.linuxquestions.org/questions/programming-9/gdb-does-not-print-right-value-908538/
2. optind
https://sourceware.org/ml/gdb/2003-12/msg00160.html
3. Copy Relocation
http://www.shrubbery.net/solaris9ab/SUNWdev/LLM/p22.html#CHAPTER4-84604
4. What's the purpose of copy relocation?
http://stackoverflow.com/questions/26863009/whats-the-purpose-of-copy-relocation
- GDB读取动态库中定义的全局变量错误
- MFC中全局变量的定义
- Android中全局变量的定义
- 动态库中,关于全局变量的调用
- 头文件中定义全局变量出现重定义错误的解决方案
- VC中全局变量的定义和调用
- VC中全局变量的定义和调用
- MFC中定义全局变量的方法
- MFC中全局变量的定义及使用
- MFC中全局变量的定义及使用
- MFC中全局变量的定义及使用
- MFC中全局变量的定义及使用
- Android中定义的路径全局变量
- MFC中全局变量的定义及使用
- MFC中全局变量的定义及使用
- MFC中全局变量的定义及使用
- MFC中全局变量的定义及使用
- MFC中全局变量的定义及使用
- PHP单例模式
- Two Sum —— Leetcode
- SSH的整合,Spring与Hibernate整合,与Struts2整合,ssh整合
- bandwagon支付宝支付教程
- GDI+学习笔记9-绘制网站流量报表
- GDB读取动态库中定义的全局变量错误
- HDU 1402(A * B Problem Plus-FFT速度测试)
- ubuntu下svn每次都要输入密码
- 093 Restore IP Addresses [Leetcode]
- arduino与Processing通信问题
- create geometry from wkt
- J2SE视频总结——回头看,收获!
- 敏捷开发真正的重点不是 User Story 的拆分, 而是开发人员的能力
- 11.7 Matlab 访问文件