From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id iH65NYFv8Ge1GicAWB0awg (envelope-from ) for ; Fri, 04 Apr 2025 19:47:13 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=eCLEFK+P; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id D91ED1E0C3; Fri, 4 Apr 2025 19:47:13 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 3DA7B1E0C0 for ; Fri, 4 Apr 2025 19:47:13 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E31E4384A414 for ; Fri, 4 Apr 2025 23:47:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E31E4384A414 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=eCLEFK+P Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 76D0F3857007 for ; Fri, 4 Apr 2025 23:44:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 76D0F3857007 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 76D0F3857007 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1743810242; cv=none; b=sLy407pFq0Rr0X6Okd5fnhAxhcg7NfcZuBfmlhRceZiQRCNN+raYcEq5imMx75Z9Fpp6YLL0NAFjBwNWzR9ScefxTLcOCWl22gmm68bGTltKKSAQcsX3be92wrP8vbi94f+Xkd1CZ4T7LVMolCLxdCb0viGEL0Xsqf3KKqaKrfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1743810242; c=relaxed/simple; bh=ZSIGh9eX5NHJtmG/lxKWR1r5yyA1f5QMojvHqxB/5o0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=TRvmB1jmOW7QAhErrIJU2PjJYmW2/C7kkQeA9SPVD0LMJaOhcwE84Jcght1X3niFJzG7H2gRg3jVXxQHhgGdKoY0X+9Rmi7I9TVfdZGflf1wK7Z94vLtaKN7IKglD4Ej9YqW0JhRihm/sXpP4pCFo10oC/OUpJxs01pM/jWT6Qw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 76D0F3857007 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1743810242; 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=+bSneuBPRfG0xBhTCgUyqEj5PrRGadtb2GXZPOMPvU4=; b=eCLEFK+PRXNzqdoPj0LGrJDcFf9b/MWdO/fwYEsShNqnBwwuF0ox/CO3ZxVrwmam0hpLx5 vAfPU4Uy7EkDNuIYpkb9KMiPmkicDkXnIPloM8teQa8SzfZO9+LqZ3oaUqAcCfSE4523UI c6GJxojBq8gR/ldeueuB2yqHFq+RObM= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-190-2MdXqp9hMGKqfesWTjJ4rg-1; Fri, 04 Apr 2025 19:43:56 -0400 X-MC-Unique: 2MdXqp9hMGKqfesWTjJ4rg-1 X-Mimecast-MFC-AGG-ID: 2MdXqp9hMGKqfesWTjJ4rg_1743810235 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4E3CC1800361 for ; Fri, 4 Apr 2025 23:43:55 +0000 (UTC) Received: from f42-1.lan (unknown [10.22.88.7]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 536E11955BC2; Fri, 4 Apr 2025 23:43:54 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH v6 01/11] Don't attempt to find TLS address when target has no registers Date: Fri, 4 Apr 2025 16:37:32 -0700 Message-ID: <20250404234324.1931302-2-kevinb@redhat.com> In-Reply-To: <20250404234324.1931302-1-kevinb@redhat.com> References: <20250404234324.1931302-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: dltlXZF9zpNU-SnLR8sfj3qZRLQdr2s7VnP5S1Fpb60_1743810235 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org This commit fixes two bugs, one of which is Bug 25807, which occurs when target_translate_tls_address() is called from language_defn::read_var_value in findvar.c. I found it while testing on aarch64; it turned a KFAIL for gdb.threads/tls.exp: print a_thread_local into a FAIL due to a GDB internal error. Now, with this commit in place, the KFAIL/FAIL turns into a PASS. In addition to the existing test just noted, I've also added a test to the new test case gdb.base/tls-nothreads.exp. It'll be tested, using different scenarios, up to 8 times: PASS: gdb.base/tls-nothreads.exp: default: force_internal_tls=false: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: default: force_internal_tls=true: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: static: force_internal_tls=false: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: static: force_internal_tls=true: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls=false: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls=true: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls=false: after exit: print tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls=true: after exit: print tls_tbss_1 There is a related problem that occurs when target_translate_tls_address is called from find_minsym_type_and_address() in minsyms.c. It can be observed when debugging a program without debugging symbols when the program is not executing. I've written a new test for this, but it's (also) included in the new test case gdb.base/tls-nothreads.exp, found later in this series. Depending on the target, it can run up to 8 times using different scenarios. E.g., on aarch64, I'm seeing these PASSes, all of which test this change: PASS: gdb.base/tls-nothreads.exp: default: force_internal_tls=false: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: default: force_internal_tls=true: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: static: force_internal_tls=false: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: static: force_internal_tls=true: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls=false: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads: force_internal_tls=true: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls=false: stripped: after exit: print (int) tls_tbss_1 PASS: gdb.base/tls-nothreads.exp: pthreads-static: force_internal_tls=true: stripped: after exit: print (int) tls_tbss_1 In an earlier version of this commit (v4), I was checking whether the target has registers in language_defn::read_var_value in findvar.c and in find_minsym_type_and_address in minsyms.c, printing suitable error messages in each case. In his review of this commit for the v4 series, Tom Tromey asked whether it would be better to do this check in target_translate_tls_address. I had considered doing that for the v4 (and earlier) series, but I wanted to print slightly different messages at each check. Also, read_var_value in findvar.c was already printing a message in some cases and I had arranged for the later check in that function to match the original message. However, while I had added a target-has-registers check at two of the call sites for target_translate_tls_address, I hadn't added it at the third call site which is in dwarf_expr_context::execute_stack_op() in dwarf2/expr.c. I believe that in most cases, this is handled by the early check in language_defn::read_var_value... else if (sym_need == SYMBOL_NEEDS_REGISTERS && !target_has_registers ()) error (_("Cannot read `%s' without registers"), var->print_name ()); ...but it's entirely possible that dwarf_expr_context::execute_stack_op() might get called in some other context. So it makes sense to do the target-has-registers check for that case too. And rather than add yet another check at that call site, I decided that moving the check and error message to target_translate_tls_address makes sense. I had to make the error messages that it prints somewhat more generic. In particular, when called from language_defn::read_var_value, the message printed by target_translate_tls_address no longer matches the earlier message that could be printed (as shown above). That meant that the test cases which check for this message, gdb.threads/tls.exp, and gdb.base/tls-nothreads.exp had to be adjusted to account for the new message. Also, I think it's valuable to the user to know (if possible) the name of the variable that caused the error, so I've added an optional parameter to target_translate_tls_address, providing the name of the variable, if it's known. Therefore, the message that's printed when the target-has-registers test fails is one of the following: When the TLS variable isn't known (due to being called from dwarf_expr_context::execute_stack_op): "Cannot translate TLS address without registers" When the TLS variable is known (from either of the other two call sites for target_translate_tls_address): "Cannot find address of TLS symbol `%s' without registers" Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=25807 --- gdb/findvar.c | 3 ++- gdb/minsyms.c | 3 ++- gdb/target.c | 16 +++++++++++++--- gdb/target.h | 8 +++++++- gdb/testsuite/gdb.threads/tls.exp | 2 +- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/gdb/findvar.c b/gdb/findvar.c index 1a9d2bedfc2..8c71d68ed31 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -485,7 +485,8 @@ language_defn::read_var_value (struct symbol *var, /* Determine address of TLS variable. */ if (obj_section && (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) - addr = target_translate_tls_address (obj_section->objfile, addr); + addr = target_translate_tls_address (obj_section->objfile, addr, + var->print_name ()); } break; diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 7b03e38de06..daa83325f30 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -1688,7 +1688,8 @@ find_minsym_type_and_address (minimal_symbol *msymbol, { /* Skip translation if caller does not need the address. */ if (address_p != NULL) - *address_p = target_translate_tls_address (objfile, addr); + *address_p = target_translate_tls_address + (objfile, addr, bound_msym.minsym->print_name ()); return builtin_type (objfile)->nodebug_tls_symbol; } diff --git a/gdb/target.c b/gdb/target.c index 8d7f168db84..210c81f7281 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1250,11 +1250,21 @@ generic_tls_error (void) _("Cannot find thread-local variables on this target")); } -/* Using the objfile specified in OBJFILE, find the address for the - current thread's thread-local storage with offset OFFSET. */ +/* See target.h. */ + CORE_ADDR -target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) +target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset, + const char *name) { + if (!target_has_registers ()) + { + if (name == nullptr) + error (_("Cannot translate TLS address without registers")); + else + error (_("Cannot find address of TLS symbol `%s' without registers"), + name); + } + volatile CORE_ADDR addr = 0; struct target_ops *target = current_inferior ()->top_target (); gdbarch *gdbarch = current_inferior ()->arch (); diff --git a/gdb/target.h b/gdb/target.h index 760d210aa3b..6b96b049ac0 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -2472,8 +2472,14 @@ extern void target_pre_inferior (); extern void target_preopen (int); +/* Using the objfile specified in OBJFILE, find the address for the + current thread's thread-local storage with offset OFFSET. If it's + provided, NAME might be used to indicate the relevant variable + in an error message. */ + extern CORE_ADDR target_translate_tls_address (struct objfile *objfile, - CORE_ADDR offset); + CORE_ADDR offset, + const char *name = nullptr); /* Return the "section" containing the specified address. */ const struct target_section *target_section_by_addr (struct target_ops *target, diff --git a/gdb/testsuite/gdb.threads/tls.exp b/gdb/testsuite/gdb.threads/tls.exp index c6fdb6f944d..1dcf269dd49 100644 --- a/gdb/testsuite/gdb.threads/tls.exp +++ b/gdb/testsuite/gdb.threads/tls.exp @@ -159,7 +159,7 @@ gdb_test_multiple "print a_thread_local" "" { -re -wrap "Cannot find thread-local variables on this target" { kfail "gdb/25807" $gdb_test_name } - -re -wrap "Cannot read .a_thread_local. without registers" { + -re -wrap "Cannot (?:read|find address of TLS symbol) .a_thread_local. without registers" { pass $gdb_test_name } } -- 2.48.1