gdb/riscv: Handle errors while setting the frame id
authorAndrew Burgess <andrew.burgess@embecosm.com>
Mon, 29 Oct 2018 15:14:03 +0000 (15:14 +0000)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Thu, 8 Nov 2018 09:34:19 +0000 (09:34 +0000)
commit17cf2897848e893d49b69eb65e00bbf71eb503ba
tree25bc24674e20f0a82c9330098fe573669dca517f
parent5acaada74578ee6a902255f0272d5f3115b76309
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.
gdb/ChangeLog
gdb/riscv-tdep.c