gdb在使用__thread时优化了值

时间:2017-05-22 14:23:55

标签: c debugging gdb c11

在调试中,我希望观察变量的值时,所有static __thread值显示为<optimized out>;即使使用-o0和/或volatile

Static没有__thread的变量显示正确。

即使我正在使用线程,还是要显示变量的值吗?

使用Win10(CreateThread),eclipse CDT,c11,mingw64-w64和gdb 7.11.1

1 个答案:

答案 0 :(得分:0)

解决方法可能是:在代码中添加一些线程局部变量的打印机,然后让gdb调用它们。 (或者,如果您熟悉x86程序集,请编写一些hackish插件来修改可执行内存以读取fs:offset / gs:offset(线程局部变量值)并恢复内存和寄存器)

更具体地说,向C代码添加一个函数,它只返回有趣的__thread变量,当你使用gdb中断程序时,你可以随时让gdb为你调用该函数(假设在不破坏原始程序的堆栈帧的情况下,该功能未被优化)。它应该像以下一样简单:

(gdb) p rand()
$1 = 1804289383
(gdb) p rand()
$2 = 846930886
(gdb) p rand()
$3 = 1681692777

虽然rand不是一个很好的例子,因为它有副作用。 TLS变量读取没有副作用。

示例:(在Ubuntu 16.04下,但由于功能非常基础,因此事情应该没有太大区别)

tls.cpp:

#include <stdio.h>

__thread long thread_cand;

long what_is_thread_cand()
{
    return thread_cand;
}

int main()
{
    while ( !feof ( stdin ) )
    {
        scanf ( "%ld", &thread_cand );
        printf ( "%p : %ld\n", &thread_cand, thread_cand );
    }
    return 0;
}

终端:

$ g++ -O2 -g3 tls.cpp -o tls
tls.cpp: In function ‘int main()’:
tls.cpp:14:38: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
         scanf ( "%ld", &thread_cand );
                                      ^
$ gdb tls --nh
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from tls...done.
(gdb) r
Starting program: /home/ubuntu/tls 
123
0x7ffff7fcb6f8 : 123
432
0x7ffff7fcb6f8 : 432
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7b04230 in __read_nocancel ()
    at ../sysdeps/unix/syscall-template.S:84
84  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) p thread_cand
Cannot find thread-local storage for process 6472, executable file /home/ubuntu/tls:
Cannot find thread-local variables on this target
(gdb) p what_is_thread_cand() 
$1 = 432
(gdb)