public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Querying registers of already-exited processes
@ 2022-02-08  9:15 Tankut Baris Aktemur
  2022-02-08  9:15 ` [PATCH v2 1/2] gdb/regcache: return REG_UNAVAILABLE if raw_update raises NOT_AVAILABLE_ERROR Tankut Baris Aktemur
                   ` (4 more replies)
  0 siblings, 5 replies; 28+ messages in thread
From: Tankut Baris Aktemur @ 2022-02-08  9:15 UTC (permalink / raw)
  To: gdb-patches

Hello,

This series can be considered a continuation of

  commit 4778a5f87d253399083565b4919816f541ebe414
  Author: Tom de Vries <tdevries@suse.de>
  Date:   Tue Apr 21 15:45:57 2020 +0200

    [gdb] Fix hang after ext sigkill

and

  commit 47f1aceffa02be4726b854082d7587eb259136e0
  Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
  Date:   Thu May 14 13:59:54 2020 +0200

    gdb/infrun: handle already-exited threads when attempting to stop

The starting point was PR gdb/26877:

  https://sourceware.org/bugzilla/show_bug.cgi?id=26877

Revision v1 of the series is available at

  https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html

The v2 is a rebase of the series on the current master, and a ping for
reviews. :)

Regards
Baris

Tankut Baris Aktemur (2):
  gdb/regcache: return REG_UNAVAILABLE if raw_update raises
    NOT_AVAILABLE_ERROR
  gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC

 gdb/amd64-linux-nat.c                         |  3 +-
 gdb/regcache.c                                | 11 ++-
 gdb/remote.c                                  | 20 +++--
 gdb/stack.c                                   | 33 +++++++-
 gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
 .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
 .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
 7 files changed, 162 insertions(+), 13 deletions(-)
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp

-- 
2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v2 1/2] gdb/regcache: return REG_UNAVAILABLE if raw_update raises NOT_AVAILABLE_ERROR
  2022-02-08  9:15 [PATCH v2 0/2] Querying registers of already-exited processes Tankut Baris Aktemur
@ 2022-02-08  9:15 ` Tankut Baris Aktemur
  2022-03-16 15:18   ` Bruno Larsen
  2022-02-08  9:15 ` [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 28+ messages in thread
From: Tankut Baris Aktemur @ 2022-02-08  9:15 UTC (permalink / raw)
  To: gdb-patches

In regcache's raw_read, it is possible that 'raw_update' fails with an
exception.  Catch this exception and return REG_UNAVAILABLE if the
error is of kind NOT_AVAILABLE_ERROR.  This makes clients' lives easier.

Regression-tested on X86_64-Linux.
---
 gdb/regcache.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gdb/regcache.c b/gdb/regcache.c
index 00d7a10e289..0379e6a8d0f 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -598,7 +598,16 @@ enum register_status
 readable_regcache::raw_read (int regnum, gdb_byte *buf)
 {
   gdb_assert (buf != NULL);
-  raw_update (regnum);
+  try
+    {
+      raw_update (regnum);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      if (ex.error == NOT_AVAILABLE_ERROR)
+	return REG_UNAVAILABLE;
+      throw;
+    }
 
   if (m_register_status[regnum] != REG_VALID)
     memset (buf, 0, m_descr->sizeof_register[regnum]);
-- 
2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2022-02-08  9:15 [PATCH v2 0/2] Querying registers of already-exited processes Tankut Baris Aktemur
  2022-02-08  9:15 ` [PATCH v2 1/2] gdb/regcache: return REG_UNAVAILABLE if raw_update raises NOT_AVAILABLE_ERROR Tankut Baris Aktemur
@ 2022-02-08  9:15 ` Tankut Baris Aktemur
  2022-03-16 17:26   ` Bruno Larsen
  2022-02-22  7:31 ` [PATCH v2 0/2] Querying registers of already-exited processes Aktemur, Tankut Baris
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 28+ messages in thread
From: Tankut Baris Aktemur @ 2022-02-08  9:15 UTC (permalink / raw)
  To: gdb-patches

This patch can be considered a continuation of

  commit 4778a5f87d253399083565b4919816f541ebe414
  Author: Tom de Vries <tdevries@suse.de>
  Date:   Tue Apr 21 15:45:57 2020 +0200

    [gdb] Fix hang after ext sigkill

and

  commit 47f1aceffa02be4726b854082d7587eb259136e0
  Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
  Date:   Thu May 14 13:59:54 2020 +0200

    gdb/infrun: handle already-exited threads when attempting to stop

If a process dies before GDB reports the exit error to the user, we
may see the "Couldn't get registers: No such process." error message
in various places.  For instance:

  (gdb) start
  ...
  (gdb) info inferior
    Num  Description       Connection           Executable
  * 1    process 31943     1 (native)           /tmp/a.out
  (gdb) shell kill -9 31943
  (gdb) maintenance flush register-cache
  Register cache flushed.
  Couldn't get registers: No such process.
  (gdb) info threads
    Id   Target Id              Frame
  * 1    process 31943 "a.out" Couldn't get registers: No such process.
  (gdb) backtrace
  Python Exception <class 'gdb.error'>: Couldn't get registers: No such process.
  Couldn't get registers: No such process.
  (gdb) inferior 1
  Couldn't get registers: No such process.
  (gdb) thread
  [Current thread is 1 (process 31943)]
  Couldn't get registers: No such process.
  (gdb)

The gdb.threads/killed-outside.exp, gdb.multi/multi-kill.exp, and
gdb.multi/multi-exit.exp tests also check related scenarios.

To improve the situation,

1. when printing the frame info, catch and process a NOT_AVAILABLE_ERROR.

2. when accessing the target to fetch registers, if the operation
   fails, raise a NOT_AVAILABLE_ERROR instead of a generic error, so
   that clients can attempt to recover accordingly.  This patch updates
   the amd64_linux_nat_target and remote_target in this direction.

With this patch, we obtain the following behavior:

  (gdb) start
  ...
  (gdb) info inferior
    Num  Description       Connection           Executable
  * 1    process 748       1 (native)           /tmp/a.out
  (gdb) shell kill -9 748
  (gdb) maintenance flush register-cache
  Register cache flushed.
  (gdb) info threads
    Id   Target Id           Frame
  * 1    process 748 "a.out" <PC register is not available>
  (gdb) backtrace
  #0  <PC register is not available>
  Backtrace stopped: not enough registers or memory available to unwind further
  (gdb) inferior 1
  [Switching to inferior 1 [process 748] (/tmp/a.out)]
  [Switching to thread 1 (process 748)]
  #0  <PC register is not available>
  (gdb) thread
  [Current thread is 1 (process 748)]
  (gdb)

Here is another "before/after" case.  Suppose we have two inferiors,
each having its own remote target underneath.  Before this patch, we
get the following output:

  # Create two inferiors on two remote targets, resume both until
  # termination.  Exit event from one of them is shown first, but the
  # other also exited -- just not yet shown.
  (gdb) maint set target-non-stop on
  (gdb) target remote | gdbserver - ./a.out
  (gdb) add-inferior -no-connection
  (gdb) inferior 2
  (gdb) target remote | gdbserver - ./a.out
  (gdb) set schedule-multiple on
  (gdb) continue
  ...
  [Inferior 2 (process 22127) exited normally]
  (gdb) inferior 1
  [Switching to inferior 1 [process 22111] (target:/tmp/a.out)]
  [Switching to thread 1.1 (Thread 22111.22111)]
  Could not read registers; remote failure reply 'E01'
  (gdb) info threads
    Id   Target Id                  Frame
  * 1.1  Thread 22111.22111 "a.out" Could not read registers; remote failure reply 'E01'
  (gdb) backtrace
  Python Exception <class 'gdb.error'>: Could not read registers; remote failure reply 'E01'
  Could not read registers; remote failure reply 'E01'
  (gdb) thread
  [Current thread is 1.1 (Thread 22111.22111)]
  Could not read registers; remote failure reply 'E01'
  (gdb)

With this patch, it becomes:

  ...
  [Inferior 1 (process 11759) exited normally]
  (gdb) inferior 2
  [Switching to inferior 2 [process 13440] (target:/path/to/a.out)]
  [Switching to thread 2.1 (Thread 13440.13440)]
  #0  <unavailable> in ?? ()
  (gdb) info threads
    Id   Target Id                   Frame
  * 2.1  Thread 13440.13440 "a.out" <unavailable> in ?? ()
  (gdb) backtrace
  #0  <unavailable> in ?? ()
  Backtrace stopped: not enough registers or memory available to unwind further
  (gdb) thread
  [Current thread is 2.1 (Thread 13440.13440)]
  (gdb)

Finally, together with its predecessor, this patch also fixes PR gdb/26877.

Regression-tested on X86_64-Linux.
---
 gdb/amd64-linux-nat.c                         |  3 +-
 gdb/remote.c                                  | 20 +++--
 gdb/stack.c                                   | 33 +++++++-
 gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
 .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
 .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
 6 files changed, 152 insertions(+), 12 deletions(-)
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp

diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 3d28d7e1d57..bdcc93eb498 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -222,7 +222,8 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
       elf_gregset_t regs;
 
       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
-	perror_with_name (_("Couldn't get registers"));
+	throw_perror_with_name (NOT_AVAILABLE_ERROR,
+				_("Couldn't get registers"));
 
       amd64_supply_native_gregset (regcache, &regs, -1);
       if (regnum != -1)
diff --git a/gdb/remote.c b/gdb/remote.c
index 49eeb63445d..936084b9b4a 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -8398,10 +8398,14 @@ remote_target::fetch_register_using_p (struct regcache *regcache,
     case PACKET_UNKNOWN:
       return 0;
     case PACKET_ERROR:
-      error (_("Could not fetch register \"%s\"; remote failure reply '%s'"),
-	     gdbarch_register_name (regcache->arch (), 
-				    reg->regnum), 
-	     buf);
+      {
+	const char *regname = gdbarch_register_name (regcache->arch (),
+						     reg->regnum);
+	std::string msg
+	  = string_printf (_("Could not fetch register \"%s\"; remote "
+			     "failure reply '%s'"), regname, buf);
+	throw_perror_with_name (NOT_AVAILABLE_ERROR, msg.c_str ());
+      }
     }
 
   /* If this register is unfetchable, tell the regcache.  */
@@ -8438,8 +8442,12 @@ remote_target::send_g_packet ()
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
   if (packet_check_result (rs->buf) == PACKET_ERROR)
-    error (_("Could not read registers; remote failure reply '%s'"),
-	   rs->buf.data ());
+    {
+      std::string msg
+	= string_printf (_("Could not read registers; remote failure reply "
+			   "'%s'"), rs->buf.data ());
+      throw_perror_with_name (NOT_AVAILABLE_ERROR, msg.c_str ());
+    }
 
   /* We can get out of synch in various cases.  If the first character
      in the buffer is not a hex character, assume that has happened
diff --git a/gdb/stack.c b/gdb/stack.c
index b1bbf7d0f44..47faec5a124 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1107,7 +1107,38 @@ print_frame_info (const frame_print_options &fp_opts,
      the next frame is a SIGTRAMP_FRAME or a DUMMY_FRAME, then the
      next frame was not entered as the result of a call, and we want
      to get the line containing FRAME->pc.  */
-  symtab_and_line sal = find_frame_sal (frame);
+  symtab_and_line sal;
+  try
+    {
+      sal = find_frame_sal (frame);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      if (ex.error == NOT_AVAILABLE_ERROR)
+	{
+	  ui_out_emit_tuple tuple_emitter (uiout, "frame");
+
+	  annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
+				gdbarch, 0);
+
+	  if (print_level)
+	    {
+	      uiout->text ("#");
+	      uiout->field_fmt_signed (2, ui_left, "level",
+				       frame_relative_level (frame));
+	    }
+
+	  std::string frame_info = "<";
+	  frame_info += ex.what ();
+	  frame_info += ">";
+	  uiout->field_string ("func", frame_info.c_str (),
+			       metadata_style.style ());
+	  uiout->text ("\n");
+	  annotate_frame_end ();
+	  return;
+	}
+      throw;
+    }
 
   location_print = (print_what == LOCATION
 		    || print_what == SRC_AND_LOC
diff --git a/gdb/testsuite/gdb.threads/killed-outside.exp b/gdb/testsuite/gdb.threads/killed-outside.exp
index 3d4543e088c..8e156c863dc 100644
--- a/gdb/testsuite/gdb.threads/killed-outside.exp
+++ b/gdb/testsuite/gdb.threads/killed-outside.exp
@@ -37,16 +37,15 @@ remote_exec target "kill -9 ${testpid}"
 # Give it some time to die.
 sleep 2
 
-set no_such_process_msg "Couldn't get registers: No such process\."
+set no_pc_available_msg "PC register is not available"
 set killed_msg "Program terminated with signal SIGKILL, Killed\."
 set no_longer_exists_msg "The program no longer exists\."
 set not_being_run_msg "The program is not being run\."
 
 gdb_test_multiple "continue" "prompt after first continue" {
-    -re "Continuing\.\r\n$no_such_process_msg\r\n$gdb_prompt " {
+    -re "Continuing\.\r\n$no_pc_available_msg\r\n$gdb_prompt " {
 	pass $gdb_test_name
-	# Saw $no_such_process_msg.  The bug condition was triggered, go
-	# check for it.
+	# The bug condition was triggered, go check for it.
 	gdb_test_multiple "" "messages" {
 	    -re ".*$killed_msg.*$no_longer_exists_msg\r\n" {
 		pass $gdb_test_name
diff --git a/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
new file mode 100644
index 00000000000..d934d74fbb7
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
@@ -0,0 +1,21 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2020 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/>.  */
+
+int main() {
+  int a = 42;
+  return 0; /* break-here */
+}
diff --git a/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
new file mode 100644
index 00000000000..10eb69500cc
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
@@ -0,0 +1,80 @@
+# Copyright 2020 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/>.
+#
+# This is a regression test for PR gdb/26877.
+
+tuiterm_env
+
+standard_testfile
+
+if {[use_gdb_stub]} {
+    return 0
+}
+
+if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} {
+    return -1
+}
+
+# Make sure TUI is supported before continuing.
+with_test_prefix "initial check" {
+    Term::clean_restart 24 80 $testfile
+    if {![Term::enter_tui]} {
+	unsupported "TUI not supported"
+	return
+    }
+}
+
+Term::clean_restart 24 80 $testfile
+
+# Create a setting with two inferiors, where both are stopped
+# at a breakpoint at the end of main.  Then resume both.
+set bp [gdb_get_line_number "break-here"]
+gdb_breakpoint "$bp"
+
+with_test_prefix "inferior 1" {
+    gdb_run_cmd
+    gdb_test "" ".*reakpoint \[^\r\n\]+${srcfile}.*" "run until bp"
+}
+
+with_test_prefix "inferior 2" {
+    gdb_test "add-inferior -exec [standard_output_file $testfile]" \
+	"Added inferior 2.*" "add inferior"
+    gdb_test "inferior 2" "Switching to inferior 2.*" "switch"
+    gdb_run_cmd
+    gdb_test "" ".*reakpoint \[^\r\n\]+${srcfile}.*" "run until bp"
+}
+
+gdb_test_no_output "set schedule-multiple on"
+gdb_continue_to_end
+
+# Find out which inferior is current.  It is the inferior that exited.
+set exited_inf [get_integer_valueof {$_inferior} 1 "current inf"]
+
+# Switch to the other inferior and remove the exited one.
+# Bad GDB used to crash when this is done under TUI.
+if {![Term::enter_tui]} {
+    unsupported "TUI not supported"
+    return
+}
+
+if {$exited_inf == 1} {
+    Term::command "inferior 2"
+} else {
+    Term::command "inferior 1"
+}
+
+Term::command "remove-inferiors $exited_inf"
+Term::command "info inferior $exited_inf"
+Term::check_contents "inferior is removed" "No inferiors."
-- 
2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v2 0/2] Querying registers of already-exited processes
  2022-02-08  9:15 [PATCH v2 0/2] Querying registers of already-exited processes Tankut Baris Aktemur
  2022-02-08  9:15 ` [PATCH v2 1/2] gdb/regcache: return REG_UNAVAILABLE if raw_update raises NOT_AVAILABLE_ERROR Tankut Baris Aktemur
  2022-02-08  9:15 ` [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
@ 2022-02-22  7:31 ` Aktemur, Tankut Baris
  2022-03-07  8:00 ` Aktemur, Tankut Baris
  2022-03-23 13:05 ` [PATCH v3 " Tankut Baris Aktemur
  4 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2022-02-22  7:31 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

Thanks
-Baris

On Tuesday, February 8, 2022 10:15 AM, Aktemur, Tankut Baris wrote: 
> Hello,
> 
> This series can be considered a continuation of
> 
>   commit 4778a5f87d253399083565b4919816f541ebe414
>   Author: Tom de Vries <tdevries@suse.de>
>   Date:   Tue Apr 21 15:45:57 2020 +0200
> 
>     [gdb] Fix hang after ext sigkill
> 
> and
> 
>   commit 47f1aceffa02be4726b854082d7587eb259136e0
>   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>   Date:   Thu May 14 13:59:54 2020 +0200
> 
>     gdb/infrun: handle already-exited threads when attempting to stop
> 
> The starting point was PR gdb/26877:
> 
>   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> 
> Revision v1 of the series is available at
> 
>   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> 
> The v2 is a rebase of the series on the current master, and a ping for
> reviews. :)
> 
> Regards
> Baris
> 
> Tankut Baris Aktemur (2):
>   gdb/regcache: return REG_UNAVAILABLE if raw_update raises
>     NOT_AVAILABLE_ERROR
>   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> 
>  gdb/amd64-linux-nat.c                         |  3 +-
>  gdb/regcache.c                                | 11 ++-
>  gdb/remote.c                                  | 20 +++--
>  gdb/stack.c                                   | 33 +++++++-
>  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
>  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
>  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
>  7 files changed, 162 insertions(+), 13 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
>  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> 
> --
> 2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v2 0/2] Querying registers of already-exited processes
  2022-02-08  9:15 [PATCH v2 0/2] Querying registers of already-exited processes Tankut Baris Aktemur
                   ` (2 preceding siblings ...)
  2022-02-22  7:31 ` [PATCH v2 0/2] Querying registers of already-exited processes Aktemur, Tankut Baris
@ 2022-03-07  8:00 ` Aktemur, Tankut Baris
  2022-03-23 13:05 ` [PATCH v3 " Tankut Baris Aktemur
  4 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2022-03-07  8:00 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

Thanks
-Baris

On Tuesday, February 8, 2022 10:15 AM, Aktemur, Tankut Baris wrote: 
> Hello,
> 
> This series can be considered a continuation of
> 
>   commit 4778a5f87d253399083565b4919816f541ebe414
>   Author: Tom de Vries <tdevries@suse.de>
>   Date:   Tue Apr 21 15:45:57 2020 +0200
> 
>     [gdb] Fix hang after ext sigkill
> 
> and
> 
>   commit 47f1aceffa02be4726b854082d7587eb259136e0
>   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>   Date:   Thu May 14 13:59:54 2020 +0200
> 
>     gdb/infrun: handle already-exited threads when attempting to stop
> 
> The starting point was PR gdb/26877:
> 
>   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> 
> Revision v1 of the series is available at
> 
>   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> 
> The v2 is a rebase of the series on the current master, and a ping for
> reviews. :)
> 
> Regards
> Baris
> 
> Tankut Baris Aktemur (2):
>   gdb/regcache: return REG_UNAVAILABLE if raw_update raises
>     NOT_AVAILABLE_ERROR
>   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> 
>  gdb/amd64-linux-nat.c                         |  3 +-
>  gdb/regcache.c                                | 11 ++-
>  gdb/remote.c                                  | 20 +++--
>  gdb/stack.c                                   | 33 +++++++-
>  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
>  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
>  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
>  7 files changed, 162 insertions(+), 13 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
>  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> 
> --
> 2.33.1
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v2 1/2] gdb/regcache: return REG_UNAVAILABLE if raw_update raises NOT_AVAILABLE_ERROR
  2022-02-08  9:15 ` [PATCH v2 1/2] gdb/regcache: return REG_UNAVAILABLE if raw_update raises NOT_AVAILABLE_ERROR Tankut Baris Aktemur
@ 2022-03-16 15:18   ` Bruno Larsen
  2022-03-23 12:55     ` Aktemur, Tankut Baris
  0 siblings, 1 reply; 28+ messages in thread
From: Bruno Larsen @ 2022-03-16 15:18 UTC (permalink / raw)
  To: Tankut Baris Aktemur, gdb-patches

Hello Tankut,

On 2/8/22 06:15, Tankut Baris Aktemur via Gdb-patches wrote:
> In regcache's raw_read, it is possible that 'raw_update' fails with an
> exception.  Catch this exception and return REG_UNAVAILABLE if the
> error is of kind NOT_AVAILABLE_ERROR.  This makes clients' lives easier.

This looks like a good idea for a change. I just have a few small comments.

Firstly, I'm not sure this change is complex enough to warrant its own commit, since - from what I can see - there is no noticeable change in GDB, and the patch itself is quite small, it could maybe just be part of patch 2. However, I am not a global maintainer or very experienced in patch review, so take this comment with a grain of salt. If the commits do stay separate, I would add a mention of raw_read in the commit title, otherwise which function is returning REG_UNAVAILABLE is not mentioned at all.

Also, the commit message is not very descriptive of what could cause the exception in the first place, and I feel like that could be good for future reference, but this may just be my GDB inexperience speaking.

> 
> Regression-tested on X86_64-Linux.
> ---
>   gdb/regcache.c | 11 ++++++++++-
>   1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/gdb/regcache.c b/gdb/regcache.c
> index 00d7a10e289..0379e6a8d0f 100644
> --- a/gdb/regcache.c
> +++ b/gdb/regcache.c
> @@ -598,7 +598,16 @@ enum register_status
>   readable_regcache::raw_read (int regnum, gdb_byte *buf)
>   {
>     gdb_assert (buf != NULL);
> -  raw_update (regnum);
> +  try
> +    {
> +      raw_update (regnum);
> +    }
> +  catch (const gdb_exception_error &ex)
> +    {
> +      if (ex.error == NOT_AVAILABLE_ERROR)
> +	return REG_UNAVAILABLE;

Lastly, Since this function is returning as if nothing unexpected happened, it should probably also set buf to 0 and possibly set m_register_status to REG_UNAVAILABLE - if it isn't set by whatever throws the exception.

> +      throw;> +    }
>   
>     if (m_register_status[regnum] != REG_VALID)
>       memset (buf, 0, m_descr->sizeof_register[regnum]);


-- 
Cheers!
Bruno Larsen


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2022-02-08  9:15 ` [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
@ 2022-03-16 17:26   ` Bruno Larsen
  2022-03-23 12:55     ` Aktemur, Tankut Baris
  0 siblings, 1 reply; 28+ messages in thread
From: Bruno Larsen @ 2022-03-16 17:26 UTC (permalink / raw)
  To: Tankut Baris Aktemur, gdb-patches

Hello Tankut,

On 2/8/22 06:15, Tankut Baris Aktemur via Gdb-patches wrote:
> This patch can be considered a continuation of
> 
>    commit 4778a5f87d253399083565b4919816f541ebe414
>    Author: Tom de Vries <tdevries@suse.de>
>    Date:   Tue Apr 21 15:45:57 2020 +0200
> 
>      [gdb] Fix hang after ext sigkill
> 
> and
> 
>    commit 47f1aceffa02be4726b854082d7587eb259136e0
>    Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>    Date:   Thu May 14 13:59:54 2020 +0200
> 
>      gdb/infrun: handle already-exited threads when attempting to stop
> 
> If a process dies before GDB reports the exit error to the user, we
> may see the "Couldn't get registers: No such process." error message
> in various places.  For instance:
> 
>    (gdb) start
>    ...
>    (gdb) info inferior
>      Num  Description       Connection           Executable
>    * 1    process 31943     1 (native)           /tmp/a.out
>    (gdb) shell kill -9 31943
>    (gdb) maintenance flush register-cache
>    Register cache flushed.
>    Couldn't get registers: No such process.
>    (gdb) info threads
>      Id   Target Id              Frame
>    * 1    process 31943 "a.out" Couldn't get registers: No such process.
>    (gdb) backtrace
>    Python Exception <class 'gdb.error'>: Couldn't get registers: No such process.
>    Couldn't get registers: No such process.
>    (gdb) inferior 1
>    Couldn't get registers: No such process.
>    (gdb) thread
>    [Current thread is 1 (process 31943)]
>    Couldn't get registers: No such process.
>    (gdb)
> 
> The gdb.threads/killed-outside.exp, gdb.multi/multi-kill.exp, and
> gdb.multi/multi-exit.exp tests also check related scenarios.
> 
> To improve the situation,
> 
> 1. when printing the frame info, catch and process a NOT_AVAILABLE_ERROR.
> 
> 2. when accessing the target to fetch registers, if the operation
>     fails, raise a NOT_AVAILABLE_ERROR instead of a generic error, so
>     that clients can attempt to recover accordingly.  This patch updates
>     the amd64_linux_nat_target and remote_target in this direction.
> 
> With this patch, we obtain the following behavior:
> 
>    (gdb) start
>    ...
>    (gdb) info inferior
>      Num  Description       Connection           Executable
>    * 1    process 748       1 (native)           /tmp/a.out
>    (gdb) shell kill -9 748
>    (gdb) maintenance flush register-cache
>    Register cache flushed.
>    (gdb) info threads
>      Id   Target Id           Frame
>    * 1    process 748 "a.out" <PC register is not available>
>    (gdb) backtrace
>    #0  <PC register is not available>
>    Backtrace stopped: not enough registers or memory available to unwind further
>    (gdb) inferior 1
>    [Switching to inferior 1 [process 748] (/tmp/a.out)]
>    [Switching to thread 1 (process 748)]
>    #0  <PC register is not available>
>    (gdb) thread
>    [Current thread is 1 (process 748)]
>    (gdb)
> 
> Here is another "before/after" case.  Suppose we have two inferiors,
> each having its own remote target underneath.  Before this patch, we
> get the following output:
> 
>    # Create two inferiors on two remote targets, resume both until
>    # termination.  Exit event from one of them is shown first, but the
>    # other also exited -- just not yet shown.
>    (gdb) maint set target-non-stop on
>    (gdb) target remote | gdbserver - ./a.out
>    (gdb) add-inferior -no-connection
>    (gdb) inferior 2
>    (gdb) target remote | gdbserver - ./a.out
>    (gdb) set schedule-multiple on
>    (gdb) continue
>    ...
>    [Inferior 2 (process 22127) exited normally]
>    (gdb) inferior 1
>    [Switching to inferior 1 [process 22111] (target:/tmp/a.out)]
>    [Switching to thread 1.1 (Thread 22111.22111)]
>    Could not read registers; remote failure reply 'E01'
>    (gdb) info threads
>      Id   Target Id                  Frame
>    * 1.1  Thread 22111.22111 "a.out" Could not read registers; remote failure reply 'E01'
>    (gdb) backtrace
>    Python Exception <class 'gdb.error'>: Could not read registers; remote failure reply 'E01'
>    Could not read registers; remote failure reply 'E01'
>    (gdb) thread
>    [Current thread is 1.1 (Thread 22111.22111)]
>    Could not read registers; remote failure reply 'E01'
>    (gdb)
> 
> With this patch, it becomes:
> 
>    ...
>    [Inferior 1 (process 11759) exited normally]
>    (gdb) inferior 2
>    [Switching to inferior 2 [process 13440] (target:/path/to/a.out)]
>    [Switching to thread 2.1 (Thread 13440.13440)]
>    #0  <unavailable> in ?? ()
>    (gdb) info threads
>      Id   Target Id                   Frame
>    * 2.1  Thread 13440.13440 "a.out" <unavailable> in ?? ()
>    (gdb) backtrace
>    #0  <unavailable> in ?? ()
>    Backtrace stopped: not enough registers or memory available to unwind further
>    (gdb) thread
>    [Current thread is 2.1 (Thread 13440.13440)]
>    (gdb)
> 
> Finally, together with its predecessor, this patch also fixes PR gdb/26877.

While I think this is a good idea, it doesn't seem to fix the root cause of the bug you mentioned. It does stop the crash that the bug reports, but I would say the actual issue is that GDB is not noticing that the second inferior is also finished. My 2 cents, for what they're worth.

The explanation in the commit message is great! It explains the problem quite well, I just don't understand why you only changed amd64_linux_nat_target and remote. I imagine this issue happens with all targets. I'd ask at least that some of the most common ones be changed and validated. Also, some extra testing revealed that the previous patch is not actually necessary to fix the crash.

As for technical review, I don't have any questions or comments, but I can't approve patches.


-- 
Cheers!
Bruno Larsen
> 
> Regression-tested on X86_64-Linux.
> ---
>   gdb/amd64-linux-nat.c                         |  3 +-
>   gdb/remote.c                                  | 20 +++--
>   gdb/stack.c                                   | 33 +++++++-
>   gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
>   .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
>   .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
>   6 files changed, 152 insertions(+), 12 deletions(-)
>   create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
>   create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> 
> diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
> index 3d28d7e1d57..bdcc93eb498 100644
> --- a/gdb/amd64-linux-nat.c
> +++ b/gdb/amd64-linux-nat.c
> @@ -222,7 +222,8 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
>         elf_gregset_t regs;
>   
>         if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
> -	perror_with_name (_("Couldn't get registers"));
> +	throw_perror_with_name (NOT_AVAILABLE_ERROR,
> +				_("Couldn't get registers"));
>   
>         amd64_supply_native_gregset (regcache, &regs, -1);
>         if (regnum != -1)
> diff --git a/gdb/remote.c b/gdb/remote.c
> index 49eeb63445d..936084b9b4a 100644
> --- a/gdb/remote.c
> +++ b/gdb/remote.c
> @@ -8398,10 +8398,14 @@ remote_target::fetch_register_using_p (struct regcache *regcache,
>       case PACKET_UNKNOWN:
>         return 0;
>       case PACKET_ERROR:
> -      error (_("Could not fetch register \"%s\"; remote failure reply '%s'"),
> -	     gdbarch_register_name (regcache->arch (),
> -				    reg->regnum),
> -	     buf);
> +      {
> +	const char *regname = gdbarch_register_name (regcache->arch (),
> +						     reg->regnum);
> +	std::string msg
> +	  = string_printf (_("Could not fetch register \"%s\"; remote "
> +			     "failure reply '%s'"), regname, buf);
> +	throw_perror_with_name (NOT_AVAILABLE_ERROR, msg.c_str ());
> +      }
>       }
>   
>     /* If this register is unfetchable, tell the regcache.  */
> @@ -8438,8 +8442,12 @@ remote_target::send_g_packet ()
>     putpkt (rs->buf);
>     getpkt (&rs->buf, 0);
>     if (packet_check_result (rs->buf) == PACKET_ERROR)
> -    error (_("Could not read registers; remote failure reply '%s'"),
> -	   rs->buf.data ());
> +    {
> +      std::string msg
> +	= string_printf (_("Could not read registers; remote failure reply "
> +			   "'%s'"), rs->buf.data ());
> +      throw_perror_with_name (NOT_AVAILABLE_ERROR, msg.c_str ());
> +    }
>   
>     /* We can get out of synch in various cases.  If the first character
>        in the buffer is not a hex character, assume that has happened
> diff --git a/gdb/stack.c b/gdb/stack.c
> index b1bbf7d0f44..47faec5a124 100644
> --- a/gdb/stack.c
> +++ b/gdb/stack.c
> @@ -1107,7 +1107,38 @@ print_frame_info (const frame_print_options &fp_opts,
>        the next frame is a SIGTRAMP_FRAME or a DUMMY_FRAME, then the
>        next frame was not entered as the result of a call, and we want
>        to get the line containing FRAME->pc.  */
> -  symtab_and_line sal = find_frame_sal (frame);
> +  symtab_and_line sal;
> +  try
> +    {
> +      sal = find_frame_sal (frame);
> +    }
> +  catch (const gdb_exception_error &ex)
> +    {
> +      if (ex.error == NOT_AVAILABLE_ERROR)
> +	{
> +	  ui_out_emit_tuple tuple_emitter (uiout, "frame");
> +
> +	  annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
> +				gdbarch, 0);
> +
> +	  if (print_level)
> +	    {
> +	      uiout->text ("#");
> +	      uiout->field_fmt_signed (2, ui_left, "level",
> +				       frame_relative_level (frame));
> +	    }
> +
> +	  std::string frame_info = "<";
> +	  frame_info += ex.what ();
> +	  frame_info += ">";
> +	  uiout->field_string ("func", frame_info.c_str (),
> +			       metadata_style.style ());
> +	  uiout->text ("\n");
> +	  annotate_frame_end ();
> +	  return;
> +	}
> +      throw;
> +    }
>   
>     location_print = (print_what == LOCATION
>   		    || print_what == SRC_AND_LOC
> diff --git a/gdb/testsuite/gdb.threads/killed-outside.exp b/gdb/testsuite/gdb.threads/killed-outside.exp
> index 3d4543e088c..8e156c863dc 100644
> --- a/gdb/testsuite/gdb.threads/killed-outside.exp
> +++ b/gdb/testsuite/gdb.threads/killed-outside.exp
> @@ -37,16 +37,15 @@ remote_exec target "kill -9 ${testpid}"
>   # Give it some time to die.
>   sleep 2
>   
> -set no_such_process_msg "Couldn't get registers: No such process\."
> +set no_pc_available_msg "PC register is not available"
>   set killed_msg "Program terminated with signal SIGKILL, Killed\."
>   set no_longer_exists_msg "The program no longer exists\."
>   set not_being_run_msg "The program is not being run\."
>   
>   gdb_test_multiple "continue" "prompt after first continue" {
> -    -re "Continuing\.\r\n$no_such_process_msg\r\n$gdb_prompt " {
> +    -re "Continuing\.\r\n$no_pc_available_msg\r\n$gdb_prompt " {
>   	pass $gdb_test_name
> -	# Saw $no_such_process_msg.  The bug condition was triggered, go
> -	# check for it.
> +	# The bug condition was triggered, go check for it.
>   	gdb_test_multiple "" "messages" {
>   	    -re ".*$killed_msg.*$no_longer_exists_msg\r\n" {
>   		pass $gdb_test_name
> diff --git a/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
> new file mode 100644
> index 00000000000..d934d74fbb7
> --- /dev/null
> +++ b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
> @@ -0,0 +1,21 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2020 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/>.  */
> +
> +int main() {
> +  int a = 42;
> +  return 0; /* break-here */
> +}
> diff --git a/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> new file mode 100644
> index 00000000000..10eb69500cc
> --- /dev/null
> +++ b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> @@ -0,0 +1,80 @@
> +# Copyright 2020 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/>.
> +#
> +# This is a regression test for PR gdb/26877.
> +
> +tuiterm_env
> +
> +standard_testfile
> +
> +if {[use_gdb_stub]} {
> +    return 0
> +}
> +
> +if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} {
> +    return -1
> +}
> +
> +# Make sure TUI is supported before continuing.
> +with_test_prefix "initial check" {
> +    Term::clean_restart 24 80 $testfile
> +    if {![Term::enter_tui]} {
> +	unsupported "TUI not supported"
> +	return
> +    }
> +}
> +
> +Term::clean_restart 24 80 $testfile
> +
> +# Create a setting with two inferiors, where both are stopped
> +# at a breakpoint at the end of main.  Then resume both.
> +set bp [gdb_get_line_number "break-here"]
> +gdb_breakpoint "$bp"
> +
> +with_test_prefix "inferior 1" {
> +    gdb_run_cmd
> +    gdb_test "" ".*reakpoint \[^\r\n\]+${srcfile}.*" "run until bp"
> +}
> +
> +with_test_prefix "inferior 2" {
> +    gdb_test "add-inferior -exec [standard_output_file $testfile]" \
> +	"Added inferior 2.*" "add inferior"
> +    gdb_test "inferior 2" "Switching to inferior 2.*" "switch"
> +    gdb_run_cmd
> +    gdb_test "" ".*reakpoint \[^\r\n\]+${srcfile}.*" "run until bp"
> +}
> +
> +gdb_test_no_output "set schedule-multiple on"
> +gdb_continue_to_end
> +
> +# Find out which inferior is current.  It is the inferior that exited.
> +set exited_inf [get_integer_valueof {$_inferior} 1 "current inf"]
> +
> +# Switch to the other inferior and remove the exited one.
> +# Bad GDB used to crash when this is done under TUI.
> +if {![Term::enter_tui]} {
> +    unsupported "TUI not supported"
> +    return
> +}
> +
> +if {$exited_inf == 1} {
> +    Term::command "inferior 2"
> +} else {
> +    Term::command "inferior 1"
> +}
> +
> +Term::command "remove-inferiors $exited_inf"
> +Term::command "info inferior $exited_inf"
> +Term::check_contents "inferior is removed" "No inferiors."


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v2 1/2] gdb/regcache: return REG_UNAVAILABLE if raw_update raises NOT_AVAILABLE_ERROR
  2022-03-16 15:18   ` Bruno Larsen
@ 2022-03-23 12:55     ` Aktemur, Tankut Baris
  0 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2022-03-23 12:55 UTC (permalink / raw)
  To: Bruno Larsen, gdb-patches

On Wednesday, March 16, 2022 4:19 PM, Bruno Larsen wrote:
> Hello Tankut,

Hi Bruno,

Thanks for your comments.

> On 2/8/22 06:15, Tankut Baris Aktemur via Gdb-patches wrote:
> > In regcache's raw_read, it is possible that 'raw_update' fails with an
> > exception.  Catch this exception and return REG_UNAVAILABLE if the
> > error is of kind NOT_AVAILABLE_ERROR.  This makes clients' lives easier.
> 
> This looks like a good idea for a change. I just have a few small comments.
> 
> Firstly, I'm not sure this change is complex enough to warrant its own commit, since - from
> what I can see - there is no noticeable change in GDB, and the patch itself is quite small,
> it could maybe just be part of patch 2. However, I am not a global maintainer or very
> experienced in patch review, so take this comment with a grain of salt.

My motivation was that 'raw_read' is a central, low-level utility function.
The second patch is about adapting the users.  Let me keep the patches separate
until a global maintainers requests merging them.

> If the commits do
> stay separate, I would add a mention of raw_read in the commit title, otherwise which
> function is returning REG_UNAVAILABLE is not mentioned at all.

Done.

> Also, the commit message is not very descriptive of what could cause the exception in the
> first place, and I feel like that could be good for future reference, but this may just be
> my GDB inexperience speaking.

I added
"This could happen, for instance, if the debugged thread is
already exited and the target cannot fetch its registers."

> >
> > Regression-tested on X86_64-Linux.
> > ---
> >   gdb/regcache.c | 11 ++++++++++-
> >   1 file changed, 10 insertions(+), 1 deletion(-)
> >
> > diff --git a/gdb/regcache.c b/gdb/regcache.c
> > index 00d7a10e289..0379e6a8d0f 100644
> > --- a/gdb/regcache.c
> > +++ b/gdb/regcache.c
> > @@ -598,7 +598,16 @@ enum register_status
> >   readable_regcache::raw_read (int regnum, gdb_byte *buf)
> >   {
> >     gdb_assert (buf != NULL);
> > -  raw_update (regnum);
> > +  try
> > +    {
> > +      raw_update (regnum);
> > +    }
> > +  catch (const gdb_exception_error &ex)
> > +    {
> > +      if (ex.error == NOT_AVAILABLE_ERROR)
> > +	return REG_UNAVAILABLE;
> 
> Lastly, Since this function is returning as if nothing unexpected happened, it should
> probably also set buf to 0 and possibly set m_register_status to REG_UNAVAILABLE - if it
> isn't set by whatever throws the exception.

I modified the patch as below.  The rest of the function handles setting
the contents of buf to 0 and returning m_register_status[regnum], which is
set to REG_UNAVAILABLE in the catch block.

diff --git a/gdb/regcache.c b/gdb/regcache.c
index 00d7a10e289..c57d2e4c345 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -598,7 +598,17 @@ enum register_status
 readable_regcache::raw_read (int regnum, gdb_byte *buf)
 {
   gdb_assert (buf != NULL);
-  raw_update (regnum);
+  try
+    {
+      raw_update (regnum);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      if (ex.error != NOT_AVAILABLE_ERROR)
+       throw;
+
+      m_register_status[regnum] = REG_UNAVAILABLE;
+    }

   if (m_register_status[regnum] != REG_VALID)
     memset (buf, 0, m_descr->sizeof_register[regnum]);


Regards
-Baris


Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2022-03-16 17:26   ` Bruno Larsen
@ 2022-03-23 12:55     ` Aktemur, Tankut Baris
  2022-03-23 13:34       ` Bruno Larsen
  0 siblings, 1 reply; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2022-03-23 12:55 UTC (permalink / raw)
  To: Bruno Larsen, gdb-patches

On Wednesday, March 16, 2022 6:27 PM, Bruno Larsen wrote:
> Hello Tankut,
> 
> On 2/8/22 06:15, Tankut Baris Aktemur via Gdb-patches wrote:
> > This patch can be considered a continuation of
> >
> >    commit 4778a5f87d253399083565b4919816f541ebe414
> >    Author: Tom de Vries <tdevries@suse.de>
> >    Date:   Tue Apr 21 15:45:57 2020 +0200
> >
> >      [gdb] Fix hang after ext sigkill
> >
> > and
> >
> >    commit 47f1aceffa02be4726b854082d7587eb259136e0
> >    Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> >    Date:   Thu May 14 13:59:54 2020 +0200
> >
> >      gdb/infrun: handle already-exited threads when attempting to stop
> >
> > If a process dies before GDB reports the exit error to the user, we
> > may see the "Couldn't get registers: No such process." error message
> > in various places.  For instance:
> >
> >    (gdb) start
> >    ...
> >    (gdb) info inferior
> >      Num  Description       Connection           Executable
> >    * 1    process 31943     1 (native)           /tmp/a.out
> >    (gdb) shell kill -9 31943
> >    (gdb) maintenance flush register-cache
> >    Register cache flushed.
> >    Couldn't get registers: No such process.
> >    (gdb) info threads
> >      Id   Target Id              Frame
> >    * 1    process 31943 "a.out" Couldn't get registers: No such process.
> >    (gdb) backtrace
> >    Python Exception <class 'gdb.error'>: Couldn't get registers: No such process.
> >    Couldn't get registers: No such process.
> >    (gdb) inferior 1
> >    Couldn't get registers: No such process.
> >    (gdb) thread
> >    [Current thread is 1 (process 31943)]
> >    Couldn't get registers: No such process.
> >    (gdb)
> >
> > The gdb.threads/killed-outside.exp, gdb.multi/multi-kill.exp, and
> > gdb.multi/multi-exit.exp tests also check related scenarios.
> >
> > To improve the situation,
> >
> > 1. when printing the frame info, catch and process a NOT_AVAILABLE_ERROR.
> >
> > 2. when accessing the target to fetch registers, if the operation
> >     fails, raise a NOT_AVAILABLE_ERROR instead of a generic error, so
> >     that clients can attempt to recover accordingly.  This patch updates
> >     the amd64_linux_nat_target and remote_target in this direction.
> >
> > With this patch, we obtain the following behavior:
> >
> >    (gdb) start
> >    ...
> >    (gdb) info inferior
> >      Num  Description       Connection           Executable
> >    * 1    process 748       1 (native)           /tmp/a.out
> >    (gdb) shell kill -9 748
> >    (gdb) maintenance flush register-cache
> >    Register cache flushed.
> >    (gdb) info threads
> >      Id   Target Id           Frame
> >    * 1    process 748 "a.out" <PC register is not available>
> >    (gdb) backtrace
> >    #0  <PC register is not available>
> >    Backtrace stopped: not enough registers or memory available to unwind further
> >    (gdb) inferior 1
> >    [Switching to inferior 1 [process 748] (/tmp/a.out)]
> >    [Switching to thread 1 (process 748)]
> >    #0  <PC register is not available>
> >    (gdb) thread
> >    [Current thread is 1 (process 748)]
> >    (gdb)
> >
> > Here is another "before/after" case.  Suppose we have two inferiors,
> > each having its own remote target underneath.  Before this patch, we
> > get the following output:
> >
> >    # Create two inferiors on two remote targets, resume both until
> >    # termination.  Exit event from one of them is shown first, but the
> >    # other also exited -- just not yet shown.
> >    (gdb) maint set target-non-stop on
> >    (gdb) target remote | gdbserver - ./a.out
> >    (gdb) add-inferior -no-connection
> >    (gdb) inferior 2
> >    (gdb) target remote | gdbserver - ./a.out
> >    (gdb) set schedule-multiple on
> >    (gdb) continue
> >    ...
> >    [Inferior 2 (process 22127) exited normally]
> >    (gdb) inferior 1
> >    [Switching to inferior 1 [process 22111] (target:/tmp/a.out)]
> >    [Switching to thread 1.1 (Thread 22111.22111)]
> >    Could not read registers; remote failure reply 'E01'
> >    (gdb) info threads
> >      Id   Target Id                  Frame
> >    * 1.1  Thread 22111.22111 "a.out" Could not read registers; remote failure reply 'E01'
> >    (gdb) backtrace
> >    Python Exception <class 'gdb.error'>: Could not read registers; remote failure reply
> 'E01'
> >    Could not read registers; remote failure reply 'E01'
> >    (gdb) thread
> >    [Current thread is 1.1 (Thread 22111.22111)]
> >    Could not read registers; remote failure reply 'E01'
> >    (gdb)
> >
> > With this patch, it becomes:
> >
> >    ...
> >    [Inferior 1 (process 11759) exited normally]
> >    (gdb) inferior 2
> >    [Switching to inferior 2 [process 13440] (target:/path/to/a.out)]
> >    [Switching to thread 2.1 (Thread 13440.13440)]
> >    #0  <unavailable> in ?? ()
> >    (gdb) info threads
> >      Id   Target Id                   Frame
> >    * 2.1  Thread 13440.13440 "a.out" <unavailable> in ?? ()
> >    (gdb) backtrace
> >    #0  <unavailable> in ?? ()
> >    Backtrace stopped: not enough registers or memory available to unwind further
> >    (gdb) thread
> >    [Current thread is 2.1 (Thread 13440.13440)]
> >    (gdb)
> >
> > Finally, together with its predecessor, this patch also fixes PR gdb/26877.
> 
> While I think this is a good idea, it doesn't seem to fix the root cause of the bug you
> mentioned. It does stop the crash that the bug reports, but I would say the actual issue is
> that GDB is not noticing that the second inferior is also finished. My 2 cents, for what
> they're worth.

The root cause was an unhandled error in a destructor.  The 2-inferior setup was
just one way to expose it.  From https://sourceware.org/bugzilla/show_bug.cgi?id=26877#c0:

	The problem is at:

	#20 0x00005555561128b9 in program_space::~program_space (this=0x55555830a070, __in_chrg=<optimized out>) at gdb/progspace.c:153

	While inside a destructor, GDB wanted to access the frame information
	of Inferior 2 in a series of calls.  But because the process is dead, its
	registers cannot be read.  This raises an error inside a destructor, leading
	to termination of GDB.

From that perspective, I think the root cause is fixed.

> The explanation in the commit message is great! It explains the problem quite well, I just
> don't understand why you only changed amd64_linux_nat_target and remote. I imagine this
> issue happens with all targets. I'd ask at least that some of the most common ones be
> changed and validated.

Those two targets are the ones I can test reliably.  For the others,
unfortunately I don't have a reliable way of regression-testing.

> Also, some extra testing revealed that the previous patch is not
> actually necessary to fix the crash.

That's possible.  The bug report in PR/26877 was just a starting point
for the submitted patches, which aim at addressing a more general problem.
 
> As for technical review, I don't have any questions or comments, but I can't approve
> patches.
 
Thanks for your comments!

Regards
-Baris


Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v3 0/2] Querying registers of already-exited processes
  2022-02-08  9:15 [PATCH v2 0/2] Querying registers of already-exited processes Tankut Baris Aktemur
                   ` (3 preceding siblings ...)
  2022-03-07  8:00 ` Aktemur, Tankut Baris
@ 2022-03-23 13:05 ` Tankut Baris Aktemur
  2022-03-23 13:05   ` [PATCH v3 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen Tankut Baris Aktemur
                     ` (3 more replies)
  4 siblings, 4 replies; 28+ messages in thread
From: Tankut Baris Aktemur @ 2022-03-23 13:05 UTC (permalink / raw)
  To: gdb-patches

Hello,

This series can be considered a continuation of

  commit 4778a5f87d253399083565b4919816f541ebe414
  Author: Tom de Vries <tdevries@suse.de>
  Date:   Tue Apr 21 15:45:57 2020 +0200

    [gdb] Fix hang after ext sigkill

and

  commit 47f1aceffa02be4726b854082d7587eb259136e0
  Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
  Date:   Thu May 14 13:59:54 2020 +0200

    gdb/infrun: handle already-exited threads when attempting to stop

The starting point was PR gdb/26877:

  https://sourceware.org/bugzilla/show_bug.cgi?id=26877

Revision v1 of the series is available at

  https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html

Revision v2 of the series is available at

  https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html

This revision (v3)

  - rebases on the current master.
  - addresses Bruno's comments in Patch 1/2.

Regards
Baris

Tankut Baris Aktemur (2):
  gdb/regcache: return REG_UNAVAILABLE in raw_read if
    NOT_AVAILABLE_ERROR is seen
  gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC

 gdb/amd64-linux-nat.c                         |  3 +-
 gdb/regcache.c                                | 12 ++-
 gdb/remote.c                                  | 20 +++--
 gdb/stack.c                                   | 33 +++++++-
 gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
 .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
 .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
 7 files changed, 163 insertions(+), 13 deletions(-)
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp

-- 
2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v3 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen
  2022-03-23 13:05 ` [PATCH v3 " Tankut Baris Aktemur
@ 2022-03-23 13:05   ` Tankut Baris Aktemur
  2022-03-23 13:05   ` [PATCH v3 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 28+ messages in thread
From: Tankut Baris Aktemur @ 2022-03-23 13:05 UTC (permalink / raw)
  To: gdb-patches

In regcache's raw_read, it is possible that 'raw_update' fails with an
exception.  This could happen, for instance, if the debugged thread is
already exited and the target cannot fetch its registers.  Catch the
exception and return REG_UNAVAILABLE if the error is of kind
NOT_AVAILABLE_ERROR.  This makes clients' lives easier.

Regression-tested on X86_64-Linux.
---
 gdb/regcache.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/gdb/regcache.c b/gdb/regcache.c
index 00d7a10e289..c57d2e4c345 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -598,7 +598,17 @@ enum register_status
 readable_regcache::raw_read (int regnum, gdb_byte *buf)
 {
   gdb_assert (buf != NULL);
-  raw_update (regnum);
+  try
+    {
+      raw_update (regnum);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      if (ex.error != NOT_AVAILABLE_ERROR)
+	throw;
+
+      m_register_status[regnum] = REG_UNAVAILABLE;
+    }
 
   if (m_register_status[regnum] != REG_VALID)
     memset (buf, 0, m_descr->sizeof_register[regnum]);
-- 
2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v3 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2022-03-23 13:05 ` [PATCH v3 " Tankut Baris Aktemur
  2022-03-23 13:05   ` [PATCH v3 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen Tankut Baris Aktemur
@ 2022-03-23 13:05   ` Tankut Baris Aktemur
  2022-05-04  7:19   ` [PATCH v3 0/2] Querying registers of already-exited processes Aktemur, Tankut Baris
  2023-12-18 14:40   ` [PATCH v4 " Tankut Baris Aktemur
  3 siblings, 0 replies; 28+ messages in thread
From: Tankut Baris Aktemur @ 2022-03-23 13:05 UTC (permalink / raw)
  To: gdb-patches

This patch can be considered a continuation of

  commit 4778a5f87d253399083565b4919816f541ebe414
  Author: Tom de Vries <tdevries@suse.de>
  Date:   Tue Apr 21 15:45:57 2020 +0200

    [gdb] Fix hang after ext sigkill

and

  commit 47f1aceffa02be4726b854082d7587eb259136e0
  Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
  Date:   Thu May 14 13:59:54 2020 +0200

    gdb/infrun: handle already-exited threads when attempting to stop

If a process dies before GDB reports the exit error to the user, we
may see the "Couldn't get registers: No such process." error message
in various places.  For instance:

  (gdb) start
  ...
  (gdb) info inferior
    Num  Description       Connection           Executable
  * 1    process 31943     1 (native)           /tmp/a.out
  (gdb) shell kill -9 31943
  (gdb) maintenance flush register-cache
  Register cache flushed.
  Couldn't get registers: No such process.
  (gdb) info threads
    Id   Target Id              Frame
  * 1    process 31943 "a.out" Couldn't get registers: No such process.
  (gdb) backtrace
  Python Exception <class 'gdb.error'>: Couldn't get registers: No such process.
  Couldn't get registers: No such process.
  (gdb) inferior 1
  Couldn't get registers: No such process.
  (gdb) thread
  [Current thread is 1 (process 31943)]
  Couldn't get registers: No such process.
  (gdb)

The gdb.threads/killed-outside.exp, gdb.multi/multi-kill.exp, and
gdb.multi/multi-exit.exp tests also check related scenarios.

To improve the situation,

1. when printing the frame info, catch and process a NOT_AVAILABLE_ERROR.

2. when accessing the target to fetch registers, if the operation
   fails, raise a NOT_AVAILABLE_ERROR instead of a generic error, so
   that clients can attempt to recover accordingly.  This patch updates
   the amd64_linux_nat_target and remote_target in this direction.

With this patch, we obtain the following behavior:

  (gdb) start
  ...
  (gdb) info inferior
    Num  Description       Connection           Executable
  * 1    process 748       1 (native)           /tmp/a.out
  (gdb) shell kill -9 748
  (gdb) maintenance flush register-cache
  Register cache flushed.
  (gdb) info threads
    Id   Target Id           Frame
  * 1    process 748 "a.out" <PC register is not available>
  (gdb) backtrace
  #0  <PC register is not available>
  Backtrace stopped: not enough registers or memory available to unwind further
  (gdb) inferior 1
  [Switching to inferior 1 [process 748] (/tmp/a.out)]
  [Switching to thread 1 (process 748)]
  #0  <PC register is not available>
  (gdb) thread
  [Current thread is 1 (process 748)]
  (gdb)

Here is another "before/after" case.  Suppose we have two inferiors,
each having its own remote target underneath.  Before this patch, we
get the following output:

  # Create two inferiors on two remote targets, resume both until
  # termination.  Exit event from one of them is shown first, but the
  # other also exited -- just not yet shown.
  (gdb) maint set target-non-stop on
  (gdb) target remote | gdbserver - ./a.out
  (gdb) add-inferior -no-connection
  (gdb) inferior 2
  (gdb) target remote | gdbserver - ./a.out
  (gdb) set schedule-multiple on
  (gdb) continue
  ...
  [Inferior 2 (process 22127) exited normally]
  (gdb) inferior 1
  [Switching to inferior 1 [process 22111] (target:/tmp/a.out)]
  [Switching to thread 1.1 (Thread 22111.22111)]
  Could not read registers; remote failure reply 'E01'
  (gdb) info threads
    Id   Target Id                  Frame
  * 1.1  Thread 22111.22111 "a.out" Could not read registers; remote failure reply 'E01'
  (gdb) backtrace
  Python Exception <class 'gdb.error'>: Could not read registers; remote failure reply 'E01'
  Could not read registers; remote failure reply 'E01'
  (gdb) thread
  [Current thread is 1.1 (Thread 22111.22111)]
  Could not read registers; remote failure reply 'E01'
  (gdb)

With this patch, it becomes:

  ...
  [Inferior 1 (process 11759) exited normally]
  (gdb) inferior 2
  [Switching to inferior 2 [process 13440] (target:/path/to/a.out)]
  [Switching to thread 2.1 (Thread 13440.13440)]
  #0  <unavailable> in ?? ()
  (gdb) info threads
    Id   Target Id                   Frame
  * 2.1  Thread 13440.13440 "a.out" <unavailable> in ?? ()
  (gdb) backtrace
  #0  <unavailable> in ?? ()
  Backtrace stopped: not enough registers or memory available to unwind further
  (gdb) thread
  [Current thread is 2.1 (Thread 13440.13440)]
  (gdb)

Finally, together with its predecessor, this patch also fixes PR gdb/26877.

Regression-tested on X86_64-Linux.
---
 gdb/amd64-linux-nat.c                         |  3 +-
 gdb/remote.c                                  | 20 +++--
 gdb/stack.c                                   | 33 +++++++-
 gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
 .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
 .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
 6 files changed, 152 insertions(+), 12 deletions(-)
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp

diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 3d28d7e1d57..bdcc93eb498 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -222,7 +222,8 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
       elf_gregset_t regs;
 
       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
-	perror_with_name (_("Couldn't get registers"));
+	throw_perror_with_name (NOT_AVAILABLE_ERROR,
+				_("Couldn't get registers"));
 
       amd64_supply_native_gregset (regcache, &regs, -1);
       if (regnum != -1)
diff --git a/gdb/remote.c b/gdb/remote.c
index aa6a67a96e0..609f6a65c2f 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -8384,10 +8384,14 @@ remote_target::fetch_register_using_p (struct regcache *regcache,
     case PACKET_UNKNOWN:
       return 0;
     case PACKET_ERROR:
-      error (_("Could not fetch register \"%s\"; remote failure reply '%s'"),
-	     gdbarch_register_name (regcache->arch (), 
-				    reg->regnum), 
-	     buf);
+      {
+	const char *regname = gdbarch_register_name (regcache->arch (),
+						     reg->regnum);
+	std::string msg
+	  = string_printf (_("Could not fetch register \"%s\"; remote "
+			     "failure reply '%s'"), regname, buf);
+	throw_perror_with_name (NOT_AVAILABLE_ERROR, msg.c_str ());
+      }
     }
 
   /* If this register is unfetchable, tell the regcache.  */
@@ -8424,8 +8428,12 @@ remote_target::send_g_packet ()
   putpkt (rs->buf);
   getpkt (&rs->buf, 0);
   if (packet_check_result (rs->buf) == PACKET_ERROR)
-    error (_("Could not read registers; remote failure reply '%s'"),
-	   rs->buf.data ());
+    {
+      std::string msg
+	= string_printf (_("Could not read registers; remote failure reply "
+			   "'%s'"), rs->buf.data ());
+      throw_perror_with_name (NOT_AVAILABLE_ERROR, msg.c_str ());
+    }
 
   /* We can get out of synch in various cases.  If the first character
      in the buffer is not a hex character, assume that has happened
diff --git a/gdb/stack.c b/gdb/stack.c
index 10da88b88e5..b1a61d5a612 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1107,7 +1107,38 @@ print_frame_info (const frame_print_options &fp_opts,
      the next frame is a SIGTRAMP_FRAME or a DUMMY_FRAME, then the
      next frame was not entered as the result of a call, and we want
      to get the line containing FRAME->pc.  */
-  symtab_and_line sal = find_frame_sal (frame);
+  symtab_and_line sal;
+  try
+    {
+      sal = find_frame_sal (frame);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      if (ex.error == NOT_AVAILABLE_ERROR)
+	{
+	  ui_out_emit_tuple tuple_emitter (uiout, "frame");
+
+	  annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
+				gdbarch, 0);
+
+	  if (print_level)
+	    {
+	      uiout->text ("#");
+	      uiout->field_fmt_signed (2, ui_left, "level",
+				       frame_relative_level (frame));
+	    }
+
+	  std::string frame_info = "<";
+	  frame_info += ex.what ();
+	  frame_info += ">";
+	  uiout->field_string ("func", frame_info.c_str (),
+			       metadata_style.style ());
+	  uiout->text ("\n");
+	  annotate_frame_end ();
+	  return;
+	}
+      throw;
+    }
 
   location_print = (print_what == LOCATION
 		    || print_what == SRC_AND_LOC
diff --git a/gdb/testsuite/gdb.threads/killed-outside.exp b/gdb/testsuite/gdb.threads/killed-outside.exp
index 3d4543e088c..8e156c863dc 100644
--- a/gdb/testsuite/gdb.threads/killed-outside.exp
+++ b/gdb/testsuite/gdb.threads/killed-outside.exp
@@ -37,16 +37,15 @@ remote_exec target "kill -9 ${testpid}"
 # Give it some time to die.
 sleep 2
 
-set no_such_process_msg "Couldn't get registers: No such process\."
+set no_pc_available_msg "PC register is not available"
 set killed_msg "Program terminated with signal SIGKILL, Killed\."
 set no_longer_exists_msg "The program no longer exists\."
 set not_being_run_msg "The program is not being run\."
 
 gdb_test_multiple "continue" "prompt after first continue" {
-    -re "Continuing\.\r\n$no_such_process_msg\r\n$gdb_prompt " {
+    -re "Continuing\.\r\n$no_pc_available_msg\r\n$gdb_prompt " {
 	pass $gdb_test_name
-	# Saw $no_such_process_msg.  The bug condition was triggered, go
-	# check for it.
+	# The bug condition was triggered, go check for it.
 	gdb_test_multiple "" "messages" {
 	    -re ".*$killed_msg.*$no_longer_exists_msg\r\n" {
 		pass $gdb_test_name
diff --git a/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
new file mode 100644
index 00000000000..d934d74fbb7
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
@@ -0,0 +1,21 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2020 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/>.  */
+
+int main() {
+  int a = 42;
+  return 0; /* break-here */
+}
diff --git a/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
new file mode 100644
index 00000000000..10eb69500cc
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
@@ -0,0 +1,80 @@
+# Copyright 2020 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/>.
+#
+# This is a regression test for PR gdb/26877.
+
+tuiterm_env
+
+standard_testfile
+
+if {[use_gdb_stub]} {
+    return 0
+}
+
+if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} {
+    return -1
+}
+
+# Make sure TUI is supported before continuing.
+with_test_prefix "initial check" {
+    Term::clean_restart 24 80 $testfile
+    if {![Term::enter_tui]} {
+	unsupported "TUI not supported"
+	return
+    }
+}
+
+Term::clean_restart 24 80 $testfile
+
+# Create a setting with two inferiors, where both are stopped
+# at a breakpoint at the end of main.  Then resume both.
+set bp [gdb_get_line_number "break-here"]
+gdb_breakpoint "$bp"
+
+with_test_prefix "inferior 1" {
+    gdb_run_cmd
+    gdb_test "" ".*reakpoint \[^\r\n\]+${srcfile}.*" "run until bp"
+}
+
+with_test_prefix "inferior 2" {
+    gdb_test "add-inferior -exec [standard_output_file $testfile]" \
+	"Added inferior 2.*" "add inferior"
+    gdb_test "inferior 2" "Switching to inferior 2.*" "switch"
+    gdb_run_cmd
+    gdb_test "" ".*reakpoint \[^\r\n\]+${srcfile}.*" "run until bp"
+}
+
+gdb_test_no_output "set schedule-multiple on"
+gdb_continue_to_end
+
+# Find out which inferior is current.  It is the inferior that exited.
+set exited_inf [get_integer_valueof {$_inferior} 1 "current inf"]
+
+# Switch to the other inferior and remove the exited one.
+# Bad GDB used to crash when this is done under TUI.
+if {![Term::enter_tui]} {
+    unsupported "TUI not supported"
+    return
+}
+
+if {$exited_inf == 1} {
+    Term::command "inferior 2"
+} else {
+    Term::command "inferior 1"
+}
+
+Term::command "remove-inferiors $exited_inf"
+Term::command "info inferior $exited_inf"
+Term::check_contents "inferior is removed" "No inferiors."
-- 
2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2022-03-23 12:55     ` Aktemur, Tankut Baris
@ 2022-03-23 13:34       ` Bruno Larsen
  2022-03-24  8:46         ` Aktemur, Tankut Baris
  0 siblings, 1 reply; 28+ messages in thread
From: Bruno Larsen @ 2022-03-23 13:34 UTC (permalink / raw)
  To: Aktemur, Tankut Baris, gdb-patches

On 3/23/22 09:55, Aktemur, Tankut Baris wrote:
> On Wednesday, March 16, 2022 6:27 PM, Bruno Larsen wrote:
>> Hello Tankut,
>>
>> On 2/8/22 06:15, Tankut Baris Aktemur via Gdb-patches wrote:
>>> This patch can be considered a continuation of
>>>
>>>     commit 4778a5f87d253399083565b4919816f541ebe414
>>>     Author: Tom de Vries <tdevries@suse.de>
>>>     Date:   Tue Apr 21 15:45:57 2020 +0200
>>>
>>>       [gdb] Fix hang after ext sigkill
>>>
>>> and
>>>
>>>     commit 47f1aceffa02be4726b854082d7587eb259136e0
>>>     Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>>>     Date:   Thu May 14 13:59:54 2020 +0200
>>>
>>>       gdb/infrun: handle already-exited threads when attempting to stop
>>>
>>> If a process dies before GDB reports the exit error to the user, we
>>> may see the "Couldn't get registers: No such process." error message
>>> in various places.  For instance:
>>>
>>>     (gdb) start
>>>     ...
>>>     (gdb) info inferior
>>>       Num  Description       Connection           Executable
>>>     * 1    process 31943     1 (native)           /tmp/a.out
>>>     (gdb) shell kill -9 31943
>>>     (gdb) maintenance flush register-cache
>>>     Register cache flushed.
>>>     Couldn't get registers: No such process.
>>>     (gdb) info threads
>>>       Id   Target Id              Frame
>>>     * 1    process 31943 "a.out" Couldn't get registers: No such process.
>>>     (gdb) backtrace
>>>     Python Exception <class 'gdb.error'>: Couldn't get registers: No such process.
>>>     Couldn't get registers: No such process.
>>>     (gdb) inferior 1
>>>     Couldn't get registers: No such process.
>>>     (gdb) thread
>>>     [Current thread is 1 (process 31943)]
>>>     Couldn't get registers: No such process.
>>>     (gdb)
>>>
>>> The gdb.threads/killed-outside.exp, gdb.multi/multi-kill.exp, and
>>> gdb.multi/multi-exit.exp tests also check related scenarios.
>>>
>>> To improve the situation,
>>>
>>> 1. when printing the frame info, catch and process a NOT_AVAILABLE_ERROR.
>>>
>>> 2. when accessing the target to fetch registers, if the operation
>>>      fails, raise a NOT_AVAILABLE_ERROR instead of a generic error, so
>>>      that clients can attempt to recover accordingly.  This patch updates
>>>      the amd64_linux_nat_target and remote_target in this direction.
>>>
>>> With this patch, we obtain the following behavior:
>>>
>>>     (gdb) start
>>>     ...
>>>     (gdb) info inferior
>>>       Num  Description       Connection           Executable
>>>     * 1    process 748       1 (native)           /tmp/a.out
>>>     (gdb) shell kill -9 748
>>>     (gdb) maintenance flush register-cache
>>>     Register cache flushed.
>>>     (gdb) info threads
>>>       Id   Target Id           Frame
>>>     * 1    process 748 "a.out" <PC register is not available>
>>>     (gdb) backtrace
>>>     #0  <PC register is not available>
>>>     Backtrace stopped: not enough registers or memory available to unwind further
>>>     (gdb) inferior 1
>>>     [Switching to inferior 1 [process 748] (/tmp/a.out)]
>>>     [Switching to thread 1 (process 748)]
>>>     #0  <PC register is not available>
>>>     (gdb) thread
>>>     [Current thread is 1 (process 748)]
>>>     (gdb)
>>>
>>> Here is another "before/after" case.  Suppose we have two inferiors,
>>> each having its own remote target underneath.  Before this patch, we
>>> get the following output:
>>>
>>>     # Create two inferiors on two remote targets, resume both until
>>>     # termination.  Exit event from one of them is shown first, but the
>>>     # other also exited -- just not yet shown.
>>>     (gdb) maint set target-non-stop on
>>>     (gdb) target remote | gdbserver - ./a.out
>>>     (gdb) add-inferior -no-connection
>>>     (gdb) inferior 2
>>>     (gdb) target remote | gdbserver - ./a.out
>>>     (gdb) set schedule-multiple on
>>>     (gdb) continue
>>>     ...
>>>     [Inferior 2 (process 22127) exited normally]
>>>     (gdb) inferior 1
>>>     [Switching to inferior 1 [process 22111] (target:/tmp/a.out)]
>>>     [Switching to thread 1.1 (Thread 22111.22111)]
>>>     Could not read registers; remote failure reply 'E01'
>>>     (gdb) info threads
>>>       Id   Target Id                  Frame
>>>     * 1.1  Thread 22111.22111 "a.out" Could not read registers; remote failure reply 'E01'
>>>     (gdb) backtrace
>>>     Python Exception <class 'gdb.error'>: Could not read registers; remote failure reply
>> 'E01'
>>>     Could not read registers; remote failure reply 'E01'
>>>     (gdb) thread
>>>     [Current thread is 1.1 (Thread 22111.22111)]
>>>     Could not read registers; remote failure reply 'E01'
>>>     (gdb)
>>>
>>> With this patch, it becomes:
>>>
>>>     ...
>>>     [Inferior 1 (process 11759) exited normally]
>>>     (gdb) inferior 2
>>>     [Switching to inferior 2 [process 13440] (target:/path/to/a.out)]
>>>     [Switching to thread 2.1 (Thread 13440.13440)]
>>>     #0  <unavailable> in ?? ()
>>>     (gdb) info threads
>>>       Id   Target Id                   Frame
>>>     * 2.1  Thread 13440.13440 "a.out" <unavailable> in ?? ()
>>>     (gdb) backtrace
>>>     #0  <unavailable> in ?? ()
>>>     Backtrace stopped: not enough registers or memory available to unwind further
>>>     (gdb) thread
>>>     [Current thread is 2.1 (Thread 13440.13440)]
>>>     (gdb)
>>>
>>> Finally, together with its predecessor, this patch also fixes PR gdb/26877.
>>
>> While I think this is a good idea, it doesn't seem to fix the root cause of the bug you
>> mentioned. It does stop the crash that the bug reports, but I would say the actual issue is
>> that GDB is not noticing that the second inferior is also finished. My 2 cents, for what
>> they're worth.
> 
> The root cause was an unhandled error in a destructor.  The 2-inferior setup was
> just one way to expose it.  From https://sourceware.org/bugzilla/show_bug.cgi?id=26877#c0:
> 
> 	The problem is at:
> 
> 	#20 0x00005555561128b9 in program_space::~program_space (this=0x55555830a070, __in_chrg=<optimized out>) at gdb/progspace.c:153
> 
> 	While inside a destructor, GDB wanted to access the frame information
> 	of Inferior 2 in a series of calls.  But because the process is dead, its
> 	registers cannot be read.  This raises an error inside a destructor, leading
> 	to termination of GDB.
> 
>  From that perspective, I think the root cause is fixed.
> 

It is the root cause of the crash, but GDB is still not aware that the second inferior has finished, which is still a problem, IMHO.
Regardless, it looks like a good cleanup anyway, since even if we fix GDB noticing the process finishing, this crash could happen for other situations.


>> The explanation in the commit message is great! It explains the problem quite well, I just
>> don't understand why you only changed amd64_linux_nat_target and remote. I imagine this
>> issue happens with all targets. I'd ask at least that some of the most common ones be
>> changed and validated.
> 
> Those two targets are the ones I can test reliably.  For the others,
> unfortunately I don't have a reliable way of regression-testing.
> 

Ah, then I guess we should keep this fix in mind if someone reports a similar bug.

>> Also, some extra testing revealed that the previous patch is not
>> actually necessary to fix the crash.
> 
> That's possible.  The bug report in PR/26877 was just a starting point
> for the submitted patches, which aim at addressing a more general problem.
>   
>> As for technical review, I don't have any questions or comments, but I can't approve
>> patches.
>   
> Thanks for your comments!
> 
> Regards
> -Baris
> 
> 
> Intel Deutschland GmbH
> Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
> Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva
> Chairperson of the Supervisory Board: Nicole Lau
> Registered Office: Munich
> Commercial Register: Amtsgericht Muenchen HRB 186928


-- 
Cheers!
Bruno Larsen


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2022-03-23 13:34       ` Bruno Larsen
@ 2022-03-24  8:46         ` Aktemur, Tankut Baris
  0 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2022-03-24  8:46 UTC (permalink / raw)
  To: Bruno Larsen, gdb-patches

On Wednesday, March 23, 2022 2:35 PM, Bruno Larsen wrote:
> On 3/23/22 09:55, Aktemur, Tankut Baris wrote:
> > On Wednesday, March 16, 2022 6:27 PM, Bruno Larsen wrote:
> >>> Finally, together with its predecessor, this patch also fixes PR gdb/26877.
> >>
> >> While I think this is a good idea, it doesn't seem to fix the root cause of the bug you
> >> mentioned. It does stop the crash that the bug reports, but I would say the actual issue
> is
> >> that GDB is not noticing that the second inferior is also finished. My 2 cents, for what
> >> they're worth.
> >
> > The root cause was an unhandled error in a destructor.  The 2-inferior setup was
> > just one way to expose it.  From https://sourceware.org/bugzilla/show_bug.cgi?id=26877#c0:
> >
> > 	The problem is at:
> >
> > 	#20 0x00005555561128b9 in program_space::~program_space (this=0x55555830a070,
> __in_chrg=<optimized out>) at gdb/progspace.c:153
> >
> > 	While inside a destructor, GDB wanted to access the frame information
> > 	of Inferior 2 in a series of calls.  But because the process is dead, its
> > 	registers cannot be read.  This raises an error inside a destructor, leading
> > 	to termination of GDB.
> >
> >  From that perspective, I think the root cause is fixed.
> >
> 
> It is the root cause of the crash, but GDB is still not aware that the second inferior has
> finished, which is still a problem, IMHO.

I agree that it's a problem.  The essence of the problem is that
the other inferior has terminated but this has not been shown to
the user, yet.  The event is pending.  I believe it can be the
topic of another fix.  I'm afraid it's a wider problem outside the
scope of what I submitted.

Regards
-Baris


Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v3 0/2] Querying registers of already-exited processes
  2022-03-23 13:05 ` [PATCH v3 " Tankut Baris Aktemur
  2022-03-23 13:05   ` [PATCH v3 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen Tankut Baris Aktemur
  2022-03-23 13:05   ` [PATCH v3 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
@ 2022-05-04  7:19   ` Aktemur, Tankut Baris
  2022-12-23 17:10     ` Aktemur, Tankut Baris
  2023-12-18 14:40   ` [PATCH v4 " Tankut Baris Aktemur
  3 siblings, 1 reply; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2022-05-04  7:19 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

-Baris


On Wednesday, March 23, 2022 2:06 PM, Aktemur, Tankut Baris wrote:
> 
> Hello,
> 
> This series can be considered a continuation of
> 
>   commit 4778a5f87d253399083565b4919816f541ebe414
>   Author: Tom de Vries <tdevries@suse.de>
>   Date:   Tue Apr 21 15:45:57 2020 +0200
> 
>     [gdb] Fix hang after ext sigkill
> 
> and
> 
>   commit 47f1aceffa02be4726b854082d7587eb259136e0
>   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>   Date:   Thu May 14 13:59:54 2020 +0200
> 
>     gdb/infrun: handle already-exited threads when attempting to stop
> 
> The starting point was PR gdb/26877:
> 
>   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> 
> Revision v1 of the series is available at
> 
>   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> 
> Revision v2 of the series is available at
> 
>   https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html
> 
> This revision (v3)
> 
>   - rebases on the current master.
>   - addresses Bruno's comments in Patch 1/2.
> 
> Regards
> Baris
> 
> Tankut Baris Aktemur (2):
>   gdb/regcache: return REG_UNAVAILABLE in raw_read if
>     NOT_AVAILABLE_ERROR is seen
>   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> 
>  gdb/amd64-linux-nat.c                         |  3 +-
>  gdb/regcache.c                                | 12 ++-
>  gdb/remote.c                                  | 20 +++--
>  gdb/stack.c                                   | 33 +++++++-
>  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
>  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
>  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
>  7 files changed, 163 insertions(+), 13 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
>  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> 
> --
> 2.33.1


Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v3 0/2] Querying registers of already-exited processes
  2022-05-04  7:19   ` [PATCH v3 0/2] Querying registers of already-exited processes Aktemur, Tankut Baris
@ 2022-12-23 17:10     ` Aktemur, Tankut Baris
  2023-01-17 20:40       ` Aktemur, Tankut Baris
                         ` (5 more replies)
  0 siblings, 6 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2022-12-23 17:10 UTC (permalink / raw)
  To: gdb-patches

Hello,

It seems it has been more than two years since I've submitted v1 of the series
below.  I've pinged it many times.  Shall I keep pinging or should I give up? :)

Just in case, here is the version that rebases the series on the current master.

https://github.com/barisaktemur/gdb/tree/wip/querying-registers-of-already-exited-processes

Thanks
-Baris


On Wednesday, March 23, 2022 2:06 PM, Aktemur, Tankut Baris wrote:
> 
> Hello,
> 
> This series can be considered a continuation of
> 
>   commit 4778a5f87d253399083565b4919816f541ebe414
>   Author: Tom de Vries <tdevries@suse.de>
>   Date:   Tue Apr 21 15:45:57 2020 +0200
> 
>     [gdb] Fix hang after ext sigkill
> 
> and
> 
>   commit 47f1aceffa02be4726b854082d7587eb259136e0
>   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>   Date:   Thu May 14 13:59:54 2020 +0200
> 
>     gdb/infrun: handle already-exited threads when attempting to stop
> 
> The starting point was PR gdb/26877:
> 
>   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> 
> Revision v1 of the series is available at
> 
>   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> 
> Revision v2 of the series is available at
> 
>   https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html
> 
> This revision (v3)
> 
>   - rebases on the current master.
>   - addresses Bruno's comments in Patch 1/2.
> 
> Regards
> Baris
> 
> Tankut Baris Aktemur (2):
>   gdb/regcache: return REG_UNAVAILABLE in raw_read if
>     NOT_AVAILABLE_ERROR is seen
>   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> 
>  gdb/amd64-linux-nat.c                         |  3 +-
>  gdb/regcache.c                                | 12 ++-
>  gdb/remote.c                                  | 20 +++--
>  gdb/stack.c                                   | 33 +++++++-
>  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
>  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
>  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
>  7 files changed, 163 insertions(+), 13 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
>  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> 
> --
> 2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v3 0/2] Querying registers of already-exited processes
  2022-12-23 17:10     ` Aktemur, Tankut Baris
@ 2023-01-17 20:40       ` Aktemur, Tankut Baris
  2023-01-24 10:35       ` Aktemur, Tankut Baris
                         ` (4 subsequent siblings)
  5 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2023-01-17 20:40 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

Thanks
-Baris

On Friday, December 23, 2022 6:11 PM Aktemur, Tankut Baris wrote:
> Hello,
> 
> It seems it has been more than two years since I've submitted v1 of the series
> below.  I've pinged it many times.  Shall I keep pinging or should I give up? :)
> 
> Just in case, here is the version that rebases the series on the current master.
> 
> https://github.com/barisaktemur/gdb/tree/wip/querying-registers-of-already-exited-processes
> 
> Thanks
> -Baris
> 
> 
> On Wednesday, March 23, 2022 2:06 PM, Aktemur, Tankut Baris wrote:
> >
> > Hello,
> >
> > This series can be considered a continuation of
> >
> >   commit 4778a5f87d253399083565b4919816f541ebe414
> >   Author: Tom de Vries <tdevries@suse.de>
> >   Date:   Tue Apr 21 15:45:57 2020 +0200
> >
> >     [gdb] Fix hang after ext sigkill
> >
> > and
> >
> >   commit 47f1aceffa02be4726b854082d7587eb259136e0
> >   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> >   Date:   Thu May 14 13:59:54 2020 +0200
> >
> >     gdb/infrun: handle already-exited threads when attempting to stop
> >
> > The starting point was PR gdb/26877:
> >
> >   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> >
> > Revision v1 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> >
> > Revision v2 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html
> >
> > This revision (v3)
> >
> >   - rebases on the current master.
> >   - addresses Bruno's comments in Patch 1/2.
> >
> > Regards
> > Baris
> >
> > Tankut Baris Aktemur (2):
> >   gdb/regcache: return REG_UNAVAILABLE in raw_read if
> >     NOT_AVAILABLE_ERROR is seen
> >   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> >
> >  gdb/amd64-linux-nat.c                         |  3 +-
> >  gdb/regcache.c                                | 12 ++-
> >  gdb/remote.c                                  | 20 +++--
> >  gdb/stack.c                                   | 33 +++++++-
> >  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
> >  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
> >  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
> >  7 files changed, 163 insertions(+), 13 deletions(-)
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> >
> > --
> > 2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v3 0/2] Querying registers of already-exited processes
  2022-12-23 17:10     ` Aktemur, Tankut Baris
  2023-01-17 20:40       ` Aktemur, Tankut Baris
@ 2023-01-24 10:35       ` Aktemur, Tankut Baris
  2023-01-31 20:14       ` Aktemur, Tankut Baris
                         ` (3 subsequent siblings)
  5 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2023-01-24 10:35 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

Thanks
-Baris

On Friday, December 23, 2022 6:11 PM Aktemur, Tankut Baris wrote:
> Hello,
> 
> It seems it has been more than two years since I've submitted v1 of the series
> below.  I've pinged it many times.  Shall I keep pinging or should I give up? :)
> 
> Just in case, here is the version that rebases the series on the current master.
> 
> https://github.com/barisaktemur/gdb/tree/wip/querying-registers-of-already-exited-processes
> 
> Thanks
> -Baris
> 
> 
> On Wednesday, March 23, 2022 2:06 PM, Aktemur, Tankut Baris wrote:
> >
> > Hello,
> >
> > This series can be considered a continuation of
> >
> >   commit 4778a5f87d253399083565b4919816f541ebe414
> >   Author: Tom de Vries <tdevries@suse.de>
> >   Date:   Tue Apr 21 15:45:57 2020 +0200
> >
> >     [gdb] Fix hang after ext sigkill
> >
> > and
> >
> >   commit 47f1aceffa02be4726b854082d7587eb259136e0
> >   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> >   Date:   Thu May 14 13:59:54 2020 +0200
> >
> >     gdb/infrun: handle already-exited threads when attempting to stop
> >
> > The starting point was PR gdb/26877:
> >
> >   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> >
> > Revision v1 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> >
> > Revision v2 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html
> >
> > This revision (v3)
> >
> >   - rebases on the current master.
> >   - addresses Bruno's comments in Patch 1/2.
> >
> > Regards
> > Baris
> >
> > Tankut Baris Aktemur (2):
> >   gdb/regcache: return REG_UNAVAILABLE in raw_read if
> >     NOT_AVAILABLE_ERROR is seen
> >   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> >
> >  gdb/amd64-linux-nat.c                         |  3 +-
> >  gdb/regcache.c                                | 12 ++-
> >  gdb/remote.c                                  | 20 +++--
> >  gdb/stack.c                                   | 33 +++++++-
> >  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
> >  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
> >  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
> >  7 files changed, 163 insertions(+), 13 deletions(-)
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> >
> > --
> > 2.33.1


Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v3 0/2] Querying registers of already-exited processes
  2022-12-23 17:10     ` Aktemur, Tankut Baris
  2023-01-17 20:40       ` Aktemur, Tankut Baris
  2023-01-24 10:35       ` Aktemur, Tankut Baris
@ 2023-01-31 20:14       ` Aktemur, Tankut Baris
  2023-02-20 13:07       ` Aktemur, Tankut Baris
                         ` (2 subsequent siblings)
  5 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2023-01-31 20:14 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

Thanks
-Baris

On Friday, December 23, 2022 6:11 PM Aktemur, Tankut Baris wrote:
> Hello,
> 
> It seems it has been more than two years since I've submitted v1 of the series
> below.  I've pinged it many times.  Shall I keep pinging or should I give up? :)
> 
> Just in case, here is the version that rebases the series on the current master.
> 
> https://github.com/barisaktemur/gdb/tree/wip/querying-registers-of-already-exited-processes
> 
> Thanks
> -Baris
> 
> 
> On Wednesday, March 23, 2022 2:06 PM, Aktemur, Tankut Baris wrote:
> >
> > Hello,
> >
> > This series can be considered a continuation of
> >
> >   commit 4778a5f87d253399083565b4919816f541ebe414
> >   Author: Tom de Vries <tdevries@suse.de>
> >   Date:   Tue Apr 21 15:45:57 2020 +0200
> >
> >     [gdb] Fix hang after ext sigkill
> >
> > and
> >
> >   commit 47f1aceffa02be4726b854082d7587eb259136e0
> >   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> >   Date:   Thu May 14 13:59:54 2020 +0200
> >
> >     gdb/infrun: handle already-exited threads when attempting to stop
> >
> > The starting point was PR gdb/26877:
> >
> >   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> >
> > Revision v1 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> >
> > Revision v2 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html
> >
> > This revision (v3)
> >
> >   - rebases on the current master.
> >   - addresses Bruno's comments in Patch 1/2.
> >
> > Regards
> > Baris
> >
> > Tankut Baris Aktemur (2):
> >   gdb/regcache: return REG_UNAVAILABLE in raw_read if
> >     NOT_AVAILABLE_ERROR is seen
> >   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> >
> >  gdb/amd64-linux-nat.c                         |  3 +-
> >  gdb/regcache.c                                | 12 ++-
> >  gdb/remote.c                                  | 20 +++--
> >  gdb/stack.c                                   | 33 +++++++-
> >  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
> >  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
> >  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
> >  7 files changed, 163 insertions(+), 13 deletions(-)
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> >
> > --
> > 2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v3 0/2] Querying registers of already-exited processes
  2022-12-23 17:10     ` Aktemur, Tankut Baris
                         ` (2 preceding siblings ...)
  2023-01-31 20:14       ` Aktemur, Tankut Baris
@ 2023-02-20 13:07       ` Aktemur, Tankut Baris
  2023-03-03  7:46       ` Aktemur, Tankut Baris
  2023-03-28 13:40       ` Aktemur, Tankut Baris
  5 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2023-02-20 13:07 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

Thanks
-Baris

On Friday, December 23, 2022 6:11 PM Aktemur, Tankut Baris wrote:
> Hello,
> 
> It seems it has been more than two years since I've submitted v1 of the series
> below.  I've pinged it many times.  Shall I keep pinging or should I give up? :)
> 
> Just in case, here is the version that rebases the series on the current master.
> 
> https://github.com/barisaktemur/gdb/tree/wip/querying-registers-of-already-exited-processes
> 
> Thanks
> -Baris
> 
> 
> On Wednesday, March 23, 2022 2:06 PM, Aktemur, Tankut Baris wrote:
> >
> > Hello,
> >
> > This series can be considered a continuation of
> >
> >   commit 4778a5f87d253399083565b4919816f541ebe414
> >   Author: Tom de Vries <tdevries@suse.de>
> >   Date:   Tue Apr 21 15:45:57 2020 +0200
> >
> >     [gdb] Fix hang after ext sigkill
> >
> > and
> >
> >   commit 47f1aceffa02be4726b854082d7587eb259136e0
> >   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> >   Date:   Thu May 14 13:59:54 2020 +0200
> >
> >     gdb/infrun: handle already-exited threads when attempting to stop
> >
> > The starting point was PR gdb/26877:
> >
> >   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> >
> > Revision v1 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> >
> > Revision v2 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html
> >
> > This revision (v3)
> >
> >   - rebases on the current master.
> >   - addresses Bruno's comments in Patch 1/2.
> >
> > Regards
> > Baris
> >
> > Tankut Baris Aktemur (2):
> >   gdb/regcache: return REG_UNAVAILABLE in raw_read if
> >     NOT_AVAILABLE_ERROR is seen
> >   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> >
> >  gdb/amd64-linux-nat.c                         |  3 +-
> >  gdb/regcache.c                                | 12 ++-
> >  gdb/remote.c                                  | 20 +++--
> >  gdb/stack.c                                   | 33 +++++++-
> >  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
> >  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
> >  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
> >  7 files changed, 163 insertions(+), 13 deletions(-)
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> >
> > --
> > 2.33.1
> 
> Intel Deutschland GmbH
> Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
> Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva
> Chairperson of the Supervisory Board: Nicole Lau
> Registered Office: Munich
> Commercial Register: Amtsgericht Muenchen HRB 186928

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v3 0/2] Querying registers of already-exited processes
  2022-12-23 17:10     ` Aktemur, Tankut Baris
                         ` (3 preceding siblings ...)
  2023-02-20 13:07       ` Aktemur, Tankut Baris
@ 2023-03-03  7:46       ` Aktemur, Tankut Baris
  2023-03-28 13:40       ` Aktemur, Tankut Baris
  5 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2023-03-03  7:46 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

Thanks
-Baris

On Friday, December 23, 2022 6:11 PM Aktemur, Tankut Baris wrote:
> Hello,
> 
> It seems it has been more than two years since I've submitted v1 of the series
> below.  I've pinged it many times.  Shall I keep pinging or should I give up? :)
> 
> Just in case, here is the version that rebases the series on the current master.
> 
> https://github.com/barisaktemur/gdb/tree/wip/querying-registers-of-already-exited-processes
> 
> Thanks
> -Baris
> 
> 
> On Wednesday, March 23, 2022 2:06 PM, Aktemur, Tankut Baris wrote:
> >
> > Hello,
> >
> > This series can be considered a continuation of
> >
> >   commit 4778a5f87d253399083565b4919816f541ebe414
> >   Author: Tom de Vries <tdevries@suse.de>
> >   Date:   Tue Apr 21 15:45:57 2020 +0200
> >
> >     [gdb] Fix hang after ext sigkill
> >
> > and
> >
> >   commit 47f1aceffa02be4726b854082d7587eb259136e0
> >   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> >   Date:   Thu May 14 13:59:54 2020 +0200
> >
> >     gdb/infrun: handle already-exited threads when attempting to stop
> >
> > The starting point was PR gdb/26877:
> >
> >   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> >
> > Revision v1 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> >
> > Revision v2 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html
> >
> > This revision (v3)
> >
> >   - rebases on the current master.
> >   - addresses Bruno's comments in Patch 1/2.
> >
> > Regards
> > Baris
> >
> > Tankut Baris Aktemur (2):
> >   gdb/regcache: return REG_UNAVAILABLE in raw_read if
> >     NOT_AVAILABLE_ERROR is seen
> >   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> >
> >  gdb/amd64-linux-nat.c                         |  3 +-
> >  gdb/regcache.c                                | 12 ++-
> >  gdb/remote.c                                  | 20 +++--
> >  gdb/stack.c                                   | 33 +++++++-
> >  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
> >  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
> >  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
> >  7 files changed, 163 insertions(+), 13 deletions(-)
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> >
> > --
> > 2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v3 0/2] Querying registers of already-exited processes
  2022-12-23 17:10     ` Aktemur, Tankut Baris
                         ` (4 preceding siblings ...)
  2023-03-03  7:46       ` Aktemur, Tankut Baris
@ 2023-03-28 13:40       ` Aktemur, Tankut Baris
  5 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2023-03-28 13:40 UTC (permalink / raw)
  To: gdb-patches

Kindly pinging.

Thanks
-Baris

On Friday, December 23, 2022 6:11 PM Aktemur, Tankut Baris wrote:
> Hello,
> 
> It seems it has been more than two years since I've submitted v1 of the series
> below.  I've pinged it many times.  Shall I keep pinging or should I give up? :)
> 
> Just in case, here is the version that rebases the series on the current master.
> 
> https://github.com/barisaktemur/gdb/tree/wip/querying-registers-of-already-exited-processes
> 
> Thanks
> -Baris
> 
> 
> On Wednesday, March 23, 2022 2:06 PM, Aktemur, Tankut Baris wrote:
> >
> > Hello,
> >
> > This series can be considered a continuation of
> >
> >   commit 4778a5f87d253399083565b4919816f541ebe414
> >   Author: Tom de Vries <tdevries@suse.de>
> >   Date:   Tue Apr 21 15:45:57 2020 +0200
> >
> >     [gdb] Fix hang after ext sigkill
> >
> > and
> >
> >   commit 47f1aceffa02be4726b854082d7587eb259136e0
> >   Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> >   Date:   Thu May 14 13:59:54 2020 +0200
> >
> >     gdb/infrun: handle already-exited threads when attempting to stop
> >
> > The starting point was PR gdb/26877:
> >
> >   https://sourceware.org/bugzilla/show_bug.cgi?id=26877
> >
> > Revision v1 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html
> >
> > Revision v2 of the series is available at
> >
> >   https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html
> >
> > This revision (v3)
> >
> >   - rebases on the current master.
> >   - addresses Bruno's comments in Patch 1/2.
> >
> > Regards
> > Baris
> >
> > Tankut Baris Aktemur (2):
> >   gdb/regcache: return REG_UNAVAILABLE in raw_read if
> >     NOT_AVAILABLE_ERROR is seen
> >   gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
> >
> >  gdb/amd64-linux-nat.c                         |  3 +-
> >  gdb/regcache.c                                | 12 ++-
> >  gdb/remote.c                                  | 20 +++--
> >  gdb/stack.c                                   | 33 +++++++-
> >  gdb/testsuite/gdb.threads/killed-outside.exp  |  7 +-
> >  .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
> >  .../gdb.tui/multi-exit-remove-inferior.exp    | 80 +++++++++++++++++++
> >  7 files changed, 163 insertions(+), 13 deletions(-)
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
> >  create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> >
> > --
> > 2.33.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v4 0/2] Querying registers of already-exited processes
  2022-03-23 13:05 ` [PATCH v3 " Tankut Baris Aktemur
                     ` (2 preceding siblings ...)
  2022-05-04  7:19   ` [PATCH v3 0/2] Querying registers of already-exited processes Aktemur, Tankut Baris
@ 2023-12-18 14:40   ` Tankut Baris Aktemur
  2023-12-18 14:40     ` [PATCH v4 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen Tankut Baris Aktemur
  2023-12-18 14:40     ` [PATCH v4 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
  3 siblings, 2 replies; 28+ messages in thread
From: Tankut Baris Aktemur @ 2023-12-18 14:40 UTC (permalink / raw)
  To: gdb-patches

Hello,

This series can be considered a continuation of

  commit 4778a5f87d253399083565b4919816f541ebe414
  Author: Tom de Vries <tdevries@suse.de>
  Date:   Tue Apr 21 15:45:57 2020 +0200

    [gdb] Fix hang after ext sigkill

and

  commit 47f1aceffa02be4726b854082d7587eb259136e0
  Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
  Date:   Thu May 14 13:59:54 2020 +0200

    gdb/infrun: handle already-exited threads when attempting to stop

The starting point was PR gdb/26877:

  https://sourceware.org/bugzilla/show_bug.cgi?id=26877

Revision v1 of the series is available at

  https://sourceware.org/pipermail/gdb-patches/2020-November/173255.html

Revision v2 of the series is available at

  https://sourceware.org/pipermail/gdb-patches/2022-February/185784.html

Revision v3 of the series is available at

  https://sourceware.org/pipermail/gdb-patches/2022-March/186919.html

This revision (v4) rebases on the current master.

Regards
Baris

Tankut Baris Aktemur (2):
  gdb/regcache: return REG_UNAVAILABLE in raw_read if
    NOT_AVAILABLE_ERROR is seen
  gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC

 gdb/amd64-linux-nat.c                         |  5 +-
 gdb/regcache.c                                | 12 ++-
 gdb/remote.c                                  | 15 ++--
 gdb/stack.c                                   | 33 ++++++-
 gdb/testsuite/gdb.threads/killed-outside.exp  |  8 +-
 .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
 .../gdb.tui/multi-exit-remove-inferior.exp    | 86 +++++++++++++++++++
 7 files changed, 167 insertions(+), 13 deletions(-)
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp

-- 
2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v4 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen
  2023-12-18 14:40   ` [PATCH v4 " Tankut Baris Aktemur
@ 2023-12-18 14:40     ` Tankut Baris Aktemur
  2023-12-18 14:40     ` [PATCH v4 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
  1 sibling, 0 replies; 28+ messages in thread
From: Tankut Baris Aktemur @ 2023-12-18 14:40 UTC (permalink / raw)
  To: gdb-patches

In regcache's raw_read, it is possible that 'raw_update' fails with an
exception.  This could happen, for instance, if the debugged thread is
already exited and the target cannot fetch its registers.  Catch the
exception and return REG_UNAVAILABLE if the error is of kind
NOT_AVAILABLE_ERROR.  This makes clients' lives easier.

Regression-tested on X86_64-Linux using the unix, native-gdbserver, and
native-extended-gdbserver board files.
---
 gdb/regcache.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/gdb/regcache.c b/gdb/regcache.c
index 6140a05f02b..0ed433aa182 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -616,7 +616,17 @@ readable_regcache::raw_read (int regnum, gdb::array_view<gdb_byte> dst)
   assert_regnum (regnum);
   gdb_assert (dst.size () == m_descr->sizeof_register[regnum]);
 
-  raw_update (regnum);
+  try
+    {
+      raw_update (regnum);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      if (ex.error != NOT_AVAILABLE_ERROR)
+	throw;
+
+      m_register_status[regnum] = REG_UNAVAILABLE;
+    }
 
   if (m_register_status[regnum] != REG_VALID)
     memset (dst.data (), 0, dst.size ());
-- 
2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v4 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2023-12-18 14:40   ` [PATCH v4 " Tankut Baris Aktemur
  2023-12-18 14:40     ` [PATCH v4 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen Tankut Baris Aktemur
@ 2023-12-18 14:40     ` Tankut Baris Aktemur
  2023-12-20 22:00       ` John Baldwin
  1 sibling, 1 reply; 28+ messages in thread
From: Tankut Baris Aktemur @ 2023-12-18 14:40 UTC (permalink / raw)
  To: gdb-patches

This patch can be considered a continuation of

  commit 4778a5f87d253399083565b4919816f541ebe414
  Author: Tom de Vries <tdevries@suse.de>
  Date:   Tue Apr 21 15:45:57 2020 +0200

    [gdb] Fix hang after ext sigkill

and

  commit 47f1aceffa02be4726b854082d7587eb259136e0
  Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
  Date:   Thu May 14 13:59:54 2020 +0200

    gdb/infrun: handle already-exited threads when attempting to stop

If a process dies before GDB reports the exit error to the user, we
may see the "Couldn't get registers: No such process." error message
in various places.  For instance:

  (gdb) start
  ...
  (gdb) info inferior
    Num  Description       Connection           Executable
  * 1    process 31943     1 (native)           /tmp/a.out
  (gdb) shell kill -9 31943
  (gdb) maintenance flush register-cache
  Register cache flushed.
  Couldn't get registers: No such process.
  (gdb) info threads
    Id   Target Id              Frame
  * 1    process 31943 "a.out" Couldn't get registers: No such process.
  (gdb) backtrace
  Python Exception <class 'gdb.error'>: Couldn't get registers: No such process.
  Couldn't get registers: No such process.
  (gdb) inferior 1
  Couldn't get registers: No such process.
  (gdb) thread
  [Current thread is 1 (process 31943)]
  Couldn't get registers: No such process.
  (gdb)

The gdb.threads/killed-outside.exp, gdb.multi/multi-kill.exp, and
gdb.multi/multi-exit.exp tests also check related scenarios.

To improve the situation,

1. when printing the frame info, catch and process a NOT_AVAILABLE_ERROR.

2. when accessing the target to fetch registers, if the operation
   fails, raise a NOT_AVAILABLE_ERROR instead of a generic error, so
   that clients can attempt to recover accordingly.  This patch updates
   the amd64_linux_nat_target and remote_target in this direction.

With this patch, we obtain the following behavior:

  (gdb) start
  ...
  (gdb) info inferior
    Num  Description       Connection           Executable
  * 1    process 748       1 (native)           /tmp/a.out
  (gdb) shell kill -9 748
  (gdb) maintenance flush register-cache
  Register cache flushed.
  (gdb) info threads
    Id   Target Id           Frame
  * 1    process 748 "a.out" <PC register is not available>
  (gdb) backtrace
  #0  <PC register is not available>
  Backtrace stopped: not enough registers or memory available to unwind further
  (gdb) inferior 1
  [Switching to inferior 1 [process 748] (/tmp/a.out)]
  [Switching to thread 1 (process 748)]
  #0  <PC register is not available>
  (gdb) thread
  [Current thread is 1 (process 748)]
  (gdb)

Here is another "before/after" case.  Suppose we have two inferiors,
each having its own remote target underneath.  Before this patch, we
get the following output:

  # Create two inferiors on two remote targets, resume both until
  # termination.  Exit event from one of them is shown first, but the
  # other also exited -- just not yet shown.
  (gdb) maint set target-non-stop on
  (gdb) target remote | gdbserver - ./a.out
  (gdb) add-inferior -no-connection
  (gdb) inferior 2
  (gdb) target remote | gdbserver - ./a.out
  (gdb) set schedule-multiple on
  (gdb) continue
  ...
  [Inferior 2 (process 22127) exited normally]
  (gdb) inferior 1
  [Switching to inferior 1 [process 22111] (target:/tmp/a.out)]
  [Switching to thread 1.1 (Thread 22111.22111)]
  Could not read registers; remote failure reply 'E01'
  (gdb) info threads
    Id   Target Id                  Frame
  * 1.1  Thread 22111.22111 "a.out" Could not read registers; remote failure reply 'E01'
  (gdb) backtrace
  Python Exception <class 'gdb.error'>: Could not read registers; remote failure reply 'E01'
  Could not read registers; remote failure reply 'E01'
  (gdb) thread
  [Current thread is 1.1 (Thread 22111.22111)]
  Could not read registers; remote failure reply 'E01'
  (gdb)

With this patch, it becomes:

  ...
  [Inferior 1 (process 11759) exited normally]
  (gdb) inferior 2
  [Switching to inferior 2 [process 13440] (target:/path/to/a.out)]
  [Switching to thread 2.1 (Thread 13440.13440)]
  #0  <unavailable> in ?? ()
  (gdb) info threads
    Id   Target Id                   Frame
  * 2.1  Thread 13440.13440 "a.out" <unavailable> in ?? ()
  (gdb) backtrace
  #0  <unavailable> in ?? ()
  Backtrace stopped: not enough registers or memory available to unwind further
  (gdb) thread
  [Current thread is 2.1 (Thread 13440.13440)]
  (gdb)

Finally, together with its predecessor, this patch also fixes PR gdb/26877.

Regression-tested on X86_64-Linux.
---
 gdb/amd64-linux-nat.c                         |  5 +-
 gdb/remote.c                                  | 15 ++--
 gdb/stack.c                                   | 33 ++++++-
 gdb/testsuite/gdb.threads/killed-outside.exp  |  8 +-
 .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
 .../gdb.tui/multi-exit-remove-inferior.exp    | 86 +++++++++++++++++++
 6 files changed, 156 insertions(+), 12 deletions(-)
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
 create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp

diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index f7f9a483def..aa9b10c52d1 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -223,7 +223,10 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
       elf_gregset_t regs;
 
       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
-	perror_with_name (_("Couldn't get registers"));
+	{
+	  std::string msg = perror_string (_("Couldn't get registers"));
+	  throw_error (NOT_AVAILABLE_ERROR, "%s", msg.c_str ());
+	}
 
       amd64_supply_native_gregset (regcache, &regs, -1);
       if (regnum != -1)
diff --git a/gdb/remote.c b/gdb/remote.c
index 84daa8567b6..e17e526411e 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -8760,9 +8760,13 @@ remote_target::fetch_register_using_p (struct regcache *regcache,
     case PACKET_UNKNOWN:
       return 0;
     case PACKET_ERROR:
-      error (_("Could not fetch register \"%s\"; remote failure reply '%s'"),
-	     gdbarch_register_name (regcache->arch (), reg->regnum),
-	     buf);
+      {
+	const char *regname = gdbarch_register_name (regcache->arch (),
+						     reg->regnum);
+	throw_error (NOT_AVAILABLE_ERROR,
+		     _("Could not fetch register \"%s\"; remote failure "
+		       "reply '%s'"), regname, buf);
+      }
     }
 
   /* If this register is unfetchable, tell the regcache.  */
@@ -8799,8 +8803,9 @@ remote_target::send_g_packet ()
   putpkt (rs->buf);
   getpkt (&rs->buf);
   if (packet_check_result (rs->buf) == PACKET_ERROR)
-    error (_("Could not read registers; remote failure reply '%s'"),
-	   rs->buf.data ());
+    throw_error (NOT_AVAILABLE_ERROR,
+		 _("Could not read registers; remote failure reply '%s'"),
+		 rs->buf.data ());
 
   /* We can get out of synch in various cases.  If the first character
      in the buffer is not a hex character, assume that has happened
diff --git a/gdb/stack.c b/gdb/stack.c
index 20bb85efd19..04478f02ce3 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1098,7 +1098,38 @@ print_frame_info (const frame_print_options &fp_opts,
      the next frame is a SIGTRAMP_FRAME or a DUMMY_FRAME, then the
      next frame was not entered as the result of a call, and we want
      to get the line containing FRAME->pc.  */
-  symtab_and_line sal = find_frame_sal (frame);
+  symtab_and_line sal;
+  try
+    {
+      sal = find_frame_sal (frame);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      if (ex.error == NOT_AVAILABLE_ERROR)
+	{
+	  ui_out_emit_tuple tuple_emitter (uiout, "frame");
+
+	  annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
+				gdbarch, 0);
+
+	  if (print_level)
+	    {
+	      uiout->text ("#");
+	      uiout->field_fmt_signed (2, ui_left, "level",
+				       frame_relative_level (frame));
+	    }
+
+	  std::string frame_info = "<";
+	  frame_info += ex.what ();
+	  frame_info += ">";
+	  uiout->field_string ("func", frame_info.c_str (),
+			       metadata_style.style ());
+	  uiout->text ("\n");
+	  annotate_frame_end ();
+	  return;
+	}
+      throw;
+    }
 
   location_print = (print_what == LOCATION
 		    || print_what == SRC_AND_LOC
diff --git a/gdb/testsuite/gdb.threads/killed-outside.exp b/gdb/testsuite/gdb.threads/killed-outside.exp
index 003cede78ee..addb6993afd 100644
--- a/gdb/testsuite/gdb.threads/killed-outside.exp
+++ b/gdb/testsuite/gdb.threads/killed-outside.exp
@@ -37,17 +37,15 @@ remote_exec target "kill -9 ${testpid}"
 # Give it some time to die.
 sleep 2
 
-set regs_msg "(Couldn't get registers|Unable to fetch general registers)"
-set no_such_process_msg "$regs_msg: No such process\."
+set error_msg "PC register is not available"
 set killed_msg "Program terminated with signal SIGKILL, Killed\."
 set no_longer_exists_msg "The program no longer exists\."
 set not_being_run_msg "The program is not being run\."
 
 gdb_test_multiple "continue" "prompt after first continue" {
-    -re "Continuing\.\r\n$no_such_process_msg\r\n$gdb_prompt " {
+    -re "Continuing\.\r\n$error_msg\r\n$gdb_prompt " {
 	pass $gdb_test_name
-	# Saw $no_such_process_msg.  The bug condition was triggered, go
-	# check for it.
+	# The bug condition was triggered, go check for it.
 	gdb_test_multiple "" "messages" {
 	    -re ".*$killed_msg.*$no_longer_exists_msg\r\n" {
 		pass $gdb_test_name
diff --git a/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
new file mode 100644
index 00000000000..594408d2e72
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
@@ -0,0 +1,21 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2020-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/>.  */
+
+int main() {
+  int a = 42;
+  return 0; /* break-here */
+}
diff --git a/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
new file mode 100644
index 00000000000..79f0b453ff4
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
@@ -0,0 +1,86 @@
+# Copyright 2020-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/>.
+#
+# This is a regression test for PR gdb/26877.
+
+tuiterm_env
+
+standard_testfile
+
+if {[use_gdb_stub]} {
+    return 0
+}
+
+if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} {
+    return -1
+}
+
+# Make sure TUI is supported before continuing.
+with_test_prefix "initial check" {
+    Term::clean_restart 24 80 $testfile
+    if {![Term::enter_tui]} {
+	unsupported "TUI not supported"
+	return
+    }
+}
+
+Term::clean_restart 24 80 $testfile
+
+# Create a setting with two inferiors, where both are stopped
+# at a breakpoint at the end of main.  Then resume both.
+set bp [gdb_get_line_number "break-here"]
+gdb_breakpoint "$bp"
+
+with_test_prefix "inferior 1" {
+    gdb_run_cmd
+    gdb_test "" ".*reakpoint \[^\r\n\]+${srcfile}.*" "run until bp"
+}
+
+with_test_prefix "inferior 2" {
+    gdb_test "add-inferior -exec [standard_output_file $testfile]" \
+	"Added inferior 2.*" "add inferior"
+    gdb_test "inferior 2" "Switching to inferior 2.*" "switch"
+    gdb_run_cmd
+    gdb_test "" ".*reakpoint \[^\r\n\]+${srcfile}.*" "run until bp"
+}
+
+gdb_test_no_output "set schedule-multiple on"
+gdb_continue_to_end
+
+# Find out which inferior is current.  It is the inferior that exited.
+set exited_inf 1
+gdb_test_multiple "inferior" "current inferior" {
+    -re -wrap "Current inferior is ($decimal) .*" {
+	set exited_inf $expect_out(1,string)
+	pass $gdb_test_name
+    }
+}
+
+# Switch to the other inferior and remove the exited one.
+# Bad GDB used to crash when this is done under TUI.
+if {![Term::enter_tui]} {
+    unsupported "TUI not supported"
+    return
+}
+
+if {$exited_inf == 1} {
+    Term::command "inferior 2"
+} else {
+    Term::command "inferior 1"
+}
+
+Term::command "remove-inferiors $exited_inf"
+Term::command "info inferior $exited_inf"
+Term::check_contents "inferior is removed" "No inferiors."
-- 
2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v4 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2023-12-18 14:40     ` [PATCH v4 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
@ 2023-12-20 22:00       ` John Baldwin
  2023-12-21  6:41         ` Eli Zaretskii
  0 siblings, 1 reply; 28+ messages in thread
From: John Baldwin @ 2023-12-20 22:00 UTC (permalink / raw)
  To: Tankut Baris Aktemur, gdb-patches

On 12/18/23 6:40 AM, Tankut Baris Aktemur wrote:
> This patch can be considered a continuation of
> 
>    commit 4778a5f87d253399083565b4919816f541ebe414
>    Author: Tom de Vries <tdevries@suse.de>
>    Date:   Tue Apr 21 15:45:57 2020 +0200
> 
>      [gdb] Fix hang after ext sigkill
> 
> and
> 
>    commit 47f1aceffa02be4726b854082d7587eb259136e0
>    Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>    Date:   Thu May 14 13:59:54 2020 +0200
> 
>      gdb/infrun: handle already-exited threads when attempting to stop
> 
> If a process dies before GDB reports the exit error to the user, we
> may see the "Couldn't get registers: No such process." error message
> in various places.  For instance:
> 
>    (gdb) start
>    ...
>    (gdb) info inferior
>      Num  Description       Connection           Executable
>    * 1    process 31943     1 (native)           /tmp/a.out
>    (gdb) shell kill -9 31943
>    (gdb) maintenance flush register-cache
>    Register cache flushed.
>    Couldn't get registers: No such process.
>    (gdb) info threads
>      Id   Target Id              Frame
>    * 1    process 31943 "a.out" Couldn't get registers: No such process.
>    (gdb) backtrace
>    Python Exception <class 'gdb.error'>: Couldn't get registers: No such process.
>    Couldn't get registers: No such process.
>    (gdb) inferior 1
>    Couldn't get registers: No such process.
>    (gdb) thread
>    [Current thread is 1 (process 31943)]
>    Couldn't get registers: No such process.
>    (gdb)
> 
> The gdb.threads/killed-outside.exp, gdb.multi/multi-kill.exp, and
> gdb.multi/multi-exit.exp tests also check related scenarios.
> 
> To improve the situation,
> 
> 1. when printing the frame info, catch and process a NOT_AVAILABLE_ERROR.
> 
> 2. when accessing the target to fetch registers, if the operation
>     fails, raise a NOT_AVAILABLE_ERROR instead of a generic error, so
>     that clients can attempt to recover accordingly.  This patch updates
>     the amd64_linux_nat_target and remote_target in this direction.
> 
> With this patch, we obtain the following behavior:
> 
>    (gdb) start
>    ...
>    (gdb) info inferior
>      Num  Description       Connection           Executable
>    * 1    process 748       1 (native)           /tmp/a.out
>    (gdb) shell kill -9 748
>    (gdb) maintenance flush register-cache
>    Register cache flushed.
>    (gdb) info threads
>      Id   Target Id           Frame
>    * 1    process 748 "a.out" <PC register is not available>
>    (gdb) backtrace
>    #0  <PC register is not available>
>    Backtrace stopped: not enough registers or memory available to unwind further
>    (gdb) inferior 1
>    [Switching to inferior 1 [process 748] (/tmp/a.out)]
>    [Switching to thread 1 (process 748)]
>    #0  <PC register is not available>
>    (gdb) thread
>    [Current thread is 1 (process 748)]
>    (gdb)
> 
> Here is another "before/after" case.  Suppose we have two inferiors,
> each having its own remote target underneath.  Before this patch, we
> get the following output:
> 
>    # Create two inferiors on two remote targets, resume both until
>    # termination.  Exit event from one of them is shown first, but the
>    # other also exited -- just not yet shown.
>    (gdb) maint set target-non-stop on
>    (gdb) target remote | gdbserver - ./a.out
>    (gdb) add-inferior -no-connection
>    (gdb) inferior 2
>    (gdb) target remote | gdbserver - ./a.out
>    (gdb) set schedule-multiple on
>    (gdb) continue
>    ...
>    [Inferior 2 (process 22127) exited normally]
>    (gdb) inferior 1
>    [Switching to inferior 1 [process 22111] (target:/tmp/a.out)]
>    [Switching to thread 1.1 (Thread 22111.22111)]
>    Could not read registers; remote failure reply 'E01'
>    (gdb) info threads
>      Id   Target Id                  Frame
>    * 1.1  Thread 22111.22111 "a.out" Could not read registers; remote failure reply 'E01'
>    (gdb) backtrace
>    Python Exception <class 'gdb.error'>: Could not read registers; remote failure reply 'E01'
>    Could not read registers; remote failure reply 'E01'
>    (gdb) thread
>    [Current thread is 1.1 (Thread 22111.22111)]
>    Could not read registers; remote failure reply 'E01'
>    (gdb)
> 
> With this patch, it becomes:
> 
>    ...
>    [Inferior 1 (process 11759) exited normally]
>    (gdb) inferior 2
>    [Switching to inferior 2 [process 13440] (target:/path/to/a.out)]
>    [Switching to thread 2.1 (Thread 13440.13440)]
>    #0  <unavailable> in ?? ()
>    (gdb) info threads
>      Id   Target Id                   Frame
>    * 2.1  Thread 13440.13440 "a.out" <unavailable> in ?? ()
>    (gdb) backtrace
>    #0  <unavailable> in ?? ()
>    Backtrace stopped: not enough registers or memory available to unwind further
>    (gdb) thread
>    [Current thread is 2.1 (Thread 13440.13440)]
>    (gdb)
> 
> Finally, together with its predecessor, this patch also fixes PR gdb/26877.
> 
> Regression-tested on X86_64-Linux.
> ---
>   gdb/amd64-linux-nat.c                         |  5 +-
>   gdb/remote.c                                  | 15 ++--
>   gdb/stack.c                                   | 33 ++++++-
>   gdb/testsuite/gdb.threads/killed-outside.exp  |  8 +-
>   .../gdb.tui/multi-exit-remove-inferior.c      | 21 +++++
>   .../gdb.tui/multi-exit-remove-inferior.exp    | 86 +++++++++++++++++++
>   6 files changed, 156 insertions(+), 12 deletions(-)
>   create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.c
>   create mode 100644 gdb/testsuite/gdb.tui/multi-exit-remove-inferior.exp
> 
> diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
> index f7f9a483def..aa9b10c52d1 100644
> --- a/gdb/amd64-linux-nat.c
> +++ b/gdb/amd64-linux-nat.c
> @@ -223,7 +223,10 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
>         elf_gregset_t regs;
>   
>         if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
> -	perror_with_name (_("Couldn't get registers"));
> +	{
> +	  std::string msg = perror_string (_("Couldn't get registers"));
> +	  throw_error (NOT_AVAILABLE_ERROR, "%s", msg.c_str ());
> +	}

Should other nat backends for other OS's (and other arches) also make this change when
failing to fetch registers?

-- 
John Baldwin


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v4 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2023-12-20 22:00       ` John Baldwin
@ 2023-12-21  6:41         ` Eli Zaretskii
  2023-12-27 18:41           ` Aktemur, Tankut Baris
  0 siblings, 1 reply; 28+ messages in thread
From: Eli Zaretskii @ 2023-12-21  6:41 UTC (permalink / raw)
  To: John Baldwin; +Cc: tankut.baris.aktemur, gdb-patches

> Date: Wed, 20 Dec 2023 14:00:03 -0800
> From: John Baldwin <jhb@FreeBSD.org>
> 
> > --- a/gdb/amd64-linux-nat.c
> > +++ b/gdb/amd64-linux-nat.c
> > @@ -223,7 +223,10 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
> >         elf_gregset_t regs;
> >   
> >         if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
> > -	perror_with_name (_("Couldn't get registers"));
> > +	{
> > +	  std::string msg = perror_string (_("Couldn't get registers"));
> > +	  throw_error (NOT_AVAILABLE_ERROR, "%s", msg.c_str ());
> > +	}
> 
> Should other nat backends for other OS's (and other arches) also
> make this change when failing to fetch registers?

That's probably a good idea, yes.

But I also wonder whether the difference between

  Couldn't get registers: No such process.

or

  Could not read registers; remote failure reply 'E01'

and

  <PC register is not available>

or

  Backtrace stopped: not enough registers or memory available to unwind further

is such a significant improvement in terms of UX.  Both the "before"
and "after" messages allude to issues that are extremely technical and
obscure, IMO.  If anything, "No such process" sounds better to me than
"<PC register is not available>", because the former explicitly
explains the reason in high-level terms understood by anyone, while
the latter alludes to the PC register, which is a GDB abstraction, and
the fact that some register is not available doesn't necessarily tell
me what is wrong in practical terms.

IOW, it seems to me that, when we catch the error, we ought to produce
some meaningful message, and with this change we don't yet do that.

Does this make sense?

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH v4 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC
  2023-12-21  6:41         ` Eli Zaretskii
@ 2023-12-27 18:41           ` Aktemur, Tankut Baris
  0 siblings, 0 replies; 28+ messages in thread
From: Aktemur, Tankut Baris @ 2023-12-27 18:41 UTC (permalink / raw)
  To: Eli Zaretskii, John Baldwin; +Cc: gdb-patches

On Thursday, December 21, 2023 7:42 AM, Eli Zaretskii wrote:
> > Date: Wed, 20 Dec 2023 14:00:03 -0800
> > From: John Baldwin <jhb@FreeBSD.org>
> >
> > > --- a/gdb/amd64-linux-nat.c
> > > +++ b/gdb/amd64-linux-nat.c
> > > @@ -223,7 +223,10 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache,
> int regnum)
> > >         elf_gregset_t regs;
> > >
> > >         if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
> > > -	perror_with_name (_("Couldn't get registers"));
> > > +	{
> > > +	  std::string msg = perror_string (_("Couldn't get registers"));
> > > +	  throw_error (NOT_AVAILABLE_ERROR, "%s", msg.c_str ());
> > > +	}
> >
> > Should other nat backends for other OS's (and other arches) also
> > make this change when failing to fetch registers?
> 
> That's probably a good idea, yes.

Yes.  I didn't do that, however, because I don't have a chance to do regression
testing for the other targets.

> But I also wonder whether the difference between
> 
>   Couldn't get registers: No such process.
> 
> or
> 
>   Could not read registers; remote failure reply 'E01'
> 
> and
> 
>   <PC register is not available>
> 
> or
> 
>   Backtrace stopped: not enough registers or memory available to unwind further
> 
> is such a significant improvement in terms of UX.  Both the "before"
> and "after" messages allude to issues that are extremely technical and
> obscure, IMO.  If anything, "No such process" sounds better to me than
> "<PC register is not available>", because the former explicitly
> explains the reason in high-level terms understood by anyone, while
> the latter alludes to the PC register, which is a GDB abstraction, and
> the fact that some register is not available doesn't necessarily tell
> me what is wrong in practical terms.
> 
> IOW, it seems to me that, when we catch the error, we ought to produce
> some meaningful message, and with this change we don't yet do that.
> 
> Does this make sense?

We can remember the reason in regcache for why a particular register became
unavailable and use that reason in the error messages.  With such a change,
the output for the first case would become

      (gdb) start
      ...
      (gdb) info inferior
        Num  Description       Connection           Executable
      * 1    process 1017286   1 (native)           /tmp/a.out
      (gdb) shell kill -9 1017286
      (gdb) maintenance flush register-cache
      Register cache flushed.
      (gdb) info threads
        Id   Target Id                                   Frame
      * 1    Thread 0x7ffff7d87740 (LWP 1017286) "a.out" <Couldn't get registers: No such process>
      (gdb) backtrace
      #0  <Couldn't get registers: No such process>
      Backtrace stopped: not enough registers or memory available to unwind further
      (gdb) inferior 1
      [Switching to inferior 1 [process 1017286] (/tmp/a.out)]
      [Switching to thread 1 (Thread 0x7ffff7d87740 (LWP 1017286))]
      #0  <Couldn't get registers: No such process>
      (gdb) thread
      [Current thread is 1 (Thread 0x7ffff7d87740 (LWP 1017286))]
      (gdb)

Does this look acceptable?

Regards
-Baris


Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2023-12-27 18:42 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-08  9:15 [PATCH v2 0/2] Querying registers of already-exited processes Tankut Baris Aktemur
2022-02-08  9:15 ` [PATCH v2 1/2] gdb/regcache: return REG_UNAVAILABLE if raw_update raises NOT_AVAILABLE_ERROR Tankut Baris Aktemur
2022-03-16 15:18   ` Bruno Larsen
2022-03-23 12:55     ` Aktemur, Tankut Baris
2022-02-08  9:15 ` [PATCH v2 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
2022-03-16 17:26   ` Bruno Larsen
2022-03-23 12:55     ` Aktemur, Tankut Baris
2022-03-23 13:34       ` Bruno Larsen
2022-03-24  8:46         ` Aktemur, Tankut Baris
2022-02-22  7:31 ` [PATCH v2 0/2] Querying registers of already-exited processes Aktemur, Tankut Baris
2022-03-07  8:00 ` Aktemur, Tankut Baris
2022-03-23 13:05 ` [PATCH v3 " Tankut Baris Aktemur
2022-03-23 13:05   ` [PATCH v3 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen Tankut Baris Aktemur
2022-03-23 13:05   ` [PATCH v3 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
2022-05-04  7:19   ` [PATCH v3 0/2] Querying registers of already-exited processes Aktemur, Tankut Baris
2022-12-23 17:10     ` Aktemur, Tankut Baris
2023-01-17 20:40       ` Aktemur, Tankut Baris
2023-01-24 10:35       ` Aktemur, Tankut Baris
2023-01-31 20:14       ` Aktemur, Tankut Baris
2023-02-20 13:07       ` Aktemur, Tankut Baris
2023-03-03  7:46       ` Aktemur, Tankut Baris
2023-03-28 13:40       ` Aktemur, Tankut Baris
2023-12-18 14:40   ` [PATCH v4 " Tankut Baris Aktemur
2023-12-18 14:40     ` [PATCH v4 1/2] gdb/regcache: return REG_UNAVAILABLE in raw_read if NOT_AVAILABLE_ERROR is seen Tankut Baris Aktemur
2023-12-18 14:40     ` [PATCH v4 2/2] gdb: raise and handle NOT_AVAILABLE_ERROR when accessing frame PC Tankut Baris Aktemur
2023-12-20 22:00       ` John Baldwin
2023-12-21  6:41         ` Eli Zaretskii
2023-12-27 18:41           ` Aktemur, Tankut Baris

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).