From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oa1-x36.google.com (mail-oa1-x36.google.com [IPv6:2001:4860:4864:20::36]) by sourceware.org (Postfix) with ESMTPS id EE8BF3857026 for ; Fri, 31 Mar 2023 03:45:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EE8BF3857026 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-oa1-x36.google.com with SMTP id 586e51a60fabf-177b78067ffso21959664fac.7 for ; Thu, 30 Mar 2023 20:45:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1680234310; x=1682826310; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ac7/Oh+Oakk03EvK8CRN5RENmU65G5HTzB6gp91/uSk=; b=F6I0RpP3hn+ol34z1i25XW5xM/HF4PapGnTgfRJSAoX59IghP8S8f98VZHHTihSc4J JBooYwcrV5UDhQ4FwLOa69qiLDXUj/e5H5dprv63JYVAN+jrjFdfD0OoM9XP15s0rArH MI0Z57u7YUZn5c3b+2VUABNPbnORq3zouz6iQZ9ZEPU1QKKJJSVHIHP9bj5RY9X9lnlD zduST+gYT9B034yxBnoujnjeDFdorG/hNPmMXEatiUe0upOHjlM7jFfe9L0T3g9lsHtY 7MGih7xWjG8I6bgI5HVET4yaw8kDIRh8897Qscx/K7r+ePTH6g5+T/VEolVvSOWlE8bi 6hyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680234310; x=1682826310; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ac7/Oh+Oakk03EvK8CRN5RENmU65G5HTzB6gp91/uSk=; b=jUdocrmXRp3yAQ1LFnAwrNZT/X5wvhYcwJwMC7jOMNYODjdV+oF756g1mbkphRM2GY 9Qgbv7hXaufGOZffKWfdnVnPWOuevU6Xaw1dRD3sh2A2B0Y0UuLAo2DCwSWbE1txfDiu q4IGJWDp9Gdye5Q8R3oR3ReT/T44xZ+q6btsYd+IrZ9SrOSQ0m1x66WzuyKvN9lisvOL s5v3Iga0/KhssPrXiV9FkK7pPH758U85Se8gEEfgC8HIk63I+j2WFNQPc+Lh0bajF9B2 uXbLc3UHP97UtquYaC6D+sp5rfhEYnm5HZQ8y9B2XWGbt2X6a5+rkxp25Bq7O9bfLvQN yKLg== X-Gm-Message-State: AO0yUKVBa+QiZchesDvP1DGSWLEnsbwOMeUwc+62dyeiLhWKzUPi04t8 JF6usV+t1gvC/7cM85ew2sm/peCShhOOWQn4JOw= X-Google-Smtp-Source: AKy350a2N3csG+0v3o2AFHOhZimMmbCLyWcP5lEiDFLx44UJkTrAsiHjUSh7F57+9SZapVpISWsuaA== X-Received: by 2002:a05:6870:b48b:b0:17a:b378:8e1d with SMTP id y11-20020a056870b48b00b0017ab3788e1dmr16263158oap.0.1680234310172; Thu, 30 Mar 2023 20:45:10 -0700 (PDT) Received: from localhost ([177.124.15.55]) by smtp.gmail.com with ESMTPSA id k21-20020a0568301bf500b006a17bffbc61sm685644otb.38.2023.03.30.20.45.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Mar 2023 20:45:09 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann Subject: [PATCH 5/5] gdb/testsuite: Add test that reads auxv in a multi-threaded inferior Date: Fri, 31 Mar 2023 03:44:32 +0000 Message-Id: <20230331034432.3037148-6-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230331034432.3037148-1-thiago.bauermann@linaro.org> References: <20230331034432.3037148-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP 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: This test exercises reading the auxiliary vector in a program where the main thread exits before other threads. Because GDB's auxv cache makes it difficult to hit the race that this test exercises, add a maintenance command that flushes the cache. Also, move the fetch_auxv procedure from gdb.base/auxv to lib/gdb.exp so that the new testcase can use it. --- gdb/auxv.c | 16 ++++++++ gdb/testsuite/gdb.base/auxv.exp | 56 --------------------------- gdb/testsuite/gdb.threads/auxv.c | 62 ++++++++++++++++++++++++++++++ gdb/testsuite/gdb.threads/auxv.exp | 30 +++++++++++++++ gdb/testsuite/lib/gdb.exp | 62 ++++++++++++++++++++++++++++++ 5 files changed, 170 insertions(+), 56 deletions(-) create mode 100644 gdb/testsuite/gdb.threads/auxv.c create mode 100644 gdb/testsuite/gdb.threads/auxv.exp diff --git a/gdb/auxv.c b/gdb/auxv.c index 812b28075548..a39d8afd2990 100644 --- a/gdb/auxv.c +++ b/gdb/auxv.c @@ -27,6 +27,7 @@ #include "observable.h" #include "gdbsupport/filestuff.h" #include "objfiles.h" +#include "cli/cli-cmds.h" #include "auxv.h" #include "elf/common.h" @@ -602,6 +603,17 @@ info_auxv_command (const char *cmd, int from_tty) } } +/* Implement 'maint flush auxv' command. */ + +static void +auxv_flush_command (const char *command, int from_tty) +{ + /* Force-flush the auxv cache. */ + invalidate_auxv_cache(); + if (from_tty) + gdb_printf (_ ("Auxiliary vector cache flushed.\n")); +} + void _initialize_auxv (); void _initialize_auxv () @@ -610,6 +622,10 @@ _initialize_auxv () _("Display the inferior's auxiliary vector.\n\ This is information provided by the operating system at program startup.")); + add_cmd ("auxv-cache", class_maintenance, auxv_flush_command, + _ ("Force gdb to flush its auxiliary vector cache."), + &maintenanceflushlist); + /* Observers used to invalidate the auxv cache when needed. */ gdb::observers::inferior_exit.attach (invalidate_auxv_cache_inf, "auxv"); gdb::observers::inferior_appeared.attach (invalidate_auxv_cache_inf, "auxv"); diff --git a/gdb/testsuite/gdb.base/auxv.exp b/gdb/testsuite/gdb.base/auxv.exp index 89242b6f4321..7f58bd318fbc 100644 --- a/gdb/testsuite/gdb.base/auxv.exp +++ b/gdb/testsuite/gdb.base/auxv.exp @@ -59,62 +59,6 @@ set print_core_line [gdb_get_line_number "ABORT;"] gdb_test "tbreak $print_core_line" gdb_test continue ".*ABORT;.*" -proc fetch_auxv {test} { - global gdb_prompt - - set auxv_lines {} - set bad -1 - # Former trailing `\[\r\n\]+' may eat just \r leaving \n in the buffer - # corrupting the next matches. - if {[gdb_test_multiple "info auxv" $test { - -re "info auxv\r\n" { - exp_continue - } - -ex "The program has no auxiliary information now" { - set bad 1 - exp_continue - } - -ex "Auxiliary vector is empty" { - set bad 1 - exp_continue - } - -ex "No auxiliary vector found" { - set bad 1 - exp_continue - } - -re "^\[0-9\]+\[ \t\]+(AT_\[^ \t\]+)\[^\r\n\]+\r\n" { - lappend auxv_lines $expect_out(0,string) - exp_continue - } - -re "^\[0-9\]+\[ \t\]+\\?\\?\\?\[^\r\n\]+\r\n" { - warning "Unrecognized tag value: $expect_out(0,string)" - set bad 1 - lappend auxv_lines $expect_out(0,string) - exp_continue - } - -re "$gdb_prompt $" { - incr bad - } - -re "^\[^\r\n\]+\r\n" { - if {!$bad} { - warning "Unrecognized output: $expect_out(0,string)" - set bad 1 - } - exp_continue - } - }] != 0} { - return {} - } - - if {$bad} { - fail $test - return {} - } - - pass $test - return $auxv_lines -} - set live_data [fetch_auxv "info auxv on live process"] # Now try gcore. diff --git a/gdb/testsuite/gdb.threads/auxv.c b/gdb/testsuite/gdb.threads/auxv.c new file mode 100644 index 000000000000..5ad280145c89 --- /dev/null +++ b/gdb/testsuite/gdb.threads/auxv.c @@ -0,0 +1,62 @@ +/* Copyright 2023 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +/* This program creates an additional thread and then exits the leader thread. + It uses semaphores so that GDB can stop the program at specific points and + test how it deals with accessing the auxv information of a multi-threaded + program in different moments of the thread life cycle. */ + +#include +#include +#include +#include +#include +#include + +static volatile pthread_t main_thread; + +static void * +subthread (void *arg) +{ + int rc; + + rc = pthread_join (main_thread, NULL); + if (rc != 0) + fprintf (stderr, "Warning: pthread_join failed: %s\n", strerror (rc)); + + return NULL; /* Main thread exited. */ +} + +int +main (int argc, char *argv[]) +{ + int rc; + pthread_t thread_id; + + main_thread = pthread_self (); + + rc = pthread_create (&thread_id, NULL, &subthread, NULL); + if (rc != 0) + { + fprintf (stderr, "Error: pthread_create failed: %s\n", strerror (rc)); + return EXIT_FAILURE; + } + + pthread_exit (NULL); + /* NOTREACHED */ + return EXIT_FAILURE; +} diff --git a/gdb/testsuite/gdb.threads/auxv.exp b/gdb/testsuite/gdb.threads/auxv.exp new file mode 100644 index 000000000000..1ad3564642bd --- /dev/null +++ b/gdb/testsuite/gdb.threads/auxv.exp @@ -0,0 +1,30 @@ +# Test 'info auxv' and related functionality with a multi-threaded inferior. + +# Copyright (C) 2023 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 . + +standard_testfile +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + {debug pthreads}] } { + return +} + +if ![runto ${srcfile}:[gdb_get_line_number "Main thread exited."]] { + return +} + +gdb_test -nopass "maintenance flush auxv-cache" "Auxiliary vector cache flushed." + +fetch_auxv "Get auxv after main thread exits" diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 14ce39e8ed72..8dd79ba5008a 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -7821,6 +7821,68 @@ proc get_var_address { var } { return "" } +# Retrieve the auxiliary vector from the inferior. +# +# Issues a pass/fail using TEST as the message, reflecting whether the "info auxv" +# command worked. +# +# Returns the command's output. +proc fetch_auxv {test} { + global gdb_prompt + + set auxv_lines {} + set bad -1 + # Former trailing `\[\r\n\]+' may eat just \r leaving \n in the buffer + # corrupting the next matches. + if {[gdb_test_multiple "info auxv" $test { + -re "info auxv\r\n" { + exp_continue + } + -ex "The program has no auxiliary information now" { + set bad 1 + exp_continue + } + -ex "Auxiliary vector is empty" { + set bad 1 + exp_continue + } + -ex "No auxiliary vector found" { + set bad 1 + exp_continue + } + -re "^\[0-9\]+\[ \t\]+(AT_\[^ \t\]+)\[^\r\n\]+\r\n" { + lappend auxv_lines $expect_out(0,string) + exp_continue + } + -re "^\[0-9\]+\[ \t\]+\\?\\?\\?\[^\r\n\]+\r\n" { + warning "Unrecognized tag value: $expect_out(0,string)" + set bad 1 + lappend auxv_lines $expect_out(0,string) + exp_continue + } + -re "$gdb_prompt $" { + incr bad + } + -re "^\[^\r\n\]+\r\n" { + if {!$bad} { + warning "Unrecognized output: $expect_out(0,string)" + set bad 1 + } + exp_continue + } + }] != 0} { + return {} + } + + if {$bad} { + fail $test + return {} + } + + pass $test + return $auxv_lines +} + # Return the frame number for the currently selected frame proc get_current_frame_number {{test_name ""}} { global gdb_prompt