This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] gdb/riscv: Handle errors while setting the frame id


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=17cf2897848e893d49b69eb65e00bbf71eb503ba

commit 17cf2897848e893d49b69eb65e00bbf71eb503ba
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Mon Oct 29 15:14:03 2018 +0000

    gdb/riscv: Handle errors while setting the frame id
    
    When we connect to a remote target one of the first things GDB does is
    establish a frame id.  If an error is thrown while building this frame
    id then GDB will disconnect from the target.
    
    This can mean that, if the user is attempting to connect to a target
    that doesn't yet have a program loaded, or the program the user is
    going to load onto the target doesn't match what is already loaded, or
    the target is just in some undefined state, then the very first
    request for a frame id can fail (for example, by trying to load from
    an invalid memory address), and GDB will disconnect.  It is then
    impossible for the user to connect to the target and load a new
    program at all.
    
    An example of such a session might look like this:
    
        Reading symbols from ./gdb/testsuite/outputs/gdb.arch/riscv-reg-aliases/riscv-reg-aliases...
        (gdb) target remote :37191
        Remote debugging using :37191
        0x0000000000000100 in ?? ()
        Cannot access memory at address 0x0
        (gdb) load
        You can't do that when your target is `exec'
        (gdb) info frame
        /path/to/gdb/gdb/thread.c:93: internal-error: thread_info* inferior_thread(): Assertion `tp' failed.
        A problem internal to GDB has been detected,
        further debugging may prove unreliable.
        Quit this debugging session? (y or n)
    
    The solution is to handle errors in riscv_frame_this_id, and leave the
    this_id variable with its default value, which is the predefined
    'outermost' frame.
    
    With this fix in place, connecting to the same target now looks like
    this:
    
        (gdb) target remote :37191
        Remote debugging using :37191
        0x0000000000000100 in ?? ()
        (gdb) info frame
        Stack level 0, frame at 0x0:
         pc = 0x100; saved pc = <not saved>
         Outermost frame: outermost
         Arglist at unknown address.
         Locals at unknown address, Previous frame's sp in sp
    
    gdb/ChangeLog:
    
    	* riscv-tdep.c (riscv_insn::decode): Update header comment.
    	(riscv_frame_this_id): Catch errors thrown while building the
    	frame cache, leave the frame id as the default, which is the outer
    	frame id.

Diff:
---
 gdb/ChangeLog    |  7 +++++++
 gdb/riscv-tdep.c | 17 ++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9c277f5..48baa37 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-08  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* riscv-tdep.c (riscv_insn::decode): Update header comment.
+	(riscv_frame_this_id): Catch errors thrown while building the
+	frame cache, leave the frame id as the default, which is the outer
+	frame id.
+
 2018-11-07  Joel Brobecker  <brobecker@adacore.com>
 
 	* ada-lang.c (read_atcb): Only set task_info->called_task if
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index db372e2..7a92fc7 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1256,7 +1256,9 @@ riscv_insn::fetch_instruction (struct gdbarch *gdbarch,
   return extract_unsigned_integer (buf, instlen, byte_order);
 }
 
-/* Fetch from target memory an instruction at PC and decode it.  */
+/* Fetch from target memory an instruction at PC and decode it.  This can
+   throw an error if the memory access fails, callers are responsible for
+   handling this error if that is appropriate.  */
 
 void
 riscv_insn::decode (struct gdbarch *gdbarch, CORE_ADDR pc)
@@ -2752,8 +2754,17 @@ riscv_frame_this_id (struct frame_info *this_frame,
 {
   struct riscv_unwind_cache *cache;
 
-  cache = riscv_frame_cache (this_frame, prologue_cache);
-  *this_id = cache->this_id;
+  TRY
+    {
+      cache = riscv_frame_cache (this_frame, prologue_cache);
+      *this_id = cache->this_id;
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      /* Ignore errors, this leaves the frame id as the predefined outer
+         frame id which terminates the backtrace at this point.  */
+    }
+  END_CATCH
 }
 
 /* Implement the prev_register callback for RiscV frame unwinder.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]