From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 487E2385B190 for ; Mon, 28 Nov 2022 14:09:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 487E2385B190 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2ASE9SUU031427 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 28 Nov 2022 09:09:33 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2ASE9SUU031427 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1669644573; bh=KS8miUl1wcaz+zMXuvfPh3JzoTMLCzjID6TN+xdFsBo=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=Qz/I+5lc7+Na2gBZHRvLXT0j95YEUJh5NUYn7NRpnw1GHr594ygFuNYM8zmtLd3PL vlCzfUDN/j7nTzMrazRD3d7LpyzI7jAF/AdDxdWwasQcraLPUy9C+AeX7Pn+kv0v8b By8b5GQFmXJmc6dCtFKLo8GOqMoOCygusej3CWq8= Received: from [10.0.0.11] (unknown [217.28.27.60]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 44DF41E0CB; Mon, 28 Nov 2022 09:09:28 -0500 (EST) Message-ID: <8a52c35d-4449-183c-56d2-930f0b0458c3@polymtl.ca> Date: Mon, 28 Nov 2022 09:09:27 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Subject: Re: [PATCH v2 4/5] gdbserver: switch to right process in find_one_thread Content-Language: en-US To: Andrew Burgess , gdb-patches@sourceware.org Cc: Simon Marchi References: <20221121171213.1414366-1-simon.marchi@polymtl.ca> <20221121171213.1414366-5-simon.marchi@polymtl.ca> <87cz972oku.fsf@redhat.com> From: Simon Marchi In-Reply-To: <87cz972oku.fsf@redhat.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Mon, 28 Nov 2022 14:09:28 +0000 X-Spam-Status: No, score=-3038.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,NICE_REPLY_A,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS,TXREP,WEIRD_PORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 11/28/22 08:30, Andrew Burgess wrote: > Simon Marchi via Gdb-patches writes: > >> From: Simon Marchi >> >> New in this version: add a dedicated test. >> >> When I do this: >> >> $ ./gdb -nx --data-directory=data-directory -q \ >> /bin/sleep \ >> -ex "maint set target-non-stop on" \ >> -ex "tar ext :1234" \ >> -ex "set remote exec-file /bin/sleep" \ >> -ex "run 1231 &" \ >> -ex add-inferior \ >> -ex "inferior 2" >> Reading symbols from /bin/sleep... >> (No debugging symbols found in /bin/sleep) >> Remote debugging using :1234 >> Starting program: /bin/sleep 1231 >> Reading /lib64/ld-linux-x86-64.so.2 from remote target... >> warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead. >> Reading /lib64/ld-linux-x86-64.so.2 from remote target... >> Reading /usr/lib/debug/.build-id/a6/7a1408f18db3576757eea210d07ba3fc560dff.debug from remote target... >> [New inferior 2] >> Added inferior 2 on connection 1 (extended-remote :1234) >> [Switching to inferior 2 [] ()] >> (gdb) Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target... >> attach 3659848 >> Attaching to process 3659848 >> /home/smarchi/src/binutils-gdb/gdb/thread.c:85: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed. >> >> Note the "attach" command just above. When doing it on the command-line >> with a -ex switch, the bug doesn't trigger. >> >> The internal error of GDB is actually caused by GDBserver crashing, and >> the error recovery of GDB is not on point. This patch aims to fix just >> the GDBserver crash, not the GDB problem. >> >> GDBserver crashes with a segfault here: >> >> (gdb) bt >> #0 0x00005555557fb3f4 in find_one_thread (ptid=...) at /home/smarchi/src/binutils-gdb/gdbserver/thread-db.cc:177 >> #1 0x00005555557fd5cf in thread_db_thread_handle (ptid=, handle=0x7fffffffc400, handle_len=0x7fffffffc3f0) >> at /home/smarchi/src/binutils-gdb/gdbserver/thread-db.cc:461 >> #2 0x000055555578a0b6 in linux_process_target::thread_handle (this=0x5555558a64c0 , ptid=, handle=0x7fffffffc400, >> handle_len=0x7fffffffc3f0) at /home/smarchi/src/binutils-gdb/gdbserver/linux-low.cc:6905 >> #3 0x00005555556dfcc6 in handle_qxfer_threads_worker (thread=0x60b000000510, buffer=0x7fffffffc8a0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1645 >> #4 0x00005555556e00e6 in operator() (__closure=0x7fffffffc5e0, thread=0x60b000000510) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1696 >> #5 0x00005555556f54be in for_each_thread >(struct {...}) (func=...) at /home/smarchi/src/binutils-gdb/gdbserver/gdbthread.h:159 >> #6 0x00005555556e0242 in handle_qxfer_threads_proper (buffer=0x7fffffffc8a0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1694 >> #7 0x00005555556e04ba in handle_qxfer_threads (annex=0x629000000213 "", readbuf=0x621000019100 '\276' ..., writebuf=0x0, offset=0, len=4097) >> at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1732 >> #8 0x00005555556e1989 in handle_qxfer (own_buf=0x629000000200 "qXfer:threads", packet_len=26, new_packet_len_p=0x7fffffffd630) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:2045 >> #9 0x00005555556e720a in handle_query (own_buf=0x629000000200 "qXfer:threads", packet_len=26, new_packet_len_p=0x7fffffffd630) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:2685 >> #10 0x00005555556f1a01 in process_serial_event () at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4176 >> #11 0x00005555556f4457 in handle_serial_event (err=0, client_data=0x0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4514 >> #12 0x0000555555820f56 in handle_file_event (file_ptr=0x607000000250, ready_mask=1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:573 >> #13 0x0000555555821895 in gdb_wait_for_event (block=1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:694 >> #14 0x000055555581f533 in gdb_do_one_event (mstimeout=-1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:264 >> #15 0x00005555556ec9fb in start_event_loop () at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3512 >> #16 0x00005555556f0769 in captured_main (argc=4, argv=0x7fffffffe0d8) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3992 >> #17 0x00005555556f0e3f in main (argc=4, argv=0x7fffffffe0d8) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4078 >> >> The reason is a wrong current process when find_one_thread is called. >> The current process is the 2nd one, which was just attached. It does >> not yet have thread_db data (proc->priv->thread_db is nullptr). As we >> iterate on all threads of all process to fulfull the qxfer:threads:read >> request, we get to a thread of process 1 for which we haven't read >> thread_db information yet (lwp_info::thread_known is false), so we get >> into find_one_thread. find_one_thread uses >> `current_processĀ ()->priv->thread_db`, assuming the current process >> matches the ptid passed as a parameter, which is wrong. A segfault >> happens when trying to dereference that thread_db pointer. >> >> Fix this by making find_one_thread not assume what the current process / >> current thread is. If it needs to call into libthread_db, which we know >> will try to read memory from the current process, then temporarily set >> the current process. >> >> In the case where the thread is already know and we return early, we >> don't need to switch process. > > Thanks for taking the time to write a test just for this issue. > Initially, I still couldn't reproduce this issue. I took the time to > dig into this a little more. > > My default desktop install is pretty old now. And it turns out that for > some reason gdbserver built in that environment can't correctly load > libthread_db, though I have no idea why. The libthread_db and > libpthreads are from the same glibc install, gdbserver does dlopen the > library correctly, but the td_ta_new_p call fails. Looking at the error > code it appears that libthread_db fails to find the version symbol (I > guess it's looking for that symbol in libpthreads, maybe?) Oh, that doesn't ring a bell, sorry. > Anyway, I write the above just for a record. > > I retried your patch on a much more recent install, and everything works > fine, I can see the failure when I back-out the GDB change, and all > works fine with the fix in place. > > I did spot one minor style issue, detailed inline below... > >> >> Add a test to reproduce this specific situation. >> >> Change-Id: I09b00883e8b73b7e5f89d0f47cb4e9c0f3d6caaa >> --- >> .../gdb.multi/attach-while-running.c | 26 +++++++ >> .../gdb.multi/attach-while-running.exp | 69 +++++++++++++++++++ >> gdbserver/thread-db.cc | 29 ++++---- >> 3 files changed, 112 insertions(+), 12 deletions(-) >> create mode 100644 gdb/testsuite/gdb.multi/attach-while-running.c >> create mode 100644 gdb/testsuite/gdb.multi/attach-while-running.exp >> >> diff --git a/gdb/testsuite/gdb.multi/attach-while-running.c b/gdb/testsuite/gdb.multi/attach-while-running.c >> new file mode 100644 >> index 000000000000..dd321dfe0071 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.multi/attach-while-running.c >> @@ -0,0 +1,26 @@ >> +/* This testcase is part of GDB, the GNU debugger. >> + >> + Copyright 2022 Free Software Foundation, Inc. >> + >> + This program is free software; you can redistribute it and/or modify >> + it under the terms of the GNU General Public License as published by >> + the Free Software Foundation; either version 3 of the License, or >> + (at your option) any later version. >> + >> + This program is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + GNU General Public License for more details. >> + >> + You should have received a copy of the GNU General Public License >> + along with this program. If not, see . */ >> + >> +#include >> + >> +int global_var = 123; >> + >> +int >> +main (void) >> +{ >> + sleep (30); >> +} >> diff --git a/gdb/testsuite/gdb.multi/attach-while-running.exp b/gdb/testsuite/gdb.multi/attach-while-running.exp >> new file mode 100644 >> index 000000000000..db2877dbebe5 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.multi/attach-while-running.exp >> @@ -0,0 +1,69 @@ >> +# Copyright -2022 Free Software Foundation, Inc. > > Extra '-' in the copyright line. > > Otherwise, this all looks good. Thanks, will fix and push with the following patch. Simon