mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-14 11:25:52 +08:00
Move unwind reasons to an external .def file
gdb/ * frame.c (frame_stop_reason_string): Rewrite using unwind_stop_reasons.def. * frame.h (enum unwind_stop_reason): Likewise. * python/py-frame.c (gdbpy_initialize_frames): Likewise. (gdbpy_frame_stop_reason_string): Use new enum unwind_stop_reason constants for bound-checking. * unwind_stop_reasons.def: New file. * stack.c (backtrace_command_1): Handle UNWIND_FIRST_ERROR as an alias instead of a distinct value. doc/ * gdb.texinfo ((Frames In Python): Document gdb.FRAME_UNWIND_FIRST_ERROR contant.
This commit is contained in:
@ -1,3 +1,16 @@
|
||||
2011-10-27 Kevin Pouget <kevin.pouget@st.com>
|
||||
|
||||
Move unwind reasons to an external .def file
|
||||
* frame.c (frame_stop_reason_string): Rewrite using
|
||||
unwind_stop_reasons.def.
|
||||
* frame.h (enum unwind_stop_reason): Likewise.
|
||||
* python/py-frame.c (gdbpy_initialize_frames): Likewise.
|
||||
(gdbpy_frame_stop_reason_string): Use new enum unwind_stop_reason
|
||||
constants for bound-checking.
|
||||
* unwind_stop_reasons.def: New file.
|
||||
* stack.c (backtrace_command_1): Handle UNWIND_FIRST_ERROR as an alias
|
||||
instead of a distinct value.
|
||||
|
||||
2011-10-27 Phil Muldoon <pmuldoon@redhat.com>
|
||||
|
||||
PR python/13331
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-10-27 Kevin Pouget <kevin.pouget@st.com>
|
||||
|
||||
* gdb.texinfo ((Frames In Python): Document
|
||||
gdb.FRAME_UNWIND_FIRST_ERROR contant.
|
||||
|
||||
2011-10-26 Paul Koning <paul_koning@dell.com>
|
||||
|
||||
* gdb.texinfo (gdb.types): Document new deepitems function.
|
||||
|
@ -23473,6 +23473,19 @@ stack corruption.
|
||||
@item gdb.FRAME_UNWIND_NO_SAVED_PC
|
||||
The frame unwinder did not find any saved PC, but we needed
|
||||
one to unwind further.
|
||||
|
||||
@item gdb.FRAME_UNWIND_FIRST_ERROR
|
||||
Any stop reason greater or equal to this value indicates some kind
|
||||
of error. This special value facilitates writing code that tests
|
||||
for errors in unwinding in a way that will work correctly even if
|
||||
the list of the other values is modified in future @value{GDBN}
|
||||
versions. Using it, you could write:
|
||||
@smallexample
|
||||
reason = gdb.selected_frame().unwind_stop_reason ()
|
||||
reason_str = gdb.frame_stop_reason_string (reason)
|
||||
if reason >= gdb.FRAME_UNWIND_FIRST_ERROR:
|
||||
print "An error occured: %s" % reason_str
|
||||
@end smallexample
|
||||
@end table
|
||||
|
||||
@end defun
|
||||
|
20
gdb/frame.c
20
gdb/frame.c
@ -2351,23 +2351,11 @@ frame_stop_reason_string (enum unwind_stop_reason reason)
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
case UNWIND_NULL_ID:
|
||||
return _("unwinder did not report frame ID");
|
||||
#define SET(name, description) \
|
||||
case name: return _(description);
|
||||
#include "unwind_stop_reasons.def"
|
||||
#undef SET
|
||||
|
||||
case UNWIND_UNAVAILABLE:
|
||||
return _("Not enough registers or memory available to unwind further");
|
||||
|
||||
case UNWIND_INNER_ID:
|
||||
return _("previous frame inner to this frame (corrupt stack?)");
|
||||
|
||||
case UNWIND_SAME_ID:
|
||||
return _("previous frame identical to this frame (corrupt stack?)");
|
||||
|
||||
case UNWIND_NO_SAVED_PC:
|
||||
return _("frame did not save the PC");
|
||||
|
||||
case UNWIND_NO_REASON:
|
||||
case UNWIND_FIRST_ERROR:
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"Invalid frame stop reason");
|
||||
|
49
gdb/frame.h
49
gdb/frame.h
@ -446,47 +446,16 @@ extern struct address_space *get_frame_address_space (struct frame_info *);
|
||||
|
||||
enum unwind_stop_reason
|
||||
{
|
||||
/* No particular reason; either we haven't tried unwinding yet,
|
||||
or we didn't fail. */
|
||||
UNWIND_NO_REASON,
|
||||
#define SET(name, description) name,
|
||||
#define FIRST_ENTRY(name) UNWIND_FIRST = name,
|
||||
#define LAST_ENTRY(name) UNWIND_LAST = name,
|
||||
#define FIRST_ERROR(name) UNWIND_FIRST_ERROR = name,
|
||||
|
||||
/* The previous frame's analyzer returns an invalid result
|
||||
from this_id.
|
||||
|
||||
FIXME drow/2006-08-16: This is how GDB used to indicate end of
|
||||
stack. We should migrate to a model where frames always have a
|
||||
valid ID, and this becomes not just an error but an internal
|
||||
error. But that's a project for another day. */
|
||||
UNWIND_NULL_ID,
|
||||
|
||||
/* This frame is the outermost. */
|
||||
UNWIND_OUTERMOST,
|
||||
|
||||
/* All the conditions after this point are considered errors;
|
||||
abnormal stack termination. If a backtrace stops for one
|
||||
of these reasons, we'll let the user know. This marker
|
||||
is not a valid stop reason. */
|
||||
UNWIND_FIRST_ERROR,
|
||||
|
||||
/* Can't unwind further, because that would require knowing the
|
||||
values of registers or memory that haven't been collected. */
|
||||
UNWIND_UNAVAILABLE,
|
||||
|
||||
/* This frame ID looks like it ought to belong to a NEXT frame,
|
||||
but we got it for a PREV frame. Normally, this is a sign of
|
||||
unwinder failure. It could also indicate stack corruption. */
|
||||
UNWIND_INNER_ID,
|
||||
|
||||
/* This frame has the same ID as the previous one. That means
|
||||
that unwinding further would almost certainly give us another
|
||||
frame with exactly the same ID, so break the chain. Normally,
|
||||
this is a sign of unwinder failure. It could also indicate
|
||||
stack corruption. */
|
||||
UNWIND_SAME_ID,
|
||||
|
||||
/* The frame unwinder didn't find any saved PC, but we needed
|
||||
one to unwind further. */
|
||||
UNWIND_NO_SAVED_PC,
|
||||
#include "unwind_stop_reasons.def"
|
||||
#undef SET
|
||||
#undef FIRST_ENTRY
|
||||
#undef LAST_ENTRY
|
||||
#undef FIRST_ERROR
|
||||
};
|
||||
|
||||
/* Return the reason why we can't unwind past this frame. */
|
||||
|
@ -553,7 +553,7 @@ gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple (args, "i", &reason))
|
||||
return NULL;
|
||||
|
||||
if (reason < 0 || reason > UNWIND_NO_SAVED_PC)
|
||||
if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
|
||||
{
|
||||
PyErr_SetString (PyExc_ValueError,
|
||||
_("Invalid frame stop reason."));
|
||||
@ -610,18 +610,13 @@ gdbpy_initialize_frames (void)
|
||||
PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME);
|
||||
PyModule_AddIntConstant (gdb_module, "ARCH_FRAME", ARCH_FRAME);
|
||||
PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME);
|
||||
PyModule_AddIntConstant (gdb_module,
|
||||
"FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON);
|
||||
PyModule_AddIntConstant (gdb_module,
|
||||
"FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID);
|
||||
PyModule_AddIntConstant (gdb_module,
|
||||
"FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR);
|
||||
PyModule_AddIntConstant (gdb_module,
|
||||
"FRAME_UNWIND_INNER_ID", UNWIND_INNER_ID);
|
||||
PyModule_AddIntConstant (gdb_module,
|
||||
"FRAME_UNWIND_SAME_ID", UNWIND_SAME_ID);
|
||||
PyModule_AddIntConstant (gdb_module,
|
||||
"FRAME_UNWIND_NO_SAVED_PC", UNWIND_NO_SAVED_PC);
|
||||
|
||||
#define SET(name, description) \
|
||||
PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name);
|
||||
#define FIRST_ERROR(name) \
|
||||
PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name);
|
||||
#include "unwind_stop_reasons.def"
|
||||
#undef SET
|
||||
|
||||
Py_INCREF (&frame_object_type);
|
||||
PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type);
|
||||
|
@ -1625,7 +1625,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
|
||||
enum unwind_stop_reason reason;
|
||||
|
||||
reason = get_frame_unwind_stop_reason (trailing);
|
||||
if (reason > UNWIND_FIRST_ERROR)
|
||||
if (reason >= UNWIND_FIRST_ERROR)
|
||||
printf_filtered (_("Backtrace stopped: %s\n"),
|
||||
frame_stop_reason_string (reason));
|
||||
}
|
||||
|
80
gdb/unwind_stop_reasons.def
Normal file
80
gdb/unwind_stop_reasons.def
Normal file
@ -0,0 +1,80 @@
|
||||
/* Copyright 2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Reasons why frames could not be further unwound
|
||||
SET (name, description)
|
||||
|
||||
After this reason name, all reasons should be considered errors;
|
||||
i.e.: abnormal stack termination.
|
||||
FIRST_ERROR (name)
|
||||
|
||||
First and Last reason defined
|
||||
FIRST_ENTRY (name)
|
||||
LAST_ENTRY (name) */
|
||||
|
||||
#ifdef SET
|
||||
/* No particular reason; either we haven't tried unwinding yet,
|
||||
or we didn't fail. */
|
||||
SET (UNWIND_NO_REASON, "no reason")
|
||||
|
||||
/* The previous frame's analyzer returns an invalid result
|
||||
from this_id.
|
||||
|
||||
FIXME drow/2006-08-16: This is how GDB used to indicate end of
|
||||
stack. We should migrate to a model where frames always have a
|
||||
valid ID, and this becomes not just an error but an internal
|
||||
error. But that's a project for another day. */
|
||||
SET (UNWIND_NULL_ID, "unwinder did not report frame ID")
|
||||
|
||||
/* This frame is the outermost. */
|
||||
SET (UNWIND_OUTERMOST, "outermost")
|
||||
|
||||
/* Can't unwind further, because that would require knowing the
|
||||
values of registers or memory that haven't been collected. */
|
||||
SET (UNWIND_UNAVAILABLE, \
|
||||
"not enough registers or memory available to unwind further")
|
||||
|
||||
/* This frame ID looks like it ought to belong to a NEXT frame,
|
||||
but we got it for a PREV frame. Normally, this is a sign of
|
||||
unwinder failure. It could also indicate stack corruption. */
|
||||
SET (UNWIND_INNER_ID, "previous frame inner to this frame (corrupt stack?)")
|
||||
|
||||
/* This frame has the same ID as the previous one. That means
|
||||
that unwinding further would almost certainly give us another
|
||||
frame with exactly the same ID, so break the chain. Normally,
|
||||
this is a sign of unwinder failure. It could also indicate
|
||||
stack corruption. */
|
||||
SET (UNWIND_SAME_ID, "previous frame identical to this frame (corrupt stack?)")
|
||||
|
||||
/* The frame unwinder didn't find any saved PC, but we needed
|
||||
one to unwind further. */
|
||||
SET (UNWIND_NO_SAVED_PC, "frame did not save the PC")
|
||||
|
||||
#endif /* SET */
|
||||
|
||||
|
||||
#ifdef FIRST_ERROR
|
||||
FIRST_ERROR (UNWIND_UNAVAILABLE)
|
||||
#endif
|
||||
|
||||
#ifdef FIRST_ENTRY
|
||||
FIRST_ENTRY (UNWIND_NO_REASON)
|
||||
#endif
|
||||
|
||||
#ifdef LAST_ENTRY
|
||||
LAST_ENTRY (UNWIND_NO_SAVED_PC)
|
||||
#endif
|
Reference in New Issue
Block a user