From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 2mYhMCUSDWlwXCcAWB0awg (envelope-from ) for ; Thu, 06 Nov 2025 16:24:53 -0500 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=VmWyTPcs; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id B66181E04C; Thu, 06 Nov 2025 16:24:53 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.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,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED 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 4A20F1E04C for ; Thu, 06 Nov 2025 16:24:52 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DFB5C385276C for ; Thu, 6 Nov 2025 21:24:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DFB5C385276C 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=VmWyTPcs Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 1072C3858415 for ; Thu, 6 Nov 2025 21:20:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1072C3858415 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 1072C3858415 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1762464009; cv=none; b=TdpTBHv/cSXyFs4nqcfRrEdxH+oanh8X8CNcGLVYf2N5NLlbrR/ETQ8N5SFMZ+IVIJGbyfhb1e3t3iAlaYMnz7WW127GrxMd7v2+wqL7VXw5I1D3u9nRZkozqbyC648+QUdqnfEF4UUdpubeG5u9YnH8JAnvNj8PzwLSXlKftT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1762464009; c=relaxed/simple; bh=tqYNy22peRI8+nMantRj4X9H/aOTXGBoIDrfty9JceY=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=qIJJTh8IknirzGN4gXj9kHAvKo0zhjouqskVXxmvaOV3C/1/mnYf+RTWfsWnMudyAyogHtCSMXOV9wksOLfx9bkiNK6zyTjtGEV+HS+KylM05KtYafcR6S3y3qIxk6z0yq3FcPTbjW7bmeyZDgDag1imzbFeUEwnWnEy+gzoh98= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1072C3858415 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762464008; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g0eaLP5XfyhPAnU9UqYaHFU7GqfoedMMxo0s/JqQi7M=; b=VmWyTPcss7tlGYON/0bFz2ew5/I/SZmYMQpOGVCUzF8VvnqX/Ch+F72CViNvuVQV15qq6i X9Y4Omp4tEfgdEBCMygBor537XpllPLBqmjBy3iPAO2lWauklFfXsVbDV0Eoi8vFDYiwnm 40VXFCnyykCm+2JfbOTkB1/v183em7o= Received: from mail-pg1-f200.google.com (mail-pg1-f200.google.com [209.85.215.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-371-8NyGr0-6PbGOvoCM_cLSbA-1; Thu, 06 Nov 2025 16:20:07 -0500 X-MC-Unique: 8NyGr0-6PbGOvoCM_cLSbA-1 X-Mimecast-MFC-AGG-ID: 8NyGr0-6PbGOvoCM_cLSbA_1762464006 Received: by mail-pg1-f200.google.com with SMTP id 41be03b00d2f7-b6ce1b57b3eso136217a12.1 for ; Thu, 06 Nov 2025 13:20:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762464006; x=1763068806; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=g0eaLP5XfyhPAnU9UqYaHFU7GqfoedMMxo0s/JqQi7M=; b=uKqkEYo2mLcjI4OsB3W9V9iHlvDOrNQ58ZkxUlbzbr2neALAg4PCIkht0xTM4ZMpzh 4q1osvcK+vEcYVwSFNEyi0dPryDTp69EEbii2wfuKK4yVdoAaGGvzxiP6k/fHBvDgfMV E1wmHKpswnooTIiTHFnyJuxnDkl9QCDkrGOVZFSGV4VdoHs9jMH4nMxgoYxvVOKezw6A lR7L+Dxje2uKVcixicZ8Ae0pLJx53Ry1lNu0FMLPJPDHv7dX624Yo9HoQwZH6h4c5pAu I9zSwYVoc7el4fuXljnScQ1rERcxmtgK6Rui6oKOMfUGB/gZwZ9mO8hlyeGcjp6dFC93 +OzQ== X-Forwarded-Encrypted: i=1; AJvYcCUIGsJK67ULtewol8fw6UEDoRQ/UmlmidSrrfOm+Iusq00FUCn1JmMKbMAbUdsT/kw3wanEjcJw89nitw==@sourceware.org X-Gm-Message-State: AOJu0YzZ9REzHLei4Xs1qqR7eJOZ50i/uXvEmeV0exUuYGLkC8Fseho+ UDkXuJWRv6pCRdn+qjUfASziu8O5k5juHGNFXLN5ftzcAf2+p2mc13yTAFyZ3sm6JllIGdydyGN dzdUuKCNdsIUFO5WJw/8QMNtJz9JVguuiEuzWM+wyOSKYOsz6k5FwM6n6UT3dS3HBRhMO0gQ= X-Gm-Gg: ASbGnctOJm5MJriN7vfNZpRja8e0D3rvxVKNPNNCZx/sIQ2Dpey7TztuCJq/ibl+s4u REcd2IcrJIN3ZYTsbc1gvLEbXDGQBp1oOutbYPW8RiJXiKk+nHVuryKFJXhDwNd58JUnMFNYGDG HYvWwl+TO3posDCWMS90TsAOVFgrCLpg9avVjkbXX54FwAdgpidQVRMRX7ruHJf+7xF9x29YMju KOE51pgwlq//uGpWqiwSIGBWjnWa1iQwzYot4JNT/ZFt3nO0W8RNKzr1XPG6a4Jn8wlPXJe0guU g1UZs3gFTn9pMtW9YRU0JVB5ogkGqUnInmy3C/vyKoHGTuBgm+DOPNApMsofbG6wUPZ7iXpNJkK ZcnBA/A== X-Received: by 2002:a05:6a20:a109:b0:33b:bce3:31c2 with SMTP id adf61e73a8af0-35228274fb5mr1473304637.20.1762464005557; Thu, 06 Nov 2025 13:20:05 -0800 (PST) X-Google-Smtp-Source: AGHT+IFulndKt440ZL+bS3ulj+VJkFElR5KV5AajyR0nuY1WoOKCIykEnYSAhjPJznMCBTmItU3oOA== X-Received: by 2002:a05:6a20:a109:b0:33b:bce3:31c2 with SMTP id adf61e73a8af0-35228274fb5mr1473273637.20.1762464005015; Thu, 06 Nov 2025 13:20:05 -0800 (PST) Received: from [150.1.200.157] ([172.56.105.134]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7b0cc866319sm498863b3a.54.2025.11.06.13.20.04 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 06 Nov 2025 13:20:04 -0800 (PST) Message-ID: <83120a5b-3448-421b-9ac5-8d1c12ed2fa6@redhat.com> Date: Thu, 6 Nov 2025 13:20:02 -0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCHv4] gdb: include NT_I386_TLS note in generated core files To: Andrew Burgess , gdb-patches@sourceware.org References: <730728a6858a3fcf4477ebe3895088c98f0fead2.1760450001.git.aburgess@redhat.com> From: Keith Seitz In-Reply-To: X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: keszJQwGkQAqUk0YEOCoZewn_4KVganMpqZdTbs0Srw_1762464006 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit 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 Hi, On 11/5/25 5:57 AM, Andrew Burgess wrote: > In v4: > > - Updated based on Christina's feedback. > > - Removed excessive use of 'struct' throughout the patch. > > - Fixed whitespace issue in comment. > > - Renamed test to remove 'linux-', this is inline with all the other > Linux specific tests, which don't have 'linux' in their name. > > - Changed 'return -1' to 'return' in the test script. > > - Updated test to handle case where kernel produced core file > doesn't work, e.g. system is configured to not allow the kernel to > dump core. Test will now report 'unsupported'. > > - Updated gdbserver changes so fetch_tls_area_register and > store_tls_area_register now return 'void'. These functions have > been updated to give a warning if something goes wrong. > > - Rebased onto something more recent, reran the patch specific test > only as the changes above are all minor and shouldn't impact > anything outside of this change. Thank you for these updates. I have tested this patch as thoroughly as I am able, and you have fixed all the issues about which we have spoken (privately). I am quite a bit outside my comfort zone, so take my review with a very large grain of salt. Nonetheless, I've only detected one trivial matter that needs addressing. Reviewed-By: Keith Seitz Keith > diff --git a/gdb/testsuite/gdb.arch/i386-tls-regs.exp b/gdb/testsuite/gdb.arch/i386-tls-regs.exp > new file mode 100644 > index 00000000000..1753f8762c6 > --- /dev/null > +++ b/gdb/testsuite/gdb.arch/i386-tls-regs.exp > @@ -0,0 +1,335 @@ > +# Copyright 2025 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 . > + > +# Check that the TLS GDT registers are available for i386 executable. > + > +require {is_any_target "i?86-*-linux*" "x86_64-*-linux*"} > + > +standard_testfile > + > +set options {debug pthreads} > +if {![istarget "i386-*-*"]} { > + lappend options "additional_flags=-m32" > +} > + > +# Check that we can actually compile a 32-bit executable. > +# > +# It is possible that even with the above setting of OPTIONS, we might > +# still get a 64-bit executable, for example, running on x86-64 with > +# '--target_board=unix/-m64' will add the -m64 after the above -m32, > +# meaning we always end up with a 64-bit executable. > +# > +# If the following compiles then we are getting a 32-bit executable. > +if {![gdb_can_simple_compile is_lp64_target { > + int dummy[sizeof (int) == 4 > + && sizeof (void *) == 4 > + && sizeof (long) == 4 ? 1 : -1];} \ > + object $options]} { > + unsupported "cannot compile 32-bit executable" > + return > +} > + > +if { [build_executable "failed to prepare" $testfile $srcfile $options] } { > + return > +} > + > +# Start an inferior and check we can read and modify the TLS registers. > +proc_with_prefix test_tls_reg_availability {} { > + clean_restart $::testfile > + > + if {![runto_main]} { > + return > + } > + > + set tls_reg_vals { "" "" "" } > + gdb_test_multiple "info registers system" "check for TLS regs" { > + -re "^info registers system\r\n" { > + exp_continue > + } > + -re "^i386_tls_gdt_(\\d) \\{($::hex), ($::hex), ($::hex), ($::hex)\\}\r\n" { > + set idx $expect_out(1,string) > + set val0 $expect_out(2,string) > + set val1 $expect_out(3,string) > + set val2 $expect_out(4,string) > + set val3 $expect_out(5,string) > + set val [list $val0 $val1 $val2 $val3] > + set tls_reg_vals [lreplace $tls_reg_vals $idx $idx $val] > + exp_continue > + } > + -re "^$::gdb_prompt $" { > + gdb_assert {[lsearch -exact $tls_reg_vals ""] == -1} $gdb_test_name > + } > + -re "^\[^\r\n\]+\r\n" { > + exp_continue > + } > + } > + > + if { [lindex $tls_reg_vals 0] != [lindex $tls_reg_vals 1] } { > + set new_vals [lindex $tls_reg_vals 0] > + set old_vals [lindex $tls_reg_vals 1] > + > + set val0 [lindex $old_vals 0] > + set val1 [lindex $new_vals 1] > + set val2 [lindex $new_vals 2] > + set val3 [lindex $new_vals 3] > + > + set new_val_str "{$val0, $val1, $val2, $val3}" > + > + gdb_test_no_output "set \$i386_tls_gdt_1 = $new_val_str" > + set re [string_to_regexp $new_val_str] > + gdb_test "print /x \$i386_tls_gdt_1" " = $re" > + } > + > + gdb_test_no_output "set should_dump_core_p=0" > + gdb_test_no_output "set wait_for_gdb_p=0" > + > + gdb_continue_to_end "" continue true > +} > + > +# Start GDB using global BINFILE, load COREFILE (which must match > +# BINFILE), and check that the core has two threads, that the TLS > +# registers are visible in both threads, and that the TLS register > +# values are different in each thread. > +proc load_core_and_test_tls_regs { corefile } { > + clean_restart $::testfile > + > + gdb_core_cmd $corefile "load corefile" > + > + gdb_test "info threads" \ > + [multi_line \ > + "\\*\\s+1\\s+Thread \[^\r\n\]+" \ > + "\\s+2\\s+Thread \[^\r\n\]+"] \ > + "check for two threads" > + > + # Record the TLS values in thread 1. > + set tls_reg_vals_thr_1 { "" "" "" } > + gdb_test_multiple "info registers system" "check for TLS regs thread 1" { > + -re "^info registers system\r\n" { > + exp_continue > + } > + -re "^i386_tls_gdt_(\\d) (\\{$::hex, $::hex, $::hex, $::hex\\})\r\n" { > + set idx $expect_out(1,string) > + set val $expect_out(2,string) > + set tls_reg_vals_thr_1 [lreplace $tls_reg_vals_thr_1 $idx $idx $val] > + exp_continue > + } > + -re "^$::gdb_prompt $" { > + gdb_assert {[lsearch -exact $tls_reg_vals_thr_1 ""] == -1} $gdb_test_name > + } > + -re "^\[^\r\n\]+\r\n" { > + exp_continue > + } > + } > + > + # Check a TLS variable in thread 1. > + gdb_test "print local_var" " = 1" \ > + "check TLS variable in thread 1" > + > + # Switch to thread 2 and confirm the values are different. > + gdb_test "thread 2" > + > + set tls_reg_vals_thr_2 { "" "" "" } > + gdb_test_multiple "info registers system" "check for TLS regs thread 2" { > + -re "^info registers system\r\n" { > + exp_continue > + } > + -re "^i386_tls_gdt_(\\d) (\\{$::hex, $::hex, $::hex, $::hex\\})\r\n" { > + set idx $expect_out(1,string) > + set val $expect_out(2,string) > + set tls_reg_vals_thr_2 \ > + [lreplace $tls_reg_vals_thr_2 $idx $idx $val] > + exp_continue > + } > + -re "^$::gdb_prompt $" { > + gdb_assert {[lsearch -exact $tls_reg_vals_thr_2 ""] == -1} \ > + $gdb_test_name > + } > + -re "^\[^\r\n\]+\r\n" { > + exp_continue > + } > + } > + > + # Check a TLS variable in thread 2. > + gdb_test "print local_var" " = 2" \ > + "check TLS variable in thread 2" > + > + set all_same [expr [lindex $tls_reg_vals_thr_1 0] == [lindex $tls_reg_vals_thr_2 0] \ > + && [lindex $tls_reg_vals_thr_1 1] == [lindex $tls_reg_vals_thr_2 1] \ > + && [lindex $tls_reg_vals_thr_1 2] == [lindex $tls_reg_vals_thr_2 2]] gdb.src/pre-commit.exp flags this line as a tclint violation of unbraced-expr (the test fails): https://wiki.tcl-lang.org/page/Brace+your+expr-essions > + gdb_assert {!$all_same} \ > + "tls regs are different between threads" > +} > + > +# Generate a core file using the gcore command. Load it into GDB and > +# check we can still read the TLS registers. > +proc_with_prefix test_gcore_tls {} { > + > + if {![gcore_cmd_available]} { > + unsupported "gcore command not available" > + return > + } > + > + clean_restart $::testfile > + > + if {![runto_main]} { > + return > + } > + > + gdb_test_no_output "set should_dump_core_p=0" > + > + gdb_breakpoint crash_func > + gdb_continue_to_breakpoint "stop at crash_func" > + > + set corefile [standard_output_file ${::testfile}.gcore] > + if {![gdb_gcore_cmd $corefile "dump core"]} { > + return > + } > + > + set readelf_program [gdb_find_readelf] > + set res [catch {exec $readelf_program -n $corefile} output] > + if { $res != 0 } { > + unresolved "unable to run readelf to check for TLS notes" > + return > + } > + set lines [split $output \n] > + set tls_count 0 > + foreach line $lines { > + if {[regexp "^\\s+LINUX\\s+$::hex\\s+NT_386_TLS" $line]} { > + incr tls_count > + } > + } > + gdb_assert {$tls_count == 2} \ > + "expected number of TLS notes" > + > + load_core_and_test_tls_regs $corefile > +} > + > +# Generate a core file using the gcore command, but before doing so, > +# clear all the TLS related GDT entries. When the TLS GDT entries > +# have a base address and limit of zero the kernel doesn't emit the > +# NT_386_TLS note, GDB copies this behaviour. > +proc_with_prefix test_gcore_no_tls {} { > + > + if {![gcore_cmd_available]} { > + unsupported "gcore command not available" > + return > + } > + > + clean_restart $::testfile > + > + if {![runto_main]} { > + return > + } > + > + gdb_test_no_output "set should_dump_core_p=0" > + > + gdb_breakpoint crash_func > + gdb_continue_to_breakpoint "stop at crash_func" > + > + # Clear the TLS registers in each thread. > + foreach_with_prefix thr { 1 2 } { > + gdb_test "thread $thr" ".*" \ > + "switch thread to clear tls regs" > + gdb_test_no_output "set \$i386_tls_gdt_0 = { 0x0, 0x0, 0x0, 0x28 }" > + gdb_test_no_output "set \$i386_tls_gdt_1 = { 0x0, 0x0, 0x0, 0x28 }" > + gdb_test_no_output "set \$i386_tls_gdt_2 = { 0x0, 0x0, 0x0, 0x28 }" > + } > + > + set corefile [standard_output_file ${::testfile}.gcore] > + if {![gdb_gcore_cmd $corefile "dump core"]} { > + return > + } > + > + # Look in the core file for NT_386_TLS entries. There should be > + # none. > + set readelf_program [gdb_find_readelf] > + set res [catch {exec $readelf_program -n $corefile} output] > + if { $res != 0 } { > + unresolved "unable to run readelf to check for TLS notes" > + return > + } > + set lines [split $output \n] > + set tls_count 0 > + foreach line $lines { > + if {[regexp "^\\s+LINUX\\s+$::hex\\s+NT_386_TLS" $line]} { > + incr tls_count > + } > + } > + gdb_assert {$tls_count == 0} \ > + "expected number of TLS notes" > + > + # Restart GDB and load the core file. As there are no NT_386_TLS > + # entries the TLS registers should show as unavailable. > + clean_restart $::testfile > + > + gdb_core_cmd $corefile "load corefile" > + > + gdb_test "info threads" \ > + [multi_line \ > + "\\*\\s+1\\s+Thread \[^\r\n\]+" \ > + "\\s+2\\s+Thread \[^\r\n\]+"] \ > + "check for two threads" > + > + foreach_with_prefix thr { 1 2 } { > + set unavailable_tls_count 0 > + set valid_tls_count 0 > + gdb_test "thread $thr" ".*" \ > + "switch thread to check TLS register status" > + gdb_test_multiple "info registers system" "check TLS reg values" { > + -re "^info registers system\r\n" { > + exp_continue > + } > + -re "^i386_tls_gdt_\\d \\{, , , \\}\r\n" { > + incr unavailable_tls_count > + exp_continue > + } > + -re "^i386_tls_gdt_\\d \[^\r\n\]+\r\n" { > + incr valid_tls_count > + exp_continue > + } > + > + -re "^$::gdb_prompt $" { > + gdb_assert {$valid_tls_count == 0 && \ > + $unavailable_tls_count == 3} \ > + $gdb_test_name > + } > + -re "^\[^\r\n\]+\r\n" { > + exp_continue > + } > + } > + > + # Check a TLS variable in this thread. > + gdb_test "print local_var" " = $thr" \ > + "check TLS variable in thread $thr" > + } > +} > + > +# Generate a native core file. Load it into GDB and check the TLS > +# registers can be read. > +proc_with_prefix test_native_core {} { > + set corefile [core_find $::binfile] > + if { $corefile eq "" } { > + unsupported "unable to generate core file" > + return > + } > + > + load_core_and_test_tls_regs $corefile > +} > + > +# Run the tests. > +test_tls_reg_availability > +test_gcore_tls > +test_gcore_no_tls > +test_native_core