public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Simon Marchi <simon.marchi@polymtl.ca>
To: John Baldwin <jhb@freebsd.org>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 3/9] Handle TLS variable lookups when using separate debug object files.
Date: Thu, 07 Feb 2019 04:05:00 -0000	[thread overview]
Message-ID: <67973931006085a171ad69952649de33@polymtl.ca> (raw)
In-Reply-To: <10dfaac6-0119-4f9f-666d-89fe7d8fb6cb@FreeBSD.org>

On 2019-02-05 17:33, John Baldwin wrote:
> On 2/5/19 2:21 PM, John Baldwin wrote:
>> So it seems that the OP_VAR_VALUE path calls down into the dwarf bits 
>> that
>> get the "original" objfile to pass to target_translate_tls_address, 
>> whereas
>> the OP_VAR_MSYM_VALUE case ends up using a separate object file.  This 
>> might
>> in fact be due to bugs in the RISCV GCC backend as the TLS symbols for 
>> RISCV
>> don't seem quite right.  I have to cast TLS variables to their types 
>> for
>> example:
>> 
>> (gdb) p __je_tsd_initialized
>> '__je_tsd_initialized` has unknown type; cast it to its declared type
>> (gdb) p (bool)__je_tsd_initialized
>> $2 = 1 '\001'
>> 
>> Also, for me TLS variables in the main executable did not work for me 
>> on
>> RISCV, only TLS variables in shared libraries, unlike on other 
>> architectures
>> I tested where TLS variables in both the executable and shared 
>> libraries
>> worked.
> 
> I should have said: I think this means I probably need to rework the 
> commit
> message a bit to explain that this doesn't always happen with separate
> debug files, but it can, and if so this fix is needed.

After discussing with John on IRC and trying by all means to trigger 
this bug, this is what I ended up with.  On x86/GNU/Linux, it is 
possible to trigger this bug in a rather contrived way, but at least it 
shows that there is indeed a bug in GDB.  The requirements are:

1. Have a TLS variable in a shared library ("libfoo.so")
2. The .o containing the TLS variable should not be described with 
DWARF.  This can be done simply by compiling it without -g.
3. The shared lib should still have a separate debug info file 
("libfoo.so.debug").
4. The shared lib should be stripped of its unnecessary ELF symbols (ran 
through the strip utility)
5. The shared library should not be the first object file in the program 
to have TLS.  This can be done by adding a TLS variable in the main 
executable ("main").
6. Because we don't have debug info for the variable we try to print, we 
need to cast it to its expected type, e.g. "print (int)foo_id".

With all this, when parsing "(int)foo_id", we find a minimal symbol 
matching foo_id in the objfile representing libfoo.so.debug.  
find_minsym_type_and_address is eventually called with that objfile, 
which calls target_translate_tls_address, which calls 
svr4_fetch_objfile_link_map.  The latter obviously can't find a link_map 
matching the separate-debug-info objfile, and wrong things happen after.

Without #2 above, the DWARF symbol is found and some other code path is 
taken, where the separate-debug-info objfile is replaced with the "real" 
objfile at some point.

Without #3, we obviously wouldn't end up with a separate-debug-info 
objfile in svr4_fetch_objfile_link_map.

Without #4 above, we would find the objfile for libfoo.so first, so we 
wouldn't end up with the seaprate-debug-info objfile in 
svr4_fetch_objfile_link_map.

Without #5 we actually get the right result by chance.  This is because 
we end up in the special case "else" of 
thread_db_target::get_thread_local_address.  That special case hardcodes 
the module id to read from to 1.  If the shared lib is the only module 
to have TLS, then it happens to be the right one.  By making the main 
executable have some TLS, we will end up reading the TLS for the wrong 
module, and thus trigger the bug.

I have not yet found the motivation to write a proper test for this (in 
particular, I am not sure how to build the lib with separate debug info 
in the testsuite).  But I attached a reproducer for future reference.  
You should just need to "make" and "gdb -x run.gdb".  The wrong value is 
printed with today's GDB.

In John's specific case, apparently the DWARF debug info for TLS 
variables on riscv is broken, which brought him to roughly the same 
state.  I don't have any more info about that.

All this to say that I think this patch is fine.  I wondered whether it 
was better instead to make svr4_fetch_objfile_link_map assert that it 
receives a "real" objfile (objfile->separate_debug_objfile_backlink == 
NULL) and push the responsibility to the caller to provide a correct 
objfile.  But in the end I didn't find a compelling to do this rather 
than what John did in this patch.  So therefore, the patch LGTM.

Simon

  reply	other threads:[~2019-02-07  4:05 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-22 18:43 [PATCH 0/9] Support for thread-local variables on FreeBSD John Baldwin
2019-01-22 18:43 ` [PATCH 7/9] Support TLS variables on FreeBSD/i386 John Baldwin
2019-01-22 18:43 ` [PATCH 6/9] Support TLS variables on FreeBSD/amd64 John Baldwin
2019-01-22 18:43 ` [PATCH 2/9] Support fs_base and gs_base on FreeBSD/i386 John Baldwin
2019-02-02 15:26   ` Simon Marchi
2019-02-04 19:45     ` John Baldwin
2019-02-05 18:59       ` Simon Marchi
2019-01-22 18:43 ` [PATCH 9/9] Support TLS variables on FreeBSD/powerpc John Baldwin
2019-01-22 18:43 ` [PATCH 1/9] Support the fs_base and gs_base registers on i386 John Baldwin
2019-01-27  4:22   ` Simon Marchi
2019-01-28 17:54     ` John Baldwin
2019-02-02 15:11       ` Simon Marchi
2019-01-22 18:43 ` [PATCH 3/9] Handle TLS variable lookups when using separate debug object files John Baldwin
2019-02-02 15:52   ` Simon Marchi
2019-02-04 20:02     ` John Baldwin
2019-02-05 20:06       ` Simon Marchi
2019-02-05 22:21         ` John Baldwin
2019-02-05 22:33           ` John Baldwin
2019-02-07  4:05             ` Simon Marchi [this message]
2019-02-07  4:08               ` Simon Marchi
2019-01-22 18:52 ` [PATCH 5/9] Add a helper function to resolve TLS variable addresses for FreeBSD John Baldwin
2019-01-24 17:09   ` John Baldwin
2019-02-07  5:05     ` Simon Marchi
2019-02-07 17:02       ` John Baldwin
2019-02-09  0:34         ` John Baldwin
2019-01-22 18:52 ` [PATCH 8/9] Support TLS variables on FreeBSD/riscv John Baldwin
2019-01-27 23:35   ` Andrew Burgess
2019-01-22 18:52 ` [PATCH 4/9] Add a new gdbarch method to resolve the address of TLS variables John Baldwin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=67973931006085a171ad69952649de33@polymtl.ca \
    --to=simon.marchi@polymtl.ca \
    --cc=gdb-patches@sourceware.org \
    --cc=jhb@freebsd.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).