/* Cache and manage frames for GDB, the GNU debugger.
- Copyright (C) 1986-2018 Free Software Foundation, Inc.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
{
if (this_frame->prev_pc.status == CC_UNKNOWN)
{
- if (gdbarch_unwind_pc_p (frame_unwind_arch (this_frame)))
+ struct gdbarch *prev_gdbarch;
+ CORE_ADDR pc = 0;
+ int pc_p = 0;
+
+ /* The right way. The `pure' way. The one true way. This
+ method depends solely on the register-unwind code to
+ determine the value of registers in THIS frame, and hence
+ the value of this frame's PC (resume address). A typical
+ implementation is no more than:
+
+ frame_unwind_register (this_frame, ISA_PC_REGNUM, buf);
+ return extract_unsigned_integer (buf, size of ISA_PC_REGNUM);
+
+ Note: this method is very heavily dependent on a correct
+ register-unwind implementation, it pays to fix that
+ method first; this method is frame type agnostic, since
+ it only deals with register values, it works with any
+ frame. This is all in stark contrast to the old
+ FRAME_SAVED_PC which would try to directly handle all the
+ different ways that a PC could be unwound. */
+ prev_gdbarch = frame_unwind_arch (this_frame);
+
+ try
{
- struct gdbarch *prev_gdbarch;
- CORE_ADDR pc = 0;
- int pc_p = 0;
-
- /* The right way. The `pure' way. The one true way. This
- method depends solely on the register-unwind code to
- determine the value of registers in THIS frame, and hence
- the value of this frame's PC (resume address). A typical
- implementation is no more than:
-
- frame_unwind_register (this_frame, ISA_PC_REGNUM, buf);
- return extract_unsigned_integer (buf, size of ISA_PC_REGNUM);
-
- Note: this method is very heavily dependent on a correct
- register-unwind implementation, it pays to fix that
- method first; this method is frame type agnostic, since
- it only deals with register values, it works with any
- frame. This is all in stark contrast to the old
- FRAME_SAVED_PC which would try to directly handle all the
- different ways that a PC could be unwound. */
- prev_gdbarch = frame_unwind_arch (this_frame);
-
- TRY
+ pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
+ pc_p = 1;
+ }
+ catch (const gdb_exception_error &ex)
+ {
+ if (ex.error == NOT_AVAILABLE_ERROR)
{
- pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
- pc_p = 1;
+ this_frame->prev_pc.status = CC_UNAVAILABLE;
+
+ if (frame_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "{ frame_unwind_pc (this_frame=%d)"
+ " -> <unavailable> }\n",
+ this_frame->level);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ else if (ex.error == OPTIMIZED_OUT_ERROR)
{
- if (ex.error == NOT_AVAILABLE_ERROR)
- {
- this_frame->prev_pc.status = CC_UNAVAILABLE;
-
- if (frame_debug)
- fprintf_unfiltered (gdb_stdlog,
- "{ frame_unwind_pc (this_frame=%d)"
- " -> <unavailable> }\n",
- this_frame->level);
- }
- else if (ex.error == OPTIMIZED_OUT_ERROR)
- {
- this_frame->prev_pc.status = CC_NOT_SAVED;
-
- if (frame_debug)
- fprintf_unfiltered (gdb_stdlog,
- "{ frame_unwind_pc (this_frame=%d)"
- " -> <not saved> }\n",
- this_frame->level);
- }
- else
- throw_exception (ex);
- }
- END_CATCH
+ this_frame->prev_pc.status = CC_NOT_SAVED;
- if (pc_p)
- {
- this_frame->prev_pc.value = pc;
- this_frame->prev_pc.status = CC_VALUE;
if (frame_debug)
fprintf_unfiltered (gdb_stdlog,
- "{ frame_unwind_pc (this_frame=%d) "
- "-> %s }\n",
- this_frame->level,
- hex_string (this_frame->prev_pc.value));
+ "{ frame_unwind_pc (this_frame=%d)"
+ " -> <not saved> }\n",
+ this_frame->level);
}
+ else
+ throw;
+ }
+
+ if (pc_p)
+ {
+ this_frame->prev_pc.value = pc;
+ this_frame->prev_pc.status = CC_VALUE;
+ if (frame_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "{ frame_unwind_pc (this_frame=%d) "
+ "-> %s }\n",
+ this_frame->level,
+ hex_string (this_frame->prev_pc.value));
}
- else
- internal_error (__FILE__, __LINE__, _("No unwind_pc method"));
}
if (this_frame->prev_pc.status == CC_VALUE)
if (prev_frame->level == 0)
return prev_frame;
- TRY
+ try
{
compute_frame_id (prev_frame);
if (!frame_stash_add (prev_frame))
prev_frame = NULL;
}
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
prev_frame->next = NULL;
this_frame->prev = NULL;
- throw_exception (ex);
+ throw;
}
- END_CATCH
return prev_frame;
}
{
struct frame_info *prev_frame = NULL;
- TRY
+ try
{
prev_frame = get_prev_frame_always_1 (this_frame);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (ex.error == MEMORY_ERROR)
{
Allocate using stack local STOP_STRING then assign the
pointer to the frame, this allows the STOP_STRING on the
frame to be of type 'const char *'. */
- size = strlen (ex.message) + 1;
+ size = ex.message->size () + 1;
stop_string = (char *) frame_obstack_zalloc (size);
- memcpy (stop_string, ex.message, size);
+ memcpy (stop_string, ex.what (), size);
this_frame->stop_string = stop_string;
}
prev_frame = NULL;
}
else
- throw_exception (ex);
+ throw;
}
- END_CATCH
return prev_frame;
}
gdb_assert (frame->next != NULL);
- TRY
+ try
{
*pc = frame_unwind_pc (frame->next);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (ex.error == NOT_AVAILABLE_ERROR)
return 0;
else
- throw_exception (ex);
+ throw;
}
- END_CATCH
return 1;
}
CORE_ADDR *pc)
{
- TRY
+ try
{
*pc = get_frame_address_in_block (this_frame);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (ex.error == NOT_AVAILABLE_ERROR)
return 0;
- throw_exception (ex);
+ throw;
}
- END_CATCH
return 1;
}
a PC that is guaranteed to be inside the frame's code
block. */
- TRY
+ try
{
pc = get_frame_address_in_block (frame);
pc_p = 1;
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (ex.error != NOT_AVAILABLE_ERROR)
- throw_exception (ex);
+ throw;
}
- END_CATCH
if (pc_p)
{
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
- /* Normality - an architecture that provides a way of obtaining any
- frame inner-most address. */
- if (gdbarch_unwind_sp_p (gdbarch))
- /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to
- operate on THIS_FRAME now. */
- return gdbarch_unwind_sp (gdbarch, this_frame->next);
- /* Now things are really are grim. Hope that the value returned by
- the gdbarch_sp_regnum register is meaningful. */
- if (gdbarch_sp_regnum (gdbarch) >= 0)
- return get_frame_register_unsigned (this_frame,
- gdbarch_sp_regnum (gdbarch));
- internal_error (__FILE__, __LINE__, _("Missing unwind SP method"));
+ /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to
+ operate on THIS_FRAME now. */
+ return gdbarch_unwind_sp (gdbarch, this_frame->next);
}
/* Return the reason why we can't unwind past FRAME. */