From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 75F0C38432DD for ; Fri, 18 Nov 2022 13:19:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 75F0C38432DD Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1668777594; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zoZQLjggM6N/Fv91vIv1/phP1zbHYh5OqNnusnwb1U8=; b=LjV1mYs9QqelByUYPjy2DbMzefs9Ebby2ABalYeqbZIIvBBZpYPloZLhfSODV+iMuRtJnH MaQUuJgQ0y6V5QtaUadOJcTIdDZdL9GprSEh/sSRJTk0cyjjbh/Xb7ttdHFpQTaVdSB7Pu 8B/BQ7CesUT1JQlwqCbwZ+49CTeOCgU= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-644-F8-8rp8aPe62az6-BUKMXQ-1; Fri, 18 Nov 2022 08:19:53 -0500 X-MC-Unique: F8-8rp8aPe62az6-BUKMXQ-1 Received: by mail-wr1-f69.google.com with SMTP id q2-20020adfab02000000b00241b8f7efc5so1404089wrc.19 for ; Fri, 18 Nov 2022 05:19:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/WY4NbFbQCOtbE6/QuIJNTv7f8NCCLxtszvO88Pexas=; b=tWPx7H2mIe/smBoIsDHc1cF4RUUoQka9l77C5xhAYdunTKQ3RFVZ2Asc8//wQF3ZLh K/jvJL5mnlywifZMRELP7Suw0DZ1tp0uMeH+BOnK514K1aQkul8C2q/7e8QrrpdiCGMt lWKQlSE4BvQLak+siRqj1Fg9W9/VGHshuE/3dmSgYRdiJv2rF1fxoImv07qIfvFe7v/S 9SpES38ctgn0dwRkGd2q9MMKky3q4I6dO/WzqmE45R8BWiYnb7slsagDkJpR5OXGgYFx cnoNQRPK41wcEifVzfeXyCn2VGeyufO8OyD2mjQJHCEn0xp9ptUDm45aNO05gx9tCitK syjg== X-Gm-Message-State: ANoB5pl6v9aBDMkcqHV2oxZA6KBf1yRwaIHnRc9kyujU6dDOlwWV8B4t QoXVlrRF2lPtp+MBhrmHN4iQmfPyICJQ/AaUQg5vS7lNyfrQkkut9h2Yuwoppwt771FF1ZAYk43 Vst2qFMSlv0eT6boBnqssOS6zgSaZXv4b/6OSBaEzU8S0k0T3p9+OKYKps1YvnsIhwNScIsBEaQ == X-Received: by 2002:a5d:6e0e:0:b0:22e:ed53:771c with SMTP id h14-20020a5d6e0e000000b0022eed53771cmr4478021wrz.297.1668777591612; Fri, 18 Nov 2022 05:19:51 -0800 (PST) X-Google-Smtp-Source: AA0mqf470VQFrwz503TlFY+tDDTtR7pYRvSQI3yGrzGBqnm3DtjCcNRMoeGZHG3zYud5gBPwhWmrtw== X-Received: by 2002:a5d:6e0e:0:b0:22e:ed53:771c with SMTP id h14-20020a5d6e0e000000b0022eed53771cmr4478001wrz.297.1668777591184; Fri, 18 Nov 2022 05:19:51 -0800 (PST) Received: from localhost ([31.111.84.238]) by smtp.gmail.com with ESMTPSA id o2-20020a05600c510200b003cf5ec79bf9sm5259341wms.40.2022.11.18.05.19.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Nov 2022 05:19:50 -0800 (PST) From: Andrew Burgess To: Simon Marchi via Gdb-patches , gdb-patches@sourceware.org Cc: Simon Marchi Subject: Re: [PATCH 7/8] gdbserver: switch to right process in find_one_thread In-Reply-To: <20221117194241.1776125-8-simon.marchi@efficios.com> References: <20221117194241.1776125-1-simon.marchi@efficios.com> <20221117194241.1776125-8-simon.marchi@efficios.com> Date: Fri, 18 Nov 2022 13:19:49 +0000 Message-ID: <875yfc8kne.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,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: Simon Marchi via Gdb-patches writes: > When I do this: > > $ ./gdb -nx --data-directory=3Ddata-directory -q \ > /bin/sleep \ > =09-ex "maint set target-non-stop on" \ > =09-ex "tar ext :1234" \ > =09-ex "set remote exec-file /bin/sleep" \ > =09-ex "run 1231 &" \ > =09-ex add-inferior \ > =09-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 sys= root" to access files locally instead. > Reading /lib64/ld-linux-x86-64.so.2 from remote target... > Reading /usr/lib/debug/.build-id/a6/7a1408f18db3576757eea210d07ba3fc5= 60dff.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: infer= ior_thread: Assertion `current_thread_ !=3D nullptr' failed. > > 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=3D...) at /home/smarc= hi/src/binutils-gdb/gdbserver/thread-db.cc:177 > #1 0x00005555557fd5cf in thread_db_thread_handle (ptid=3D, handle= =3D0x7fffffffc400, handle_len=3D0x7fffffffc3f0) > at /home/smarchi/src/binutils-gdb/gdbserver/thread-db.cc:461 > #2 0x000055555578a0b6 in linux_process_target::thread_handle (this= =3D0x5555558a64c0 , ptid=3D, handle=3D0x7fffffffc400, > handle_len=3D0x7fffffffc3f0) at /home/smarchi/src/binutils-gdb/gd= bserver/linux-low.cc:6905 > #3 0x00005555556dfcc6 in handle_qxfer_threads_worker (thread=3D0x60b= 000000510, buffer=3D0x7fffffffc8a0) at /home/smarchi/src/binutils-gdb/gdbse= rver/server.cc:1645 > #4 0x00005555556e00e6 in operator() (__closure=3D0x7fffffffc5e0, thr= ead=3D0x60b000000510) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc= :1696 > #5 0x00005555556f54be in for_each_thread >(struct {...}) (func=3D...) at /home/sma= rchi/src/binutils-gdb/gdbserver/gdbthread.h:159 > #6 0x00005555556e0242 in handle_qxfer_threads_proper (buffer=3D0x7ff= fffffc8a0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1694 > #7 0x00005555556e04ba in handle_qxfer_threads (annex=3D0x62900000021= 3 "", readbuf=3D0x621000019100 '\276' ..., writebuf=3D0x= 0, offset=3D0, len=3D4097) > at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:1732 > #8 0x00005555556e1989 in handle_qxfer (own_buf=3D0x629000000200 "qXf= er:threads", packet_len=3D26, new_packet_len_p=3D0x7fffffffd630) at /home/s= marchi/src/binutils-gdb/gdbserver/server.cc:2045 > #9 0x00005555556e720a in handle_query (own_buf=3D0x629000000200 "qXf= er:threads", packet_len=3D26, new_packet_len_p=3D0x7fffffffd630) at /home/s= marchi/src/binutils-gdb/gdbserver/server.cc:2685 > #10 0x00005555556f1a01 in process_serial_event () at /home/smarchi/sr= c/binutils-gdb/gdbserver/server.cc:4176 > #11 0x00005555556f4457 in handle_serial_event (err=3D0, client_data= =3D0x0) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:4514 > #12 0x0000555555820f56 in handle_file_event (file_ptr=3D0x60700000025= 0, ready_mask=3D1) at /home/smarchi/src/binutils-gdb/gdbsupport/event-loop.= cc:573 > #13 0x0000555555821895 in gdb_wait_for_event (block=3D1) at /home/sma= rchi/src/binutils-gdb/gdbsupport/event-loop.cc:694 > #14 0x000055555581f533 in gdb_do_one_event (mstimeout=3D-1) at /home/= smarchi/src/binutils-gdb/gdbsupport/event-loop.cc:264 > #15 0x00005555556ec9fb in start_event_loop () at /home/smarchi/src/bi= nutils-gdb/gdbserver/server.cc:3512 > #16 0x00005555556f0769 in captured_main (argc=3D4, argv=3D0x7fffffffe= 0d8) at /home/smarchi/src/binutils-gdb/gdbserver/server.cc:3992 > #17 0x00005555556f0e3f in main (argc=3D4, argv=3D0x7fffffffe0d8) 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=C2=A0()->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. > > I hit this case when running the test included with the following patch, > "gdb: disable commit resumed in target_kill", so the fix is exercised by > that test. I'm not able to reproduce the failure you describe. I've applied this series except for this patch, and run the test from patch #8 with native-extended-gdbserver board, and it passes just fine. Actually, I do see an issue with the test, but that issue doesn't seem to be related to this problem, and is present with and without this patch - I'll reply to patch #8 describing that issue. Is this bug intermittent? Or is it likely to depend on certain parts of the environment? I got the impression from the description that it if we did the steps in the right order then we'd get a nullptr dereference, which didn't feel like an intermittent issue, but maybe I don't understand correctly. That said, the change itself looks reasonable - but it would be nice to know why I can't reproduce the failure. Thanks, Andrew > > Change-Id: I09b00883e8b73b7e5f89d0f47cb4e9c0f3d6caaa > --- > gdbserver/thread-db.cc | 29 +++++++++++++++++------------ > 1 file changed, 17 insertions(+), 12 deletions(-) > > diff --git a/gdbserver/thread-db.cc b/gdbserver/thread-db.cc > index 6e0e2228a5f..bf98ca9557a 100644 > --- a/gdbserver/thread-db.cc > +++ b/gdbserver/thread-db.cc > @@ -155,30 +155,35 @@ thread_db_state_str (td_thr_state_e state) > } > #endif > =20 > -/* Get thread info about PTID, accessing memory via the current > - thread. */ > +/* Get thread info about PTID. */ > =20 > static int > find_one_thread (ptid_t ptid) > { > - td_thrhandle_t th; > - td_thrinfo_t ti; > - td_err_e err; > - struct lwp_info *lwp; > - struct thread_db *thread_db =3D current_process ()->priv->thread_db; > - int lwpid =3D ptid.lwp (); > - > thread_info *thread =3D find_thread_ptid (ptid); > - lwp =3D get_thread_lwp (thread); > + lwp_info *lwp =3D get_thread_lwp (thread); > if (lwp->thread_known) > return 1; > =20 > - /* Get information about this thread. */ > - err =3D thread_db->td_ta_map_lwp2thr_p (thread_db->thread_agent, lwpid= , &th); > + /* Get information about this thread. libthread_db will need to read = some > + memory, which will be done on the current process, so make PTID's p= rocess > + the current one. */ > + process_info *proc =3D find_process_pid (ptid.pid ()); > + gdb_assert (proc !=3D nullptr); > + > + scoped_restore_current_thread restore_thread; > + switch_to_process (proc); > + > + thread_db *thread_db =3D proc->priv->thread_db; > + td_thrhandle_t th; > + int lwpid =3D ptid.lwp (); > + td_err_e err =3D thread_db->td_ta_map_lwp2thr_p (thread_db->thread_age= nt, lwpid, > +=09=09=09=09=09=09 &th); > if (err !=3D TD_OK) > error ("Cannot get thread handle for LWP %d: %s", > =09 lwpid, thread_db_err_str (err)); > =20 > + td_thrinfo_t ti; > err =3D thread_db->td_thr_get_info_p (&th, &ti); > if (err !=3D TD_OK) > error ("Cannot get thread info for LWP %d: %s", > --=20 > 2.37.3