-1

All my static __thread values shown as <optimized out> when, in debugging, I want to watch the value of a variable; even with -o0 and/or volatile.

Static Variables without __thread are shown correctly.

Is there anyway to show the values of the variable even though I'm working with threads?

Using Win10 (CreateThread), eclipse CDT, c11, mingw64-w64 and gdb 7.11.1

Max R.
  • 811
  • 1
  • 13
  • 31
  • gdb is a debugger. Debuggers don't optimise code. – too honest for this site May 22 '17 at 14:36
  • `__thread` variables are in Thread Local Storage, which is in memory referenced with fs/gs segment register in Windows/Linux x86. As far as my linux experience, gdb is not good at viewing TLS variables. (since gdb does not know where TLS resides in linear memory space: gdb cannot view the address value of fs segment register). It would be surprising if in Windows it manage to view TLS. – Thiner Jun 20 '17 at 09:44

1 Answers1

0

A workaround may be: add some printers of thread local variables in your code, and let gdb call them. (Or if you are familiar with x86 assembly, write some hackish plugin to modify the executable memory to read out fs:offset/gs:offset (thread local variable value) and recover the memory & register)

To be more specific, add a function to the C code that does nothing but return the interesting __thread variable, and when you break the program using gdb, you can always make gdb call that function for you (assume that the function is not optimized) without corrupting the stack frame of the original program. it should be as easy as:

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

although rand is not a good example since it has side effect. TLS variable read does not have side effect.

Example: (under Ubuntu 16.04, but things shouldn't have much difference since the functionality is very basic)

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;
}

terminal:

$ 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) 
Thiner
  • 345
  • 1
  • 9
  • Do you mean printfs? I tried that, nevertheless it doesn't work. I helped myself with creating a `#define __debug__thread __thread` which I replaced with all my `__thread` prefixes. When I want to debug I let that define be empty (works in my case, because I debug only with one Client) – Max R. Jun 21 '17 at 11:58
  • I don't know what printfs is.. (I even did not learn/expect that a solution is available on the Internet) However if you know that all `__thread` variable are referenced in x86 by fs:xxh or gs:xxh, and you are familiar enough with the intrinsic of how debugger works, then you can hack and write such a plugin itself; even if you aren't, you can always add some functions in your C code that RETURN the thread local variables, and actually you can let gdb call this function for you and show you the return value. – Thiner Jun 21 '17 at 12:37