D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4181 - GDB prints wrong value of TLS variables
Summary: GDB prints wrong value of TLS variables
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Linux
: P2 normal
Assignee: Iain Buclaw
URL:
Keywords: bounty, DebugInfo, pull
Depends on:
Blocks: 4044
  Show dependency treegraph
 
Reported: 2010-05-12 14:51 UTC by Mihail Zenkov
Modified: 2015-06-09 05:10 UTC (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Mihail Zenkov 2010-05-12 14:51:01 UTC
GDB print strange value if source compiled with dmd -g (with dmd -gc it print correct value).

# cat test.d
import std.stdio: writefln;

int x;

struct STest {
        static int y;
}

void dummy() {}

int main() {
        x = 11;
        STest.y = 22;
        writefln("x=%d STest.y=%d", x, STest.y);
        dummy();

        return 0;
}


# dmd -g test.d
# gdb test
GNU gdb (GDB) 7.1.50.20100430-cvs
Copyright (C) 2010 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 "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /mnt/work/source/dgdb/test1/test...done.
(gdb) break 'test.dummy'
Breakpoint 1 at 0x8049a94: file test.d, line 9.
(gdb) run
Starting program: /mnt/work/source/dgdb/test1/test
[Thread debugging using libthread_db enabled]
x=11 STest.y=22

Breakpoint 1, test.dummy () at test.d:9
9       void dummy() {}
(gdb) p 'test.x'
$1 = 11
(gdb) p 'test.STest.y'
$2 = 11

I also have more complex example that have p 'test.x' incorrect too.
Comment 1 Martin Krejcirik 2012-04-04 14:18:58 UTC
I should add to this report, that all thread-local variables are shown with wrong value (init value instead of changed value) in gdb (tested gdb 7.3, 7.4, dmd 2.058) when compiled with -g.
Comment 2 Andrei Alexandrescu 2014-01-10 17:45:09 UTC
placed $50 bounty
Comment 3 Iain Buclaw 2014-01-12 02:36:32 UTC
(In reply to comment #2)
> placed $50 bounty

Something is completely fudged with -g in DMD.

Just doing a cursory check on 2.064:

(gdb) p 'test.STest.y'
Cannot access memory at address 0x736574050065b510
(gdb) p 'test.x'
Cannot access memory at address 0x34445f040065b510


Cannot reproduce with -gc, and of course, GDC is just fine.

Personally I would like to see -gc deprecated and all features of -gc moved over to -g, excluding the setting of DW_LANG_C89.
Comment 4 Benjamin Thaut 2014-01-12 03:13:51 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > placed $50 bounty
> 
> Something is completely fudged with -g in DMD.
> 

I also noticed that debugging seemed to work better with dmd 2.063.2 (but on Windows)

> 
> Personally I would like to see -gc deprecated and all features of -gc moved
> over to -g, excluding the setting of DW_LANG_C89.

Please no. Under windows -g works fine and I really don't want the debug information to look like C code. If this is done please make it unix only.
Comment 5 Iain Buclaw 2014-01-12 03:26:48 UTC
(In reply to comment #4)
> 
> Please no. Under windows -g works fine and I really don't want the debug
> information to look like C code. If this is done please make it unix only.

I'd hate to be the barer of bad news, but -g and -gc have been nearly identical for quite a few years now.  Here's the current score.

1) The difference between -g and -gc on Windows is dchars are represented as ulong (determined by a quick grep of 'symdebug' over the glue code.  Windows debug format is either CV4 or CV8.

2) The difference between -g and -gc on Linux is DW_LANG_D vs DW_LANG_C89 (determined by diff'ing a objdump -g of two compiled objects).

So whatever misconception you have of -gc, it is wrong and this attitude should be dropped.


I can't imagine things breaking on Windows deprecating -gc and removing (1) so that dchar is *always* represented as dchar.

As for (2) something is sorely broken on Linux if DW_LANG_D is specified vs DW_LANG_C89.  This may not be a problem for GDC perhaps because it emits DW_OP_GNU_tls_address against the TLS symbols.  But it's still no excuse for GDB to break debugging when this is missing.
Comment 6 Benjamin Thaut 2014-01-12 03:56:32 UTC
> 
> So whatever misconception you have of -gc, it is wrong and this attitude should
> be dropped.


If its really that similar I'm fine with dropping it. I just wanted to point out the windows side of things, as those are often forgotten in den D-Community in general.
Comment 7 Iain Buclaw 2014-01-12 04:54:06 UTC
(In reply to comment #5)
 
> If its really that similar I'm fine with dropping it. I just wanted to point
> out the windows side of things, as those are often forgotten in den D-Community
> in general.

Anyway, I'm not promoting 'pretend we're C' behaviour.  I'm in favour of killing 'pretend we're C' behaviour.

There was a time where DMD would emit a delegate as a ulong in debug code, and have it's own custom DWARF tags for D arrays, etc.  This is no longer the case.
Comment 8 Iain Buclaw 2014-01-12 06:25:52 UTC
(In reply to comment #5)
> 
> As for (2) something is sorely broken on Linux if DW_LANG_D is specified vs
> DW_LANG_C89.  This may not be a problem for GDC perhaps because it emits
> DW_OP_GNU_tls_address against the TLS symbols.  But it's still no excuse for
> GDB to break debugging when this is missing.

Problem seems to be in GDB itself, and not DMD.  This is something that I'll check is fixed once I finish up writing the D expression parser.
Comment 9 Iain Buclaw 2014-01-20 10:04:04 UTC
I believe this should be now fixed in my local copy of gdb.  I've got a few more things to do including:

- Get line completion working without 'quotes'
- Implement .sizeof property keeping sizeof(T) for gdb compatibility.
- Recognise 'cast(T)' whilst keeping C-style casts for gdb compatibility.

Oh Ho!
Comment 10 Iain Buclaw 2014-01-20 22:53:11 UTC
Yep, this is now working for DMD in my local copy of gdb. :)

Will probably take me about a week to finalise some patches to send off (anyone wanting to help test is more than welcome).
Comment 11 Andrei Alexandrescu 2014-01-22 13:48:07 UTC
Awesome, keep us posted.
Comment 12 Iain Buclaw 2014-01-23 00:11:33 UTC
Will do.
Comment 13 Martin Nowak 2014-03-13 07:57:45 UTC
(In reply to comment #7)
> There was a time where DMD would emit a delegate as a ulong in debug code, and
> have it's own custom DWARF tags for D arrays, etc.  This is no longer the case.

Yeah, I removed most of these differences and replaced them with structs. Some of them are recognized by the rotten D support in gdb.
But it would be much nicer to use DWARF-4 for array types.
Comment 14 Martin Krejcirik 2014-10-07 23:30:01 UTC
https://github.com/D-Programming-Language/dmd/pull/4053
Comment 15 Martin Krejcirik 2014-10-08 23:04:45 UTC
Note: if, with the above pull, you experience high tls offset like this:

(gdb) p _D4test1xi
Cannot access memory at address 0x7ffff8434e50
(gdb) info address _D4test1xi
Symbol "test.x()" is a thread-local variable at offset 0x45e6f0 in the thread-local storage for `/home/dawg/Code/D/test'.

It may be caused by ld.gold linker during program build time. Use ld.bfd.
Comment 16 github-bugzilla 2014-10-10 00:39:30 UTC
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/aa9812bef7e8aadb1495c474f7587f8481077ab8
Fix Issue 4181 - GDB prints wrong value of TLS variables

- add DWARF_VERSION to dwarf.h
- emit DW_OP_GNU_push_tls_address or DW_OP_form_tls_address based on DWARF_VERSION

https://github.com/D-Programming-Language/dmd/commit/11842652cdc58f479590af618c79335ba44af03f
Merge pull request #4053 from tramker/bug4181

Fix Issue 4181 - GDB prints wrong value of TLS variables
Comment 17 Brad Roberts 2014-10-10 01:16:25 UTC
I believe we'd gotten the dmd codegen and debug gen to the point that ld.gold was happy.  This fix is incomplete as long as ld.gold isn't happy.  It should either be re-opened or a followup ld.gold specific bug filed.  imho.
Comment 18 Martin Krejcirik 2014-10-10 01:26:43 UTC
I think it's a bug in ld.gold which has been fixed recently:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=5efeedf61e4fe720fd3e9a08e6c91c10abb66d42
Comment 19 Brad Roberts 2014-10-10 01:29:11 UTC
Can you confirm?  Either way, thanks for the research.
Comment 20 Martin Krejcirik 2014-10-10 13:55:35 UTC
Yes, I can confirm it works on Fedora 20 x86_64 with ld.gold from git (GNU Binutils 2.24.51.20141010). Debian wheezy seems not affected.
Comment 21 Martin Nowak 2014-10-10 15:23:54 UTC
I didn't had any problems with this patch and my default ld.gold (2.23.2) version.
Also the linked binutils issue seems unrelated.
Comment 22 Martin Krejcirik 2014-10-10 16:13:03 UTC
I did find out. My original patch din't work with the stock (2.23.2) ld.gold.
Merged version is not affected. So all is well.
Comment 23 Iain Buclaw 2014-10-11 05:47:05 UTC
Just a note from my side (as I've been silent on this).

Further changes in GDB instead re-exposed this bug.  I had looked at the area PR fixed, and while I could see in the codegen what the dmd backend was doing wrong, I do not have the time to figure out how to make dmd more conformant.
Comment 24 Martin Krejcirik 2014-10-11 12:40:29 UTC
Can you elaborate ? I've tried gdb 7.8.50.20141011-cvs on Debian x86_64 and it doesn't seem broken.
Comment 25 Iain Buclaw 2014-10-11 12:49:01 UTC
> Can you elaborate ? I've tried gdb 7.8.50.20141011-cvs on Debian x86_64 and it doesn't seem broken.

In response to my own Comment 10.