Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Issue 4181 - GDB prints wrong value of TLS variables #4053

Merged
merged 2 commits into from Oct 10, 2014

Conversation

tramker
Copy link
Contributor

@tramker tramker commented Oct 7, 2014

https://issues.dlang.org/show_bug.cgi?id=4181

Add DW_OP_GNU_push_tls_address to dwarf debug info for tls vars and also add offset to the address in append_addr() which fixes shared global vars.

I'm novice in dmd and dwarf hacking, so please review thoroughly.

Works for me on Debian wheezy x86 and x86_64, dmd 2.066 and master, gdb 7.8.50.

{
#if ELFOBJ
ElfObj::addrel(seg, offset, R_X86_64_DTPOFF32, MAP_SEG2SYMIDX(targseg), val);
#elif MACHOBJ
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I64 ? R_X86_64_DTPOFF32 : RI_TYPE_TLS_LDO_32

@MartinNowak
Copy link
Member

I want to support newer Dwarf versions at some point.
Could you add a #define DWARF_VERSION 2 in the header and conditionally use the standard TLS op?
http://llvm.org/bugs/show_bug.cgi?id=18423

void dwarf_addrel_tls(int seg, targ_size_t offset, int targseg, targ_size_t val = 0)
{
#if ELFOBJ
ElfObj::addrel(seg, offset, I64 ? R_X86_64_DTPOFF32 : RI_TYPE_TLS_LDO_32, MAP_SEG2SYMIDX(targseg), val);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be R_X86_64_DTPOFF64?

@MartinNowak
Copy link
Member

I still get Cannot access memory at address 0x7ffff8434e50 errors.

@tramker
Copy link
Contributor Author

tramker commented Oct 8, 2014

On Wed, 8 Oct 2014, Martin Nowak wrote:

I still get Cannot access memory at address 0x7ffff8434e50 errors.

What system and gdb version ? What info address 'module.tlsvar' shows ?

@MartinNowak
Copy link
Member

I just broke your pull merging #3814, you simply have to replace the RI_TYPE_ constants with R_386_.

@MartinNowak
Copy link
Member

GNU gdb (GDB) Fedora 7.7.1-19.fc20

(gdb) p 'test.x'
Cannot access memory at address 0x7ffff8434e50
(gdb) p _D4test1xi
Cannot access memory at address 0x7ffff8434e50
(gdb) info address 'test.x'
No symbol "'test.x'" in current context.
(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'.

@MartinNowak
Copy link
Member

The offset 0x45e6f0 is incorrect that is an absolute value of the TLS image, it should be 0x10 I guess.

readelf --segments test

  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  TLS            0x000000000005d6e0 0x000000000045e6e0 0x000000000045e6e0
                 0x0000000000000010 0x0000000000000060  R      10

@tramker
Copy link
Contributor Author

tramker commented Oct 8, 2014

Shouldn't this be R_X86_64_DTPOFF64?

I've tried, but it produces an error (absolute address) similar to your report.

Edit: R_X86_64_DTPOFF32 is a workaround for ld.bfd v2.22. Recent binutils (2.25.51, probably since 2.24) work with R_X86_64_DTPOFF64

@tramker
Copy link
Contributor Author

tramker commented Oct 8, 2014

The offset 0x45e6f0 is incorrect that is an absolute value of the TLS image, it should be 0x10 I guess.

This is caused by ld.gold linker. ld.bfd works, I've tried it on Fedora.

@MartinNowak
Copy link
Member

Sorry for the noise, the problem only happened with R_X86_64_DTPOFF64 instead of R_X86_64_DTPOFF32.

dwarf_addrel(infoseg,infobuf->size(),s->Sseg);
append_addr(infobuf, 0); // address of global
// append DW_OP_GNU_push_tls_address for tls variables
if (s->Sfl == FLtlsdata)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only applies to ELF.
Also there is no need to add all those dwarf_appreladdr_tls functions when they are only used once.
I'd propose this instead.

#if ELFOBJ
            assert(s->Sxtrnnum);
            if (s->Sfl == FLtlsdata)
            {
                if (I64)
                {
                    infobuf->writeByte(DW_OP_const8u);
                    ElfObj::addrel(infoseg, infobuf->size(), R_X86_64_DTPOFF32, s->Sxtrnnum, 0);
                    infobuf->write64(0);
                }
                else
                {
                    infobuf->writeByte(DW_OP_const4u);
                    ElfObj::addrel(infoseg, infobuf->size(), R_386_TLS_LDO_32, s->Sxtrnnum, 0);
                    infobuf->write32(0);
                }
                infobuf->writeByte(0xe0);            // DW_OP_GNU_push_tls_address
            }
            else
#endif
            {
                infobuf->writeByte(DW_OP_addr);
                dwarf_addrel(infoseg,infobuf->size(),s->Sseg);
                append_addr(infobuf, s->Soffset);    // address of global
            }

- add DWARF_VERSION to dwarf.h
- emit DW_OP_GNU_push_tls_address or DW_OP_form_tls_address based on DWARF_VERSION
@tramker
Copy link
Contributor Author

tramker commented Oct 9, 2014

Redone based on Martin's suggestions. Looks much cleaner.

MartinNowak added a commit that referenced this pull request Oct 10, 2014
Fix Issue 4181 - GDB prints wrong value of TLS variables
@MartinNowak MartinNowak merged commit 1184265 into dlang:master Oct 10, 2014
@MartinNowak
Copy link
Member

Great, thanks a lot.

infobuf->writeByte(DW_OP_form_tls_address);
#endif
} else
#endif

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this break DDMD? @yebblies

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, because the backend doesn't get converted.

@tramker tramker deleted the bug4181 branch January 26, 2015 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants