public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
To: gdb-patches@sourceware.org
Cc: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
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	[thread overview]
Message-ID: <20230331034432.3037148-6-thiago.bauermann@linaro.org> (raw)
In-Reply-To: <20230331034432.3037148-1-thiago.bauermann@linaro.org>

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 <http://www.gnu.org/licenses/>.  */
+
+/* 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 <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+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 <http://www.gnu.org/licenses/>.
+
+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

  parent reply	other threads:[~2023-03-31  3:45 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-31  3:44 [PATCH 0/5] gdbserver: Follow-up on linux_get_auxv using PID parameter Thiago Jung Bauermann
2023-03-31  3:44 ` [PATCH 1/5] gdbserver: Use current_process in handle_qxfer_auxv Thiago Jung Bauermann
2023-03-31  3:44 ` [PATCH 2/5] gdbserver: Use the PID of the current process instead of the current thread Thiago Jung Bauermann
2023-03-31  3:44 ` [PATCH 3/5] gdbserver/linux: Read auxv from any thread of the process Thiago Jung Bauermann
2023-03-31  3:44 ` [PATCH 4/5] gdb/linux-nat: " Thiago Jung Bauermann
2023-03-31  3:44 ` Thiago Jung Bauermann [this message]
2023-04-04 14:00   ` [PATCH 5/5] gdb/testsuite: Add test that reads auxv in a multi-threaded inferior Alexandra Petlanova Hajkova
2023-04-04 15:19 ` [PATCH 0/5] gdbserver: Follow-up on linux_get_auxv using PID parameter Simon Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230331034432.3037148-6-thiago.bauermann@linaro.org \
    --to=thiago.bauermann@linaro.org \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).