mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-14 19:38:01 +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>
|
2011-10-27 Phil Muldoon <pmuldoon@redhat.com>
|
||||||
|
|
||||||
PR python/13331
|
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>
|
2011-10-26 Paul Koning <paul_koning@dell.com>
|
||||||
|
|
||||||
* gdb.texinfo (gdb.types): Document new deepitems function.
|
* gdb.texinfo (gdb.types): Document new deepitems function.
|
||||||
|
@ -23473,6 +23473,19 @@ stack corruption.
|
|||||||
@item gdb.FRAME_UNWIND_NO_SAVED_PC
|
@item gdb.FRAME_UNWIND_NO_SAVED_PC
|
||||||
The frame unwinder did not find any saved PC, but we needed
|
The frame unwinder did not find any saved PC, but we needed
|
||||||
one to unwind further.
|
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 table
|
||||||
|
|
||||||
@end defun
|
@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)
|
switch (reason)
|
||||||
{
|
{
|
||||||
case UNWIND_NULL_ID:
|
#define SET(name, description) \
|
||||||
return _("unwinder did not report frame ID");
|
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:
|
default:
|
||||||
internal_error (__FILE__, __LINE__,
|
internal_error (__FILE__, __LINE__,
|
||||||
"Invalid frame stop reason");
|
"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
|
enum unwind_stop_reason
|
||||||
{
|
{
|
||||||
/* No particular reason; either we haven't tried unwinding yet,
|
#define SET(name, description) name,
|
||||||
or we didn't fail. */
|
#define FIRST_ENTRY(name) UNWIND_FIRST = name,
|
||||||
UNWIND_NO_REASON,
|
#define LAST_ENTRY(name) UNWIND_LAST = name,
|
||||||
|
#define FIRST_ERROR(name) UNWIND_FIRST_ERROR = name,
|
||||||
|
|
||||||
/* The previous frame's analyzer returns an invalid result
|
#include "unwind_stop_reasons.def"
|
||||||
from this_id.
|
#undef SET
|
||||||
|
#undef FIRST_ENTRY
|
||||||
FIXME drow/2006-08-16: This is how GDB used to indicate end of
|
#undef LAST_ENTRY
|
||||||
stack. We should migrate to a model where frames always have a
|
#undef FIRST_ERROR
|
||||||
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,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return the reason why we can't unwind past this frame. */
|
/* 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))
|
if (!PyArg_ParseTuple (args, "i", &reason))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (reason < 0 || reason > UNWIND_NO_SAVED_PC)
|
if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
|
||||||
{
|
{
|
||||||
PyErr_SetString (PyExc_ValueError,
|
PyErr_SetString (PyExc_ValueError,
|
||||||
_("Invalid frame stop reason."));
|
_("Invalid frame stop reason."));
|
||||||
@ -610,18 +610,13 @@ gdbpy_initialize_frames (void)
|
|||||||
PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME);
|
PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME);
|
||||||
PyModule_AddIntConstant (gdb_module, "ARCH_FRAME", ARCH_FRAME);
|
PyModule_AddIntConstant (gdb_module, "ARCH_FRAME", ARCH_FRAME);
|
||||||
PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME);
|
PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME);
|
||||||
PyModule_AddIntConstant (gdb_module,
|
|
||||||
"FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON);
|
#define SET(name, description) \
|
||||||
PyModule_AddIntConstant (gdb_module,
|
PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name);
|
||||||
"FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID);
|
#define FIRST_ERROR(name) \
|
||||||
PyModule_AddIntConstant (gdb_module,
|
PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name);
|
||||||
"FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR);
|
#include "unwind_stop_reasons.def"
|
||||||
PyModule_AddIntConstant (gdb_module,
|
#undef SET
|
||||||
"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);
|
|
||||||
|
|
||||||
Py_INCREF (&frame_object_type);
|
Py_INCREF (&frame_object_type);
|
||||||
PyModule_AddObject (gdb_module, "Frame", (PyObject *) &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;
|
enum unwind_stop_reason reason;
|
||||||
|
|
||||||
reason = get_frame_unwind_stop_reason (trailing);
|
reason = get_frame_unwind_stop_reason (trailing);
|
||||||
if (reason > UNWIND_FIRST_ERROR)
|
if (reason >= UNWIND_FIRST_ERROR)
|
||||||
printf_filtered (_("Backtrace stopped: %s\n"),
|
printf_filtered (_("Backtrace stopped: %s\n"),
|
||||||
frame_stop_reason_string (reason));
|
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