From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id 910DF3858D3C for ; Fri, 10 Nov 2023 08:07:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 910DF3858D3C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 910DF3858D3C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=195.135.220.29 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699603675; cv=none; b=qq1R842hnXvy4XGmGSiXnH04/EEjGPgAEkWmUkmvDAMfYqqYk5387c2KjSaMIQkpXdEpEJMxNGXtxz83DXmJlLozX5gqm7WOvRulvuaSA8ycE9bsgdMDULZO3cXh8l1EfBh9pml3eB2BOIkVTgwtg8lZMYwY3nReV9wWZgSBFSE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699603675; c=relaxed/simple; bh=n3PR7oco2xFR36/ItRwqikm71l+7Rcec+oo6rO1vL3c=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-Id: MIME-Version; b=UiFR+fYoK107iVoP/BVcePdkkvm+x5xVbGx0SznBQonXfY/4Ad6//+RF+OxWgpYdfn7v8qS63DDs966nnqROMGK4BSVp2SDfcrANJ8qpFVQp1IBtoT19egNTQrvCZExZjk303/oQLCfPflsrBNelKjok6kNNOX3dZmp6I9sI5IY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id BBCD11F8BB for ; Fri, 10 Nov 2023 08:07:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1699603672; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wi1Y54cwky9cEUSpJSQU9nrKL3QLeSn+80rFSFWHVA8=; b=PhEC9nUYm7Jri/6F2JbhJt2kRlK23cLrrYLbw6K7/uXIDasw+SaWcDgV81O2XBKjiuUWYP 7mS2RcbkbxAG6ZCyKgNLfP4aMrnPLbjejWJYzVh2xUlQTf1OCk82EpaAsowICvOZwzVNyx QeDwkRIhfPnmqLT7bJ+tilWkOhO6Ar0= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1699603672; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wi1Y54cwky9cEUSpJSQU9nrKL3QLeSn+80rFSFWHVA8=; b=2NH4uVGdMj4xVL8DQNcTwthV1pEXylGtHplZix3EzOKKlL8pfht9z9XDceJd1jQEuVzR1t VRqtnsTaC//UtyAg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id AAB66138FC for ; Fri, 10 Nov 2023 08:07:52 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id oOjLKNjkTWV1IQAAMHmgww (envelope-from ) for ; Fri, 10 Nov 2023 08:07:52 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH v4 2/2] [gdb] Fix segfault in for_each_block, part 2 Date: Fri, 10 Nov 2023 09:09:15 +0100 Message-Id: <20231110080915.18008-3-tdevries@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20231110080915.18008-1-tdevries@suse.de> References: <20231110080915.18008-1-tdevries@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_NUMSUBJECT,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE 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: The previous commit describes PR gdb/30547, a segfault when running test-case gdb.base/vfork-follow-parent.exp on powerpc64 (likewise on s390x). The root cause for the segmentation fault is that linux_is_uclinux gives an incorrect result: it returns true instead of false. So, why does linux_is_uclinux: ... int linux_is_uclinux (void) { CORE_ADDR dummy; return (target_auxv_search (AT_NULL, &dummy) > 0 && target_auxv_search (AT_PAGESZ, &dummy) == 0); ... return true? This is because ppc_linux_target_wordsize returns 4 instead of 8, causing ppc_linux_nat_target::auxv_parse to misinterpret the auxv vector. So, why does ppc_linux_target_wordsize: ... int ppc_linux_target_wordsize (int tid) { int wordsize = 4; /* Check for 64-bit inferior process. This is the case when the host is 64-bit, and in addition the top bit of the MSR register is set. */ long msr; errno = 0; msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0); if (errno == 0 && ppc64_64bit_inferior_p (msr)) wordsize = 8; return wordsize; } ... return 4? Specifically, we get this result because because tid == 0, so we get errno == ESRCH. The tid == 0 is caused by the switch_to_no_thread in handle_vfork_child_exec_or_exit: ... /* Switch to no-thread while running clone_program_space, so that clone_program_space doesn't want to read the selected frame of a dead process. */ scoped_restore_current_thread restore_thread; switch_to_no_thread (); inf->pspace = new program_space (maybe_new_address_space ()); ... but moving the maybe_new_address_space call to before that gives us the same result. The tid is no longer 0, but we still get ESRCH because the thread has exited. Fix this in handle_vfork_child_exec_or_exit by doing the maybe_new_address_space call in the context of the vfork parent. Tested on top of trunk on x86_64-linux and ppc64le-linux. Tested on top of gdb-14-branch on ppc64-linux. Co-Authored-By: Simon Marchi PR gdb/30547 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30547 --- gdb/infrun.c | 16 +++++++++++----- gdb/nat/ppc-linux.c | 2 ++ gdb/ppc-linux-nat.c | 2 ++ gdb/s390-linux-nat.c | 5 ++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 95620d479d8..7266bbe5960 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1103,13 +1103,19 @@ handle_vfork_child_exec_or_exit (int exec) go ahead and create a new one for this exiting inferior. */ - /* Switch to no-thread while running clone_program_space, so - that clone_program_space doesn't want to read the - selected frame of a dead process. */ scoped_restore_current_thread restore_thread; - switch_to_no_thread (); - inf->pspace = new program_space (maybe_new_address_space ()); + /* Temporarily switch to the vfork parent, to facilitate ptrace + calls done during maybe_new_address_space. */ + switch_to_thread (any_live_thread_of_inferior (vfork_parent)); + address_space_ref_ptr aspace = maybe_new_address_space (); + + /* Switch back to the vfork child inferior. Switch to no-thread + while running clone_program_space, so that clone_program_space + doesn't want to read the selected frame of a dead process. */ + switch_to_inferior_no_thread (inf); + + inf->pspace = new program_space (std::move (aspace)); inf->aspace = inf->pspace->aspace; set_current_program_space (inf->pspace); inf->removable = true; diff --git a/gdb/nat/ppc-linux.c b/gdb/nat/ppc-linux.c index 0957d1b58a7..74549754806 100644 --- a/gdb/nat/ppc-linux.c +++ b/gdb/nat/ppc-linux.c @@ -78,6 +78,8 @@ ppc64_64bit_inferior_p (long msr) int ppc_linux_target_wordsize (int tid) { + gdb_assert (tid != 0); + int wordsize = 4; /* Check for 64-bit inferior process. This is the case when the host is diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index a0205119f00..70dd20ad963 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -1914,6 +1914,8 @@ ppc_linux_nat_target::auxv_parse (const gdb_byte **readptr, const gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) { + gdb_assert (inferior_ptid != null_ptid); + int tid = inferior_ptid.lwp (); if (tid == 0) tid = inferior_ptid.pid (); diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c index 0aa3edea8aa..1a94ce487c3 100644 --- a/gdb/s390-linux-nat.c +++ b/gdb/s390-linux-nat.c @@ -949,10 +949,12 @@ s390_target_wordsize (void) /* Check for 64-bit inferior process. This is the case when the host is 64-bit, and in addition bit 32 of the PSW mask is set. */ #ifdef __s390x__ + int tid = s390_inferior_tid (); + gdb_assert (tid == 0); long pswm; errno = 0; - pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0); + pswm = (long) ptrace (PTRACE_PEEKUSER, tid, PT_PSWMASK, 0); if (errno == 0 && (pswm & 0x100000000ul) != 0) wordsize = 8; #endif @@ -965,6 +967,7 @@ s390_linux_nat_target::auxv_parse (const gdb_byte **readptr, const gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) { + gdb_assert (inferior_ptid != null_ptid); int sizeof_auxv_field = s390_target_wordsize (); bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ()); const gdb_byte *ptr = *readptr; -- 2.35.3