为什么gdb出错“optind”变量值?

时间:2016-03-04 03:56:36

标签: c gdb getopt

我正在编写一个使用getopt函数的简单程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{

        char *fname;
        int c;

        printf("Before getopt: optind is %d, address is %p \n", optind, &optind);

        while ((c = getopt(argc, argv, "f:")) != -1)
                switch (c) {
                case 'f':
                        fname = optarg;
                        break;
                }

        printf("After getopt: optind is %d, address is %p \n", optind, &optind);
        return 0;
}

执行它,输出:

# ./test -f 1
Before getopt: optind is 1, address is 0x601040
After getopt: optind is 3, address is 0x601040

但是当使用gdb进行调试时,会发生一些奇怪的事情:

13              printf("Before getopt: optind is %d, address is %p \n", optind, &optind);
(gdb) n
Before getopt: optind is 1, address is 0x601040
15              while ((c = getopt(argc, argv, "f:")) != -1)
(gdb) p &optind
$1 = (int *) 0x7ffff7dd42a0 <optind>
(gdb) n
16                      switch (c) {
(gdb) n
18                              fname = optarg;
(gdb)
19                              break;
(gdb) p &optind
$2 = (int *) 0x7ffff7dd42a0 <optind>
(gdb) p optind
$3 = 1

我可以看到使用p optind命令,它输出1(应为3),此变量地址为0x7ffff7dd42a0,而不是0x601040

使用readelf命令:

# readelf -a test | grep optind
000000601040  000600000005 R_X86_64_COPY     0000000000601040 optind + 0
 6: 0000000000601040     4 OBJECT  GLOBAL DEFAULT   25 optind@GLIBC_2.2.5 (2)
54: 0000000000601040     4 OBJECT  GLOBAL DEFAULT   25 optind@@GLIBC_2.2.5

它还会显示一个optind,其地址应为0x601040。因此,在使用gdb时,为什么它会从optind获得0x7ffff7dd42a0?它是什么?

更新
使用最新的gdb 7.11,并发现此问题已修复。

1 个答案:

答案 0 :(得分:1)

这是一个obscure gdb bug,由另一个名为复制重定位的晦涩功能触发。