mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 01:07:52 +00:00
2010-02-24 Phil Muldoon <pmuldoon@redhat.com>
Tom Tromey <tromey@redhat.com> Thiago Jung Bauermann <bauerman@br.ibm.com> * python/python.c (_initialize_python): Call gdbpy_initialize_symtabs, gdbpy_initialize_symbols and gdbpy_initialize_blocks. * python/python-internal.h: Declare struct symbol, block and symtab_and_line. Declare block_object_type and symbol_object_type (gdbpy_lookup_symbol gdbpy_block_for_pc) (symtab_and_line_to_sal_object, symtab_to_symtab_object) (symbol_to_symbol_object, block_to_block_object) (gdbpy_initialize_symtabs,gdbpy_initialize_symbols) (gdbpy_initialize_blocks ): Declare. * python/py-frame.c (frapy_block, frapy_function, frapy_find_sal) (frapy_select): Add methods. (frapy_read_var): Add symbol branch. * Makefile.in (SUBDIR_PYTHON_OBS): Add py-symbol, py-symtab, py-block. (SUBDIR_PYTHON_SRCS): Likewise. (py-symbol.o): New rule. (py-symtab.o): Likewise. (py-block.o): Likewise. * python/py-symbol.c: New file. * python/py-symtab.c: Likewise. * python/py-block.c: Likewise. 2010-02-24 Phil Muldoon <pmuldoon@redhat.com> * Makefile.in: Add py-block and py-symbol. * gdb.python/py-symbol.exp: New File. * gdb.python/py-symtab.exp: New File. * gdb.python/py-block.exp: New File. * gdb.python/py-symbol.c: New File. * gdb.python/py-block.c: New File. 2010-02-24 Phil Muldoon <pmuldoon@redhat.com> * gdb.texinfo (Frames In Python): Add block, find_sal, function and select method descriptions. (Python API): Add Blocks In Python, Symbols in Python and Symbol Tables in Python to menu. (Blocks In Python): New node. (Symbols In Python): New node. (Symbol Tables in Python): New node.
This commit is contained in:
@@ -1,3 +1,31 @@
|
|||||||
|
2010-02-24 Phil Muldoon <pmuldoon@redhat.com>
|
||||||
|
Tom Tromey <tromey@redhat.com>
|
||||||
|
Thiago Jung Bauermann <bauerman@br.ibm.com>
|
||||||
|
|
||||||
|
* python/python.c (_initialize_python): Call
|
||||||
|
gdbpy_initialize_symtabs, gdbpy_initialize_symbols and
|
||||||
|
gdbpy_initialize_blocks.
|
||||||
|
* python/python-internal.h: Declare struct symbol, block and
|
||||||
|
symtab_and_line. Declare block_object_type and
|
||||||
|
symbol_object_type
|
||||||
|
(gdbpy_lookup_symbol gdbpy_block_for_pc)
|
||||||
|
(symtab_and_line_to_sal_object, symtab_to_symtab_object)
|
||||||
|
(symbol_to_symbol_object, block_to_block_object)
|
||||||
|
(gdbpy_initialize_symtabs,gdbpy_initialize_symbols)
|
||||||
|
(gdbpy_initialize_blocks ): Declare.
|
||||||
|
* python/py-frame.c (frapy_block, frapy_function, frapy_find_sal)
|
||||||
|
(frapy_select): Add methods.
|
||||||
|
(frapy_read_var): Add symbol branch.
|
||||||
|
* Makefile.in (SUBDIR_PYTHON_OBS): Add py-symbol, py-symtab,
|
||||||
|
py-block.
|
||||||
|
(SUBDIR_PYTHON_SRCS): Likewise.
|
||||||
|
(py-symbol.o): New rule.
|
||||||
|
(py-symtab.o): Likewise.
|
||||||
|
(py-block.o): Likewise.
|
||||||
|
* python/py-symbol.c: New file.
|
||||||
|
* python/py-symtab.c: Likewise.
|
||||||
|
* python/py-block.c: Likewise.
|
||||||
|
|
||||||
2010-02-24 Pedro Alves <pedro@codesourcery.com>
|
2010-02-24 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
PR gdb/11321
|
PR gdb/11321
|
||||||
|
|||||||
@@ -267,23 +267,29 @@ SUBDIR_TUI_CFLAGS= \
|
|||||||
#
|
#
|
||||||
SUBDIR_PYTHON_OBS = \
|
SUBDIR_PYTHON_OBS = \
|
||||||
python.o \
|
python.o \
|
||||||
|
py-block.o \
|
||||||
py-cmd.o \
|
py-cmd.o \
|
||||||
py-frame.o \
|
py-frame.o \
|
||||||
py-function.o \
|
py-function.o \
|
||||||
py-lazy-string.o \
|
py-lazy-string.o \
|
||||||
py-objfile.o \
|
py-objfile.o \
|
||||||
py-prettyprint.o \
|
py-prettyprint.o \
|
||||||
|
py-symbol.o \
|
||||||
|
py-symtab.o \
|
||||||
py-type.o \
|
py-type.o \
|
||||||
py-utils.o \
|
py-utils.o \
|
||||||
py-value.o
|
py-value.o
|
||||||
SUBDIR_PYTHON_SRCS = \
|
SUBDIR_PYTHON_SRCS = \
|
||||||
python/python.c \
|
python/python.c \
|
||||||
|
python/py-block.c \
|
||||||
python/py-cmd.c \
|
python/py-cmd.c \
|
||||||
python/py-frame.c \
|
python/py-frame.c \
|
||||||
python/py-function.c \
|
python/py-function.c \
|
||||||
python/py-lazy-string.c \
|
python/py-lazy-string.c \
|
||||||
python/py-objfile.c \
|
python/py-objfile.c \
|
||||||
python/py-prettyprint.c \
|
python/py-prettyprint.c \
|
||||||
|
python/py-symbol.c \
|
||||||
|
python/py-symtab.c \
|
||||||
python/py-type.c \
|
python/py-type.c \
|
||||||
python/py-utils.c \
|
python/py-utils.c \
|
||||||
python/py-value.c
|
python/py-value.c
|
||||||
@@ -1971,6 +1977,10 @@ python.o: $(srcdir)/python/python.c
|
|||||||
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
|
||||||
$(POSTCOMPILE)
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
|
py-block.o: $(srcdir)/python/py-block.c
|
||||||
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-block.c
|
||||||
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
py-cmd.o: $(srcdir)/python/py-cmd.c
|
py-cmd.o: $(srcdir)/python/py-cmd.c
|
||||||
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-cmd.c
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-cmd.c
|
||||||
$(POSTCOMPILE)
|
$(POSTCOMPILE)
|
||||||
@@ -1995,6 +2005,14 @@ py-prettyprint.o: $(srcdir)/python/py-prettyprint.c
|
|||||||
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c
|
||||||
$(POSTCOMPILE)
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
|
py-symbol.o: $(srcdir)/python/py-symbol.c
|
||||||
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symbol.c
|
||||||
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
|
py-symtab.o: $(srcdir)/python/py-symtab.c
|
||||||
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symtab.c
|
||||||
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
py-type.o: $(srcdir)/python/py-type.c
|
py-type.o: $(srcdir)/python/py-type.c
|
||||||
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-type.c
|
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-type.c
|
||||||
$(POSTCOMPILE)
|
$(POSTCOMPILE)
|
||||||
|
|||||||
5
gdb/NEWS
5
gdb/NEWS
@@ -3,6 +3,11 @@
|
|||||||
|
|
||||||
*** Changes since GDB 7.1
|
*** Changes since GDB 7.1
|
||||||
|
|
||||||
|
* Python scripting
|
||||||
|
|
||||||
|
The GDB Python API now has access to symbols, symbol tables, and
|
||||||
|
frame's code blocks.
|
||||||
|
|
||||||
*** Changes in GDB 7.1
|
*** Changes in GDB 7.1
|
||||||
|
|
||||||
* C++ Improvements
|
* C++ Improvements
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
2010-02-24 Phil Muldoon <pmuldoon@redhat.com>
|
||||||
|
|
||||||
|
* gdb.texinfo (Frames In Python): Add block, find_sal, function
|
||||||
|
and select method descriptions.
|
||||||
|
(Python API): Add Blocks In Python, Symbols in Python and Symbol
|
||||||
|
Tables in Python to menu.
|
||||||
|
(Blocks In Python): New node.
|
||||||
|
(Symbols In Python): New node.
|
||||||
|
(Symbol Tables in Python): New node.
|
||||||
|
|
||||||
2010-02-24 Vladimir Prus <vladimir@codesourcery.com>
|
2010-02-24 Vladimir Prus <vladimir@codesourcery.com>
|
||||||
|
|
||||||
Multiexec MI
|
Multiexec MI
|
||||||
|
|||||||
@@ -19547,7 +19547,10 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
|
|||||||
* Commands In Python:: Implementing new commands in Python.
|
* Commands In Python:: Implementing new commands in Python.
|
||||||
* Functions In Python:: Writing new convenience functions.
|
* Functions In Python:: Writing new convenience functions.
|
||||||
* Objfiles In Python:: Object files.
|
* Objfiles In Python:: Object files.
|
||||||
* Frames In Python:: Acessing inferior stack frames from Python.
|
* Frames In Python:: Accessing inferior stack frames from Python.
|
||||||
|
* Blocks In Python:: Accessing frame blocks from Python.
|
||||||
|
* Symbols In Python:: Python representation of symbols.
|
||||||
|
* Symbol Tables In Python:: Python representation of symbol tables.
|
||||||
* Lazy Strings In Python:: Python representation of lazy strings.
|
* Lazy Strings In Python:: Python representation of lazy strings.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@@ -20707,7 +20710,7 @@ information.
|
|||||||
@end defivar
|
@end defivar
|
||||||
|
|
||||||
@node Frames In Python
|
@node Frames In Python
|
||||||
@subsubsection Acessing inferior stack frames from Python.
|
@subsubsection Accessing inferior stack frames from Python.
|
||||||
|
|
||||||
@cindex frames in python
|
@cindex frames in python
|
||||||
When the debugged program stops, @value{GDBN} is able to analyze its call
|
When the debugged program stops, @value{GDBN} is able to analyze its call
|
||||||
@@ -20770,6 +20773,15 @@ function to a string.
|
|||||||
Returns the frame's resume address.
|
Returns the frame's resume address.
|
||||||
@end defmethod
|
@end defmethod
|
||||||
|
|
||||||
|
@defmethod Frame block
|
||||||
|
Return the frame's code block. @xref{Blocks In Python}.
|
||||||
|
@end defmethod
|
||||||
|
|
||||||
|
@defmethod Frame function
|
||||||
|
Return the symbol for the function corresponding to this frame.
|
||||||
|
@xref{Symbols In Python}.
|
||||||
|
@end defmethod
|
||||||
|
|
||||||
@defmethod Frame older
|
@defmethod Frame older
|
||||||
Return the frame that called this frame.
|
Return the frame that called this frame.
|
||||||
@end defmethod
|
@end defmethod
|
||||||
@@ -20778,10 +20790,308 @@ Return the frame that called this frame.
|
|||||||
Return the frame called by this frame.
|
Return the frame called by this frame.
|
||||||
@end defmethod
|
@end defmethod
|
||||||
|
|
||||||
|
@defmethod Frame find_sal
|
||||||
|
Return the frame's symtab and line object.
|
||||||
|
@xref{Symbol Tables In Python}.
|
||||||
|
@end defmethod
|
||||||
|
|
||||||
@defmethod Frame read_var variable
|
@defmethod Frame read_var variable
|
||||||
Return the value of the given variable in this frame. @var{variable} must
|
Return the value of the given variable in this frame. @var{variable} must
|
||||||
be a string.
|
be a string.
|
||||||
@end defmethod
|
@end defmethod
|
||||||
|
|
||||||
|
@defmethod Frame select
|
||||||
|
Set this frame to be the selected frame. @xref{Stack, ,Examining the
|
||||||
|
Stack}.
|
||||||
|
@end defmethod
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@node Blocks In Python
|
||||||
|
@subsubsection Accessing frame blocks from Python.
|
||||||
|
|
||||||
|
@cindex blocks in python
|
||||||
|
@tindex gdb.Block
|
||||||
|
|
||||||
|
Within each frame, @value{GDBN} maintains information on each block
|
||||||
|
stored in that frame. These blocks are organized hierarchically, and
|
||||||
|
are represented individually in Python as a @code{gdb.Block}.
|
||||||
|
Please see @ref{Frames In Python}, for a more in-depth discussion on
|
||||||
|
frames. Furthermore, see @ref{Stack, ,Examining the Stack}, for more
|
||||||
|
detailed technical information on @value{GDBN}'s book-keeping of the
|
||||||
|
stack.
|
||||||
|
|
||||||
|
The following block-related functions are available in the @code{gdb}
|
||||||
|
module:
|
||||||
|
|
||||||
|
@findex gdb.block_for_pc
|
||||||
|
@defun block_for_pc pc
|
||||||
|
Return the @code{gdb.Block} containing the given @var{pc} value. If the
|
||||||
|
block cannot be found for the @var{pc} value specified, the function
|
||||||
|
will return @code{None}.
|
||||||
|
@end defun
|
||||||
|
|
||||||
|
A @code{gdb.Block} object has the following attributes:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@defivar Block start
|
||||||
|
The start address of the block. This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Block end
|
||||||
|
The end address of the block. This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Block function
|
||||||
|
The name of the block represented as a @code{gdb.Symbol}. If the
|
||||||
|
block is not named, then this attribute holds @code{None}. This
|
||||||
|
attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Block superblock
|
||||||
|
The block containing this block. If this parent block does not exist,
|
||||||
|
this attribute holds @code{None}. This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@node Symbols In Python
|
||||||
|
@subsubsection Python representation of Symbols.
|
||||||
|
|
||||||
|
@cindex symbols in python
|
||||||
|
@tindex gdb.Symbol
|
||||||
|
|
||||||
|
@value{GDBN} represents every variable, function and type as an
|
||||||
|
entry in a symbol table. @xref{Symbols, ,Examining the Symbol Table}.
|
||||||
|
Similarly, Python represents these symbols in @value{GDBN} with the
|
||||||
|
@code{gdb.Symbol} object.
|
||||||
|
|
||||||
|
The following symbol-related functions are available in the @code{gdb}
|
||||||
|
module:
|
||||||
|
|
||||||
|
@findex gdb.lookup_symbol
|
||||||
|
@defun lookup_symbol name [block] [domain]
|
||||||
|
This function searches for a symbol by name. The search scope can be
|
||||||
|
restricted to the parameters defined in the optional domain and block
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
@var{name} is the name of the symbol. It must be a string. The
|
||||||
|
optional @var{block} argument restricts the search to symbols visible
|
||||||
|
in that @var{block}. The @var{block} argument must be a
|
||||||
|
@code{gdb.Block} object. The optional @var{domain} argument restricts
|
||||||
|
the search to the domain type. The @var{domain} argument must be a
|
||||||
|
domain constant defined in the @code{gdb} module and described later
|
||||||
|
in this chapter.
|
||||||
|
@end defun
|
||||||
|
|
||||||
|
A @code{gdb.Symbol} object has the following attributes:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@defivar Symbol symtab
|
||||||
|
The symbol table in which the symbol appears. This attribute is
|
||||||
|
represented as a @code{gdb.Symtab} object. @xref{Symbol Tables In
|
||||||
|
Python}. This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symbol name
|
||||||
|
The name of the symbol as a string. This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symbol linkage_name
|
||||||
|
The name of the symbol, as used by the linker (i.e., may be mangled).
|
||||||
|
This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symbol print_name
|
||||||
|
The name of the symbol in a form suitable for output. This is either
|
||||||
|
@code{name} or @code{linkage_name}, depending on whether the user
|
||||||
|
asked @value{GDBN} to display demangled or mangled names.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symbol addr_class
|
||||||
|
The address class of the symbol. This classifies how to find the value
|
||||||
|
of a symbol. Each address class is a constant defined in the
|
||||||
|
@code{gdb} module and described later in this chapter.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symbol is_argument
|
||||||
|
@code{True} if the symbol is an argument of a function.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symbol is_constant
|
||||||
|
@code{True} if the symbol is a constant.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symbol is_function
|
||||||
|
@code{True} if the symbol is a function or a method.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symbol is_variable
|
||||||
|
@code{True} if the symbol is a variable.
|
||||||
|
@end defivar
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The available domain categories in @code{gdb.Symbol} are represented
|
||||||
|
as constants in the @code{gdb} module:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@findex SYMBOL_UNDEF_DOMAIN
|
||||||
|
@findex gdb.SYMBOL_UNDEF_DOMAIN
|
||||||
|
@item SYMBOL_UNDEF_DOMAIN
|
||||||
|
This is used when a domain has not been discovered or none of the
|
||||||
|
following domains apply. This usually indicates an error either
|
||||||
|
in the symbol information or in @value{GDBN}'s handling of symbols.
|
||||||
|
@findex SYMBOL_VAR_DOMAIN
|
||||||
|
@findex gdb.SYMBOL_VAR_DOMAIN
|
||||||
|
@item SYMBOL_VAR_DOMAIN
|
||||||
|
This domain contains variables, function names, typedef names and enum
|
||||||
|
type values.
|
||||||
|
@findex SYMBOL_STRUCT_DOMAIN
|
||||||
|
@findex gdb.SYMBOL_STRUCT_DOMAIN
|
||||||
|
@item SYMBOL_STRUCT_DOMAIN
|
||||||
|
This domain holds struct, union and enum type names.
|
||||||
|
@findex SYMBOL_LABEL_DOMAIN
|
||||||
|
@findex gdb.SYMBOL_LABEL_DOMAIN
|
||||||
|
@item SYMBOL_LABEL_DOMAIN
|
||||||
|
This domain contains names of labels (for gotos).
|
||||||
|
@findex SYMBOL_VARIABLES_DOMAIN
|
||||||
|
@findex gdb.SYMBOL_VARIABLES_DOMAIN
|
||||||
|
@item SYMBOL_VARIABLES_DOMAIN
|
||||||
|
This domain holds a subset of the @code{SYMBOLS_VAR_DOMAIN}; it
|
||||||
|
contains everything minus functions and types.
|
||||||
|
@findex SYMBOL_FUNCTIONS_DOMAIN
|
||||||
|
@findex gdb.SYMBOL_FUNCTIONS_DOMAIN
|
||||||
|
@item SYMBOL_FUNCTION_DOMAIN
|
||||||
|
This domain contains all functions.
|
||||||
|
@findex SYMBOL_TYPES_DOMAIN
|
||||||
|
@findex gdb.SYMBOL_TYPES_DOMAIN
|
||||||
|
@item SYMBOL_TYPES_DOMAIN
|
||||||
|
This domain contains all types.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The available address class categories in @code{gdb.Symbol} are represented
|
||||||
|
as constants in the @code{gdb} module:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@findex SYMBOL_LOC_UNDEF
|
||||||
|
@findex gdb.SYMBOL_LOC_UNDEF
|
||||||
|
@item SYMBOL_LOC_UNDEF
|
||||||
|
If this is returned by address class, it indicates an error either in
|
||||||
|
the symbol information or in @value{GDBN}'s handling of symbols.
|
||||||
|
@findex SYMBOL_LOC_CONST
|
||||||
|
@findex gdb.SYMBOL_LOC_CONST
|
||||||
|
@item SYMBOL_LOC_CONST
|
||||||
|
Value is constant int.
|
||||||
|
@findex SYMBOL_LOC_STATIC
|
||||||
|
@findex gdb.SYMBOL_LOC_STATIC
|
||||||
|
@item SYMBOL_LOC_STATIC
|
||||||
|
Value is at a fixed address.
|
||||||
|
@findex SYMBOL_LOC_REGISTER
|
||||||
|
@findex gdb.SYMBOL_LOC_REGISTER
|
||||||
|
@item SYMBOL_LOC_REGISTER
|
||||||
|
Value is in a register.
|
||||||
|
@findex SYMBOL_LOC_ARG
|
||||||
|
@findex gdb.SYMBOL_LOC_ARG
|
||||||
|
@item SYMBOL_LOC_ARG
|
||||||
|
Value is an argument. This value is at the offset stored within the
|
||||||
|
symbol inside the frame's argument list.
|
||||||
|
@findex SYMBOL_LOC_REF_ARG
|
||||||
|
@findex gdb.SYMBOL_LOC_REF_ARG
|
||||||
|
@item SYMBOL_LOC_REF_ARG
|
||||||
|
Value address is stored in the frame's argument list. Just like
|
||||||
|
@code{LOC_ARG} except that the value's address is stored at the
|
||||||
|
offset, not the value itself.
|
||||||
|
@findex SYMBOL_LOC_REGPARM_ADDR
|
||||||
|
@findex gdb.SYMBOL_LOC_REGPARM_ADDR
|
||||||
|
@item SYMBOL_LOC_REGPARM_ADDR
|
||||||
|
Value is a specified register. Just like @code{LOC_REGISTER} except
|
||||||
|
the register holds the address of the argument instead of the argument
|
||||||
|
itself.
|
||||||
|
@findex SYMBOL_LOC_LOCAL
|
||||||
|
@findex gdb.SYMBOL_LOC_LOCAL
|
||||||
|
@item SYMBOL_LOC_LOCAL
|
||||||
|
Value is a local variable.
|
||||||
|
@findex SYMBOL_LOC_TYPEDEF
|
||||||
|
@findex gdb.SYMBOL_LOC_TYPEDEF
|
||||||
|
@item SYMBOL_LOC_TYPEDEF
|
||||||
|
Value not used. Symbols in the domain @code{SYMBOL_STRUCT_DOMAIN} all
|
||||||
|
have this class.
|
||||||
|
@findex SYMBOL_LOC_BLOCK
|
||||||
|
@findex gdb.SYMBOL_LOC_BLOCK
|
||||||
|
@item SYMBOL_LOC_BLOCK
|
||||||
|
Value is a block.
|
||||||
|
@findex SYMBOL_LOC_CONST_BYTES
|
||||||
|
@findex gdb.SYMBOL_LOC_CONST_BYTES
|
||||||
|
@item SYMBOL_LOC_CONST_BYTES
|
||||||
|
Value is a byte-sequence.
|
||||||
|
@findex SYMBOL_LOC_UNRESOLVED
|
||||||
|
@findex gdb.SYMBOL_LOC_UNRESOLVED
|
||||||
|
@item SYMBOL_LOC_UNRESOLVED
|
||||||
|
Value is at a fixed address, but the address of the variable has to be
|
||||||
|
determined from the minimal symbol table whenever the variable is
|
||||||
|
referenced.
|
||||||
|
@findex SYMBOL_LOC_OPTIMIZED_OUT
|
||||||
|
@findex gdb.SYMBOL_LOC_OPTIMIZED_OUT
|
||||||
|
@item SYMBOL_LOC_OPTIMIZED_OUT
|
||||||
|
The value does not actually exist in the program.
|
||||||
|
@findex SYMBOL_LOC_COMPUTED
|
||||||
|
@findex gdb.SYMBOL_LOC_COMPUTED
|
||||||
|
@item SYMBOL_LOC_COMPUTED
|
||||||
|
The value's address is a computed location.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@node Symbol Tables In Python
|
||||||
|
@subsubsection Symbol table representation in Python.
|
||||||
|
|
||||||
|
@cindex symbol tables in python
|
||||||
|
@tindex gdb.Symtab
|
||||||
|
@tindex gdb.Symtab_and_line
|
||||||
|
|
||||||
|
Access to symbol table data maintained by @value{GDBN} on the inferior
|
||||||
|
is exposed to Python via two objects: @code{gdb.Symtab_and_line} and
|
||||||
|
@code{gdb.Symtab}. Symbol table and line data for a frame is returned
|
||||||
|
from the @code{find_sal} method in @code{gdb.Frame} object.
|
||||||
|
@xref{Frames In Python}.
|
||||||
|
|
||||||
|
For more information on @value{GDBN}'s symbol table management, see
|
||||||
|
@ref{Symbols, ,Examining the Symbol Table}, for more information.
|
||||||
|
|
||||||
|
A @code{gdb.Symtab_and_line} object has the following attributes:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@defivar Symtab_and_line symtab
|
||||||
|
The symbol table object (@code{gdb.Symtab}) for this frame.
|
||||||
|
This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symtab_and_line pc
|
||||||
|
Indicates the current program counter address. This attribute is not
|
||||||
|
writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symtab_and_line line
|
||||||
|
Indicates the current line number for this object. This
|
||||||
|
attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
@end table
|
||||||
|
|
||||||
|
A @code{gdb.Symtab} object has the following attributes:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@defivar Symtab filename
|
||||||
|
The symbol table's source filename. This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
|
||||||
|
@defivar Symtab objfile
|
||||||
|
The symbol table's backing object file. @xref{Objfiles In Python}.
|
||||||
|
This attribute is not writable.
|
||||||
|
@end defivar
|
||||||
|
@end table
|
||||||
|
|
||||||
|
The following methods are provided:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@defmethod Symtab fullname
|
||||||
|
Return the symbol table's source absolute file name.
|
||||||
|
@end defmethod
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@node Lazy Strings In Python
|
@node Lazy Strings In Python
|
||||||
|
|||||||
418
gdb/python/py-block.c
Normal file
418
gdb/python/py-block.c
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
/* Python interface to blocks.
|
||||||
|
|
||||||
|
Copyright (C) 2008, 2009, 2010 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/>. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "block.h"
|
||||||
|
#include "dictionary.h"
|
||||||
|
#include "symtab.h"
|
||||||
|
#include "python-internal.h"
|
||||||
|
#include "objfiles.h"
|
||||||
|
#include "symtab.h"
|
||||||
|
|
||||||
|
typedef struct blpy_block_object {
|
||||||
|
PyObject_HEAD
|
||||||
|
/* The GDB block structure that represents a frame's code block. */
|
||||||
|
struct block *block;
|
||||||
|
/* The backing object file. There is no direct relationship in GDB
|
||||||
|
between a block and an object file. When a block is created also
|
||||||
|
store a pointer to the object file for later use. */
|
||||||
|
struct objfile *objfile;
|
||||||
|
/* Keep track of all blocks with a doubly-linked list. Needed for
|
||||||
|
block invalidation if the source object file has been freed. */
|
||||||
|
struct blpy_block_object *prev;
|
||||||
|
struct blpy_block_object *next;
|
||||||
|
} block_object;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
/* The block dictionary of symbols. */
|
||||||
|
struct dictionary *dict;
|
||||||
|
/* The iterator for that dictionary. */
|
||||||
|
struct dict_iterator iter;
|
||||||
|
/* Has the iterator been initialized flag. */
|
||||||
|
int initialized_p;
|
||||||
|
/* Pointer back to the original source block object. Needed to
|
||||||
|
check if the block is still valid, and has not been invalidated
|
||||||
|
when an object file has been freed. */
|
||||||
|
struct blpy_block_object *source;
|
||||||
|
} block_syms_iterator_object;
|
||||||
|
|
||||||
|
/* Require a valid block. All access to block_object->block should be
|
||||||
|
gated by this call. */
|
||||||
|
#define BLPY_REQUIRE_VALID(block_obj, block) \
|
||||||
|
do { \
|
||||||
|
block = block_object_to_block (block_obj); \
|
||||||
|
if (block == NULL) \
|
||||||
|
{ \
|
||||||
|
PyErr_SetString (PyExc_RuntimeError, \
|
||||||
|
_("Block is invalid.")); \
|
||||||
|
return NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Require a valid block. This macro is called during block iterator
|
||||||
|
creation, and at each next call. */
|
||||||
|
#define BLPY_ITER_REQUIRE_VALID(block_obj) \
|
||||||
|
do { \
|
||||||
|
if (block_obj->block == NULL) \
|
||||||
|
{ \
|
||||||
|
PyErr_SetString (PyExc_RuntimeError, \
|
||||||
|
_("Source block for iterator is invalid.")); \
|
||||||
|
return NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static PyTypeObject block_syms_iterator_object_type;
|
||||||
|
static const struct objfile_data *blpy_objfile_data_key;
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
blpy_iter (PyObject *self)
|
||||||
|
{
|
||||||
|
block_syms_iterator_object *block_iter_obj;
|
||||||
|
struct block *block = NULL;
|
||||||
|
|
||||||
|
BLPY_REQUIRE_VALID (self, block);
|
||||||
|
|
||||||
|
block_iter_obj = PyObject_New (block_syms_iterator_object,
|
||||||
|
&block_syms_iterator_object_type);
|
||||||
|
if (block_iter_obj == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
block_iter_obj->dict = BLOCK_DICT (block);
|
||||||
|
block_iter_obj->initialized_p = 0;
|
||||||
|
Py_INCREF (self);
|
||||||
|
block_iter_obj->source = (block_object *) self;
|
||||||
|
|
||||||
|
return (PyObject *) block_iter_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
blpy_get_start (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct block *block = NULL;
|
||||||
|
|
||||||
|
BLPY_REQUIRE_VALID (self, block);
|
||||||
|
|
||||||
|
return PyLong_FromUnsignedLongLong (BLOCK_START (block));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
blpy_get_end (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct block *block = NULL;
|
||||||
|
|
||||||
|
BLPY_REQUIRE_VALID (self, block);
|
||||||
|
|
||||||
|
return PyLong_FromUnsignedLongLong (BLOCK_END (block));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
blpy_get_function (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *sym;
|
||||||
|
struct block *block = NULL;
|
||||||
|
|
||||||
|
BLPY_REQUIRE_VALID (self, block);
|
||||||
|
|
||||||
|
sym = BLOCK_FUNCTION (block);
|
||||||
|
if (sym)
|
||||||
|
return symbol_to_symbol_object (sym);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
blpy_get_superblock (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct block *block = NULL;
|
||||||
|
struct block *super_block = NULL;
|
||||||
|
block_object *self_obj = (block_object *) self;
|
||||||
|
|
||||||
|
BLPY_REQUIRE_VALID (self, block);
|
||||||
|
|
||||||
|
super_block = BLOCK_SUPERBLOCK (block);
|
||||||
|
if (super_block)
|
||||||
|
return block_to_block_object (super_block, self_obj->objfile);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
blpy_dealloc (PyObject *obj)
|
||||||
|
{
|
||||||
|
block_object *block = (block_object *) obj;
|
||||||
|
|
||||||
|
if (block->prev)
|
||||||
|
block->prev->next = block->next;
|
||||||
|
else if (block->objfile)
|
||||||
|
{
|
||||||
|
set_objfile_data (block->objfile, blpy_objfile_data_key,
|
||||||
|
block->next);
|
||||||
|
}
|
||||||
|
if (block->next)
|
||||||
|
block->next->prev = block->prev;
|
||||||
|
block->block = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a block, and a block_object that has previously been
|
||||||
|
allocated and initialized, populate the block_object with the
|
||||||
|
struct block data. Also, register the block_object life-cycle
|
||||||
|
with the life-cycle of the the object file associated with this
|
||||||
|
block, if needed. */
|
||||||
|
static void
|
||||||
|
set_block (block_object *obj, struct block *block,
|
||||||
|
struct objfile *objfile)
|
||||||
|
{
|
||||||
|
obj->block = block;
|
||||||
|
obj->prev = NULL;
|
||||||
|
if (objfile)
|
||||||
|
{
|
||||||
|
obj->objfile = objfile;
|
||||||
|
obj->next = objfile_data (objfile, blpy_objfile_data_key);
|
||||||
|
if (obj->next)
|
||||||
|
obj->next->prev = obj;
|
||||||
|
set_objfile_data (objfile, blpy_objfile_data_key, obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
obj->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new block object (gdb.Block) that encapsulates the struct
|
||||||
|
block object from GDB. */
|
||||||
|
PyObject *
|
||||||
|
block_to_block_object (struct block *block, struct objfile *objfile)
|
||||||
|
{
|
||||||
|
block_object *block_obj;
|
||||||
|
|
||||||
|
block_obj = PyObject_New (block_object, &block_object_type);
|
||||||
|
if (block_obj)
|
||||||
|
set_block (block_obj, block, objfile);
|
||||||
|
|
||||||
|
return (PyObject *) block_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return struct block reference that is wrapped by this object. */
|
||||||
|
struct block *
|
||||||
|
block_object_to_block (PyObject *obj)
|
||||||
|
{
|
||||||
|
if (! PyObject_TypeCheck (obj, &block_object_type))
|
||||||
|
return NULL;
|
||||||
|
return ((block_object *) obj)->block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a reference to the block iterator. */
|
||||||
|
static PyObject *
|
||||||
|
blpy_block_syms_iter (PyObject *self)
|
||||||
|
{
|
||||||
|
block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
|
||||||
|
|
||||||
|
BLPY_ITER_REQUIRE_VALID (iter_obj->source);
|
||||||
|
|
||||||
|
Py_INCREF (self);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the next symbol in the iteration through the block's
|
||||||
|
dictionary. */
|
||||||
|
static PyObject *
|
||||||
|
blpy_block_syms_iternext (PyObject *self)
|
||||||
|
{
|
||||||
|
block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
|
||||||
|
struct symbol *sym;
|
||||||
|
|
||||||
|
BLPY_ITER_REQUIRE_VALID (iter_obj->source);
|
||||||
|
|
||||||
|
if (!iter_obj->initialized_p)
|
||||||
|
{
|
||||||
|
sym = dict_iterator_first (iter_obj->dict, &(iter_obj->iter));
|
||||||
|
iter_obj->initialized_p = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sym = dict_iterator_next (&(iter_obj->iter));
|
||||||
|
|
||||||
|
if (sym == NULL)
|
||||||
|
{
|
||||||
|
PyErr_SetString (PyExc_StopIteration, "Symbol is null.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbol_to_symbol_object (sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
blpy_block_syms_dealloc (PyObject *obj)
|
||||||
|
{
|
||||||
|
block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
|
||||||
|
Py_XDECREF (iter_obj->source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the innermost lexical block containing the specified pc value,
|
||||||
|
or 0 if there is none. */
|
||||||
|
PyObject *
|
||||||
|
gdbpy_block_for_pc (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
unsigned PY_LONG_LONG pc;
|
||||||
|
struct block *block;
|
||||||
|
struct obj_section *section;
|
||||||
|
struct symtab *symtab;
|
||||||
|
PyObject *sym_obj;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple (args, "K", &pc))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
section = find_pc_mapped_section (pc);
|
||||||
|
symtab = find_pc_sect_symtab (pc, section);
|
||||||
|
if (!symtab || symtab->objfile == NULL)
|
||||||
|
{
|
||||||
|
PyErr_SetString (PyExc_RuntimeError,
|
||||||
|
"Cannot locate object file for block.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
block = block_for_pc (pc);
|
||||||
|
if (block)
|
||||||
|
return block_to_block_object (block, symtab->objfile);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is called when an objfile is about to be freed.
|
||||||
|
Invalidate the block as further actions on the block would result
|
||||||
|
in bad data. All access to obj->symbol should be gated by
|
||||||
|
BLPY_REQUIRE_VALID which will raise an exception on invalid
|
||||||
|
blocks. */
|
||||||
|
static void
|
||||||
|
del_objfile_blocks (struct objfile *objfile, void *datum)
|
||||||
|
{
|
||||||
|
block_object *obj = datum;
|
||||||
|
while (obj)
|
||||||
|
{
|
||||||
|
block_object *next = obj->next;
|
||||||
|
|
||||||
|
obj->block = NULL;
|
||||||
|
obj->objfile = NULL;
|
||||||
|
obj->next = NULL;
|
||||||
|
obj->prev = NULL;
|
||||||
|
|
||||||
|
obj = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdbpy_initialize_blocks (void)
|
||||||
|
{
|
||||||
|
block_object_type.tp_new = PyType_GenericNew;
|
||||||
|
if (PyType_Ready (&block_object_type) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
block_syms_iterator_object_type.tp_new = PyType_GenericNew;
|
||||||
|
if (PyType_Ready (&block_syms_iterator_object_type) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Register an objfile "free" callback so we can properly
|
||||||
|
invalidate blocks when an object file is about to be
|
||||||
|
deleted. */
|
||||||
|
blpy_objfile_data_key
|
||||||
|
= register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
|
||||||
|
|
||||||
|
Py_INCREF (&block_object_type);
|
||||||
|
PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type);
|
||||||
|
|
||||||
|
Py_INCREF (&block_syms_iterator_object_type);
|
||||||
|
PyModule_AddObject (gdb_module, "BlockIterator",
|
||||||
|
(PyObject *) &block_syms_iterator_object_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static PyGetSetDef block_object_getset[] = {
|
||||||
|
{ "start", blpy_get_start, NULL, "Start address of the block.", NULL },
|
||||||
|
{ "end", blpy_get_end, NULL, "End address of the block.", NULL },
|
||||||
|
{ "function", blpy_get_function, NULL,
|
||||||
|
"Symbol that names the block, or None.", NULL },
|
||||||
|
{ "superblock", blpy_get_superblock, NULL,
|
||||||
|
"Block containing the block, or None.", NULL },
|
||||||
|
{ NULL } /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
PyTypeObject block_object_type = {
|
||||||
|
PyObject_HEAD_INIT (NULL)
|
||||||
|
0, /*ob_size*/
|
||||||
|
"gdb.Block", /*tp_name*/
|
||||||
|
sizeof (block_object), /*tp_basicsize*/
|
||||||
|
0, /*tp_itemsize*/
|
||||||
|
blpy_dealloc, /*tp_dealloc*/
|
||||||
|
0, /*tp_print*/
|
||||||
|
0, /*tp_getattr*/
|
||||||
|
0, /*tp_setattr*/
|
||||||
|
0, /*tp_compare*/
|
||||||
|
0, /*tp_repr*/
|
||||||
|
0, /*tp_as_number*/
|
||||||
|
0, /*tp_as_sequence*/
|
||||||
|
0, /*tp_as_mapping*/
|
||||||
|
0, /*tp_hash */
|
||||||
|
0, /*tp_call*/
|
||||||
|
0, /*tp_str*/
|
||||||
|
0, /*tp_getattro*/
|
||||||
|
0, /*tp_setattro*/
|
||||||
|
0, /*tp_as_buffer*/
|
||||||
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
|
||||||
|
"GDB block object", /* tp_doc */
|
||||||
|
0, /* tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
blpy_iter, /* tp_iter */
|
||||||
|
0, /* tp_iternext */
|
||||||
|
0, /* tp_methods */
|
||||||
|
0, /* tp_members */
|
||||||
|
block_object_getset /* tp_getset */
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyTypeObject block_syms_iterator_object_type = {
|
||||||
|
PyObject_HEAD_INIT (NULL)
|
||||||
|
0, /*ob_size*/
|
||||||
|
"gdb.BlockIterator", /*tp_name*/
|
||||||
|
sizeof (block_syms_iterator_object), /*tp_basicsize*/
|
||||||
|
0, /*tp_itemsize*/
|
||||||
|
blpy_block_syms_dealloc, /*tp_dealloc*/
|
||||||
|
0, /*tp_print*/
|
||||||
|
0, /*tp_getattr*/
|
||||||
|
0, /*tp_setattr*/
|
||||||
|
0, /*tp_compare*/
|
||||||
|
0, /*tp_repr*/
|
||||||
|
0, /*tp_as_number*/
|
||||||
|
0, /*tp_as_sequence*/
|
||||||
|
0, /*tp_as_mapping*/
|
||||||
|
0, /*tp_hash */
|
||||||
|
0, /*tp_call*/
|
||||||
|
0, /*tp_str*/
|
||||||
|
0, /*tp_getattro*/
|
||||||
|
0, /*tp_setattro*/
|
||||||
|
0, /*tp_as_buffer*/
|
||||||
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
|
||||||
|
"GDB block syms iterator object", /*tp_doc */
|
||||||
|
0, /*tp_traverse */
|
||||||
|
0, /*tp_clear */
|
||||||
|
0, /*tp_richcompare */
|
||||||
|
0, /*tp_weaklistoffset */
|
||||||
|
blpy_block_syms_iter, /*tp_iter */
|
||||||
|
blpy_block_syms_iternext, /*tp_iternext */
|
||||||
|
0 /*tp_methods */
|
||||||
|
};
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "python-internal.h"
|
#include "python-internal.h"
|
||||||
|
#include "symfile.h"
|
||||||
|
#include "objfiles.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
@@ -202,6 +204,64 @@ frapy_pc (PyObject *self, PyObject *args)
|
|||||||
return PyLong_FromUnsignedLongLong (pc);
|
return PyLong_FromUnsignedLongLong (pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Implementation of gdb.Frame.block (self) -> gdb.Block.
|
||||||
|
Returns the frame's code block. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frapy_block (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
struct frame_info *frame;
|
||||||
|
struct block *block = NULL;
|
||||||
|
volatile struct gdb_exception except;
|
||||||
|
struct symtab_and_line sal;
|
||||||
|
|
||||||
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
|
||||||
|
|
||||||
|
find_frame_sal (frame, &sal);
|
||||||
|
block = block_for_pc (get_frame_address_in_block (frame));
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
if (!sal.symtab || !sal.symtab->objfile)
|
||||||
|
{
|
||||||
|
PyErr_SetString (PyExc_RuntimeError,
|
||||||
|
"Cannot locate object file for block.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block)
|
||||||
|
return block_to_block_object (block, sal.symtab->objfile);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Implementation of gdb.Frame.function (self) -> gdb.Symbol.
|
||||||
|
Returns the symbol for the function corresponding to this frame. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frapy_function (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
struct symbol *sym = NULL;
|
||||||
|
struct frame_info *frame;
|
||||||
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
|
||||||
|
|
||||||
|
sym = find_pc_function (get_frame_address_in_block (frame));
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
if (sym)
|
||||||
|
return symbol_to_symbol_object (sym);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert a frame_info struct to a Python Frame object.
|
/* Convert a frame_info struct to a Python Frame object.
|
||||||
Sets a Python exception and returns NULL on error. */
|
Sets a Python exception and returns NULL on error. */
|
||||||
|
|
||||||
@@ -296,6 +356,30 @@ frapy_newer (PyObject *self, PyObject *args)
|
|||||||
return next_obj;
|
return next_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line.
|
||||||
|
Returns the frame's symtab and line. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frapy_find_sal (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
struct frame_info *frame;
|
||||||
|
struct symtab_and_line sal;
|
||||||
|
struct objfile *objfile = NULL;
|
||||||
|
volatile struct gdb_exception except;
|
||||||
|
PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */
|
||||||
|
|
||||||
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
|
||||||
|
|
||||||
|
find_frame_sal (frame, &sal);
|
||||||
|
sal_obj = symtab_and_line_to_sal_object (sal);
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
return sal_obj;
|
||||||
|
}
|
||||||
|
|
||||||
/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value.
|
/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value.
|
||||||
Returns the value of the given variable in this frame. The argument must be
|
Returns the value of the given variable in this frame. The argument must be
|
||||||
a string. Returns None if GDB can't find the specified variable. */
|
a string. Returns None if GDB can't find the specified variable. */
|
||||||
@@ -312,7 +396,9 @@ frapy_read_var (PyObject *self, PyObject *args)
|
|||||||
if (!PyArg_ParseTuple (args, "O", &sym_obj))
|
if (!PyArg_ParseTuple (args, "O", &sym_obj))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (gdbpy_is_string (sym_obj))
|
if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
|
||||||
|
var = symbol_object_to_symbol (sym_obj);
|
||||||
|
else if (gdbpy_is_string (sym_obj))
|
||||||
{
|
{
|
||||||
char *var_name;
|
char *var_name;
|
||||||
struct block *block = NULL;
|
struct block *block = NULL;
|
||||||
@@ -365,6 +451,26 @@ frapy_read_var (PyObject *self, PyObject *args)
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Select this frame. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frapy_select (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
struct frame_info *fi;
|
||||||
|
frame_object *frame = (frame_object *) self;
|
||||||
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
FRAPY_REQUIRE_VALID (frame, fi);
|
||||||
|
|
||||||
|
select_frame (fi);
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Implementation of gdb.selected_frame () -> gdb.Frame.
|
/* Implementation of gdb.selected_frame () -> gdb.Frame.
|
||||||
Returns the selected frame object. */
|
Returns the selected frame object. */
|
||||||
|
|
||||||
@@ -484,15 +590,26 @@ Return the reason why it's not possible to find frames older than this." },
|
|||||||
{ "pc", frapy_pc, METH_NOARGS,
|
{ "pc", frapy_pc, METH_NOARGS,
|
||||||
"pc () -> Long.\n\
|
"pc () -> Long.\n\
|
||||||
Return the frame's resume address." },
|
Return the frame's resume address." },
|
||||||
|
{ "block", frapy_block, METH_NOARGS,
|
||||||
|
"block () -> gdb.Block.\n\
|
||||||
|
Return the frame's code block." },
|
||||||
|
{ "function", frapy_function, METH_NOARGS,
|
||||||
|
"function () -> gdb.Symbol.\n\
|
||||||
|
Returns the symbol for the function corresponding to this frame." },
|
||||||
{ "older", frapy_older, METH_NOARGS,
|
{ "older", frapy_older, METH_NOARGS,
|
||||||
"older () -> gdb.Frame.\n\
|
"older () -> gdb.Frame.\n\
|
||||||
Return the frame that called this frame." },
|
Return the frame that called this frame." },
|
||||||
{ "newer", frapy_newer, METH_NOARGS,
|
{ "newer", frapy_newer, METH_NOARGS,
|
||||||
"newer () -> gdb.Frame.\n\
|
"newer () -> gdb.Frame.\n\
|
||||||
Return the frame called by this frame." },
|
Return the frame called by this frame." },
|
||||||
|
{ "find_sal", frapy_find_sal, METH_NOARGS,
|
||||||
|
"find_sal () -> gdb.Symtab_and_line.\n\
|
||||||
|
Return the frame's symtab and line." },
|
||||||
{ "read_var", frapy_read_var, METH_VARARGS,
|
{ "read_var", frapy_read_var, METH_VARARGS,
|
||||||
"read_var (variable) -> gdb.Value.\n\
|
"read_var (variable) -> gdb.Value.\n\
|
||||||
Return the value of the variable in this frame." },
|
Return the value of the variable in this frame." },
|
||||||
|
{ "select", frapy_select, METH_NOARGS,
|
||||||
|
"Select this frame as the user's current frame." },
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
419
gdb/python/py-symbol.c
Normal file
419
gdb/python/py-symbol.c
Normal file
@@ -0,0 +1,419 @@
|
|||||||
|
/* Python interface to symbols.
|
||||||
|
|
||||||
|
Copyright (C) 2008, 2009, 2010 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/>. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "block.h"
|
||||||
|
#include "exceptions.h"
|
||||||
|
#include "frame.h"
|
||||||
|
#include "symtab.h"
|
||||||
|
#include "python-internal.h"
|
||||||
|
#include "objfiles.h"
|
||||||
|
|
||||||
|
typedef struct sympy_symbol_object {
|
||||||
|
PyObject_HEAD
|
||||||
|
/* The GDB symbol structure this object is wrapping. */
|
||||||
|
struct symbol *symbol;
|
||||||
|
/* A symbol object is associated with an objfile, so keep track with
|
||||||
|
doubly-linked list, rooted in the objfile. This lets us
|
||||||
|
invalidate the underlying struct symbol when the objfile is
|
||||||
|
deleted. */
|
||||||
|
struct sympy_symbol_object *prev;
|
||||||
|
struct sympy_symbol_object *next;
|
||||||
|
} symbol_object;
|
||||||
|
|
||||||
|
/* Require a valid symbol. All access to symbol_object->symbol should be
|
||||||
|
gated by this call. */
|
||||||
|
#define SYMPY_REQUIRE_VALID(symbol_obj, symbol) \
|
||||||
|
do { \
|
||||||
|
symbol = symbol_object_to_symbol (symbol_obj); \
|
||||||
|
if (symbol == NULL) \
|
||||||
|
{ \
|
||||||
|
PyErr_SetString (PyExc_RuntimeError, \
|
||||||
|
_("Symbol is invalid.")); \
|
||||||
|
return NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static const struct objfile_data *sympy_objfile_data_key;
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_str (PyObject *self)
|
||||||
|
{
|
||||||
|
PyObject *result;
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
result = PyString_FromString (SYMBOL_PRINT_NAME (symbol));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_get_symtab (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
return symtab_to_symtab_object (SYMBOL_SYMTAB (symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_get_name (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
return PyString_FromString (SYMBOL_NATURAL_NAME (symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_get_linkage_name (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
return PyString_FromString (SYMBOL_LINKAGE_NAME (symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_get_print_name (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
return sympy_str (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_get_addr_class (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
return PyInt_FromLong (SYMBOL_CLASS (symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_is_argument (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
return PyBool_FromLong (SYMBOL_IS_ARGUMENT (symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_is_constant (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
enum address_class class;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
class = SYMBOL_CLASS (symbol);
|
||||||
|
|
||||||
|
return PyBool_FromLong (class == LOC_CONST || class == LOC_CONST_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_is_function (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
enum address_class class;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
class = SYMBOL_CLASS (symbol);
|
||||||
|
|
||||||
|
return PyBool_FromLong (class == LOC_BLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
sympy_is_variable (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symbol *symbol = NULL;
|
||||||
|
enum address_class class;
|
||||||
|
|
||||||
|
SYMPY_REQUIRE_VALID (self, symbol);
|
||||||
|
|
||||||
|
class = SYMBOL_CLASS (symbol);
|
||||||
|
|
||||||
|
return PyBool_FromLong (!SYMBOL_IS_ARGUMENT (symbol)
|
||||||
|
&& (class == LOC_LOCAL || class == LOC_REGISTER
|
||||||
|
|| class == LOC_STATIC || class == LOC_COMPUTED
|
||||||
|
|| class == LOC_OPTIMIZED_OUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a symbol, and a symbol_object that has previously been
|
||||||
|
allocated and initialized, populate the symbol_object with the
|
||||||
|
struct symbol data. Also, register the symbol_object life-cycle
|
||||||
|
with the life-cycle of the the object file associated with this
|
||||||
|
symbol, if needed. */
|
||||||
|
static void
|
||||||
|
set_symbol (symbol_object *obj, struct symbol *symbol)
|
||||||
|
{
|
||||||
|
obj->symbol = symbol;
|
||||||
|
obj->prev = NULL;
|
||||||
|
if (SYMBOL_SYMTAB (symbol))
|
||||||
|
{
|
||||||
|
obj->next = objfile_data (SYMBOL_SYMTAB (symbol)->objfile,
|
||||||
|
sympy_objfile_data_key);
|
||||||
|
|
||||||
|
if (obj->next)
|
||||||
|
obj->next->prev = obj;
|
||||||
|
set_objfile_data (SYMBOL_SYMTAB (symbol)->objfile,
|
||||||
|
sympy_objfile_data_key, obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
obj->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new symbol object (gdb.Symbol) that encapsulates the struct
|
||||||
|
symbol object from GDB. */
|
||||||
|
PyObject *
|
||||||
|
symbol_to_symbol_object (struct symbol *sym)
|
||||||
|
{
|
||||||
|
symbol_object *sym_obj;
|
||||||
|
|
||||||
|
sym_obj = PyObject_New (symbol_object, &symbol_object_type);
|
||||||
|
if (sym_obj)
|
||||||
|
set_symbol (sym_obj, sym);
|
||||||
|
|
||||||
|
return (PyObject *) sym_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the symbol that is wrapped by this symbol object. */
|
||||||
|
struct symbol *
|
||||||
|
symbol_object_to_symbol (PyObject *obj)
|
||||||
|
{
|
||||||
|
if (! PyObject_TypeCheck (obj, &symbol_object_type))
|
||||||
|
return NULL;
|
||||||
|
return ((symbol_object *) obj)->symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sympy_dealloc (PyObject *obj)
|
||||||
|
{
|
||||||
|
symbol_object *sym_obj = (symbol_object *) obj;
|
||||||
|
|
||||||
|
if (sym_obj->prev)
|
||||||
|
sym_obj->prev->next = sym_obj->next;
|
||||||
|
else if (SYMBOL_SYMTAB (sym_obj->symbol))
|
||||||
|
{
|
||||||
|
set_objfile_data (SYMBOL_SYMTAB (sym_obj->symbol)->objfile,
|
||||||
|
sympy_objfile_data_key, sym_obj->next);
|
||||||
|
}
|
||||||
|
if (sym_obj->next)
|
||||||
|
sym_obj->next->prev = sym_obj->prev;
|
||||||
|
sym_obj->symbol = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of
|
||||||
|
gdb.lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)
|
||||||
|
A tuple with 2 elements is always returned. The first is the symbol
|
||||||
|
object or None, the second is a boolean with the value of
|
||||||
|
is_a_field_of_this (see comment in lookup_symbol_in_language). */
|
||||||
|
PyObject *
|
||||||
|
gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
|
||||||
|
{
|
||||||
|
int domain = VAR_DOMAIN, is_a_field_of_this = 0;
|
||||||
|
const char *name;
|
||||||
|
static char *keywords[] = { "name", "block", "domain", NULL };
|
||||||
|
struct symbol *symbol;
|
||||||
|
PyObject *block_obj = NULL, *ret_tuple, *sym_obj, *bool_obj;
|
||||||
|
struct block *block = NULL;
|
||||||
|
|
||||||
|
if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name,
|
||||||
|
&block_object_type, &block_obj, &domain))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (block_obj)
|
||||||
|
block = block_object_to_block (block_obj);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct frame_info *selected_frame;
|
||||||
|
volatile struct gdb_exception except;
|
||||||
|
|
||||||
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
selected_frame = get_selected_frame (_("No frame selected."));
|
||||||
|
block = block_for_pc (get_frame_address_in_block (selected_frame));
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol = lookup_symbol (name, block, domain, &is_a_field_of_this);
|
||||||
|
|
||||||
|
ret_tuple = PyTuple_New (2);
|
||||||
|
if (!ret_tuple)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (symbol)
|
||||||
|
{
|
||||||
|
sym_obj = symbol_to_symbol_object (symbol);
|
||||||
|
if (!sym_obj)
|
||||||
|
{
|
||||||
|
Py_DECREF (ret_tuple);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sym_obj = Py_None;
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
}
|
||||||
|
PyTuple_SET_ITEM (ret_tuple, 0, sym_obj);
|
||||||
|
|
||||||
|
bool_obj = is_a_field_of_this? Py_True : Py_False;
|
||||||
|
Py_INCREF (bool_obj);
|
||||||
|
PyTuple_SET_ITEM (ret_tuple, 1, bool_obj);
|
||||||
|
|
||||||
|
return ret_tuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is called when an objfile is about to be freed.
|
||||||
|
Invalidate the symbol as further actions on the symbol would result
|
||||||
|
in bad data. All access to obj->symbol should be gated by
|
||||||
|
SYMPY_REQUIRE_VALID which will raise an exception on invalid
|
||||||
|
symbols. */
|
||||||
|
static void
|
||||||
|
del_objfile_symbols (struct objfile *objfile, void *datum)
|
||||||
|
{
|
||||||
|
symbol_object *obj = datum;
|
||||||
|
while (obj)
|
||||||
|
{
|
||||||
|
symbol_object *next = obj->next;
|
||||||
|
|
||||||
|
obj->symbol = NULL;
|
||||||
|
obj->next = NULL;
|
||||||
|
obj->prev = NULL;
|
||||||
|
|
||||||
|
obj = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdbpy_initialize_symbols (void)
|
||||||
|
{
|
||||||
|
if (PyType_Ready (&symbol_object_type) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Register an objfile "free" callback so we can properly
|
||||||
|
invalidate symbol when an object file that is about to be
|
||||||
|
deleted. */
|
||||||
|
sympy_objfile_data_key
|
||||||
|
= register_objfile_data_with_cleanup (NULL, del_objfile_symbols);
|
||||||
|
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNDEF", LOC_UNDEF);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST", LOC_CONST);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_STATIC", LOC_STATIC);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGISTER", LOC_REGISTER);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_ARG", LOC_ARG);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REF_ARG", LOC_REF_ARG);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LOCAL", LOC_LOCAL);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_TYPEDEF", LOC_TYPEDEF);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LABEL", LOC_LABEL);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_BLOCK", LOC_BLOCK);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST_BYTES",
|
||||||
|
LOC_CONST_BYTES);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNRESOLVED", LOC_UNRESOLVED);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_OPTIMIZED_OUT",
|
||||||
|
LOC_OPTIMIZED_OUT);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_COMPUTED", LOC_COMPUTED);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGPARM_ADDR",
|
||||||
|
LOC_REGPARM_ADDR);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_UNDEF_DOMAIN", UNDEF_DOMAIN);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_VAR_DOMAIN", VAR_DOMAIN);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_STRUCT_DOMAIN", STRUCT_DOMAIN);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_LABEL_DOMAIN", LABEL_DOMAIN);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_VARIABLES_DOMAIN",
|
||||||
|
VARIABLES_DOMAIN);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_FUNCTIONS_DOMAIN",
|
||||||
|
FUNCTIONS_DOMAIN);
|
||||||
|
PyModule_AddIntConstant (gdb_module, "SYMBOL_TYPES_DOMAIN", TYPES_DOMAIN);
|
||||||
|
|
||||||
|
Py_INCREF (&symbol_object_type);
|
||||||
|
PyModule_AddObject (gdb_module, "Symbol", (PyObject *) &symbol_object_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static PyGetSetDef symbol_object_getset[] = {
|
||||||
|
{ "symtab", sympy_get_symtab, NULL,
|
||||||
|
"Symbol table in which the symbol appears.", NULL },
|
||||||
|
{ "name", sympy_get_name, NULL,
|
||||||
|
"Name of the symbol, as it appears in the source code.", NULL },
|
||||||
|
{ "linkage_name", sympy_get_linkage_name, NULL,
|
||||||
|
"Name of the symbol, as used by the linker (i.e., may be mangled).", NULL },
|
||||||
|
{ "print_name", sympy_get_print_name, NULL,
|
||||||
|
"Name of the symbol in a form suitable for output.\n\
|
||||||
|
This is either name or linkage_name, depending on whether the user asked GDB\n\
|
||||||
|
to display demangled or mangled names.", NULL },
|
||||||
|
{ "addr_class", sympy_get_addr_class, NULL, "Address class of the symbol." },
|
||||||
|
{ "is_argument", sympy_is_argument, NULL,
|
||||||
|
"True if the symbol is an argument of a function." },
|
||||||
|
{ "is_constant", sympy_is_constant, NULL,
|
||||||
|
"True if the symbol is a constant." },
|
||||||
|
{ "is_function", sympy_is_function, NULL,
|
||||||
|
"True if the symbol is a function or method." },
|
||||||
|
{ "is_variable", sympy_is_variable, NULL,
|
||||||
|
"True if the symbol is a variable." },
|
||||||
|
{ NULL } /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
PyTypeObject symbol_object_type = {
|
||||||
|
PyObject_HEAD_INIT (NULL)
|
||||||
|
0, /*ob_size*/
|
||||||
|
"gdb.Symbol", /*tp_name*/
|
||||||
|
sizeof (symbol_object), /*tp_basicsize*/
|
||||||
|
0, /*tp_itemsize*/
|
||||||
|
sympy_dealloc, /*tp_dealloc*/
|
||||||
|
0, /*tp_print*/
|
||||||
|
0, /*tp_getattr*/
|
||||||
|
0, /*tp_setattr*/
|
||||||
|
0, /*tp_compare*/
|
||||||
|
0, /*tp_repr*/
|
||||||
|
0, /*tp_as_number*/
|
||||||
|
0, /*tp_as_sequence*/
|
||||||
|
0, /*tp_as_mapping*/
|
||||||
|
0, /*tp_hash */
|
||||||
|
0, /*tp_call*/
|
||||||
|
sympy_str, /*tp_str*/
|
||||||
|
0, /*tp_getattro*/
|
||||||
|
0, /*tp_setattro*/
|
||||||
|
0, /*tp_as_buffer*/
|
||||||
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
||||||
|
"GDB symbol object", /*tp_doc */
|
||||||
|
0, /*tp_traverse */
|
||||||
|
0, /*tp_clear */
|
||||||
|
0, /*tp_richcompare */
|
||||||
|
0, /*tp_weaklistoffset */
|
||||||
|
0, /*tp_iter */
|
||||||
|
0, /*tp_iternext */
|
||||||
|
0, /*tp_methods */
|
||||||
|
0, /*tp_members */
|
||||||
|
symbol_object_getset /*tp_getset */
|
||||||
|
};
|
||||||
523
gdb/python/py-symtab.c
Normal file
523
gdb/python/py-symtab.c
Normal file
@@ -0,0 +1,523 @@
|
|||||||
|
/* Python interface to symbol tables.
|
||||||
|
|
||||||
|
Copyright (C) 2008, 2009, 2010 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/>. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "charset.h"
|
||||||
|
#include "symtab.h"
|
||||||
|
#include "source.h"
|
||||||
|
#include "python-internal.h"
|
||||||
|
#include "objfiles.h"
|
||||||
|
|
||||||
|
typedef struct stpy_symtab_object {
|
||||||
|
PyObject_HEAD
|
||||||
|
/* The GDB Symbol table structure. */
|
||||||
|
struct symtab *symtab;
|
||||||
|
/* A symtab object is associated with an objfile, so keep track with
|
||||||
|
a doubly-linked list, rooted in the objfile. This allows
|
||||||
|
invalidation of the underlying struct symtab when the objfile is
|
||||||
|
deleted. */
|
||||||
|
struct stpy_symtab_object *prev;
|
||||||
|
struct stpy_symtab_object *next;
|
||||||
|
} symtab_object;
|
||||||
|
|
||||||
|
static PyTypeObject symtab_object_type;
|
||||||
|
static const struct objfile_data *stpy_objfile_data_key;
|
||||||
|
|
||||||
|
/* Require a valid symbol table. All access to symtab_object->symtab
|
||||||
|
should be gated by this call. */
|
||||||
|
#define STPY_REQUIRE_VALID(symtab_obj, symtab) \
|
||||||
|
do { \
|
||||||
|
symtab = symtab_object_to_symtab (symtab_obj); \
|
||||||
|
if (symtab == NULL) \
|
||||||
|
{ \
|
||||||
|
PyErr_SetString (PyExc_RuntimeError, \
|
||||||
|
_("Symbol Table is invalid.")); \
|
||||||
|
return NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
typedef struct salpy_sal_object {
|
||||||
|
PyObject_HEAD
|
||||||
|
/* The GDB Symbol table structure. */
|
||||||
|
symtab_object *symtab;
|
||||||
|
/* The GDB Symbol table and line structure. */
|
||||||
|
struct symtab_and_line *sal;
|
||||||
|
/* A Symtab and line object is associated with an objfile, so keep
|
||||||
|
track with a doubly-linked list, rooted in the objfile. This
|
||||||
|
allows invalidation of the underlying struct symtab_and_line
|
||||||
|
when the objfile is deleted. */
|
||||||
|
struct salpy_sal_object *prev;
|
||||||
|
struct salpy_sal_object *next;
|
||||||
|
} sal_object;
|
||||||
|
|
||||||
|
static PyTypeObject sal_object_type;
|
||||||
|
static const struct objfile_data *salpy_objfile_data_key;
|
||||||
|
|
||||||
|
/* Require a valid symbol table and line object. All access to
|
||||||
|
sal_object->sal should be gated by this call. */
|
||||||
|
#define SALPY_REQUIRE_VALID(sal_obj, sal) \
|
||||||
|
do { \
|
||||||
|
sal = sal_object_to_symtab_and_line (sal_obj); \
|
||||||
|
if (sal == NULL) \
|
||||||
|
{ \
|
||||||
|
PyErr_SetString (PyExc_RuntimeError, \
|
||||||
|
_("Symbol Table and Line is invalid.")); \
|
||||||
|
return NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
stpy_str (PyObject *self)
|
||||||
|
{
|
||||||
|
PyObject *result;
|
||||||
|
struct symtab *symtab = NULL;
|
||||||
|
|
||||||
|
STPY_REQUIRE_VALID (self, symtab);
|
||||||
|
|
||||||
|
result = PyString_FromString (symtab->filename);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
stpy_get_filename (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
PyObject *str_obj;
|
||||||
|
struct symtab *symtab = NULL;
|
||||||
|
|
||||||
|
STPY_REQUIRE_VALID (self, symtab);
|
||||||
|
|
||||||
|
str_obj = PyString_Decode (symtab->filename,
|
||||||
|
strlen (symtab->filename),
|
||||||
|
host_charset (), NULL);
|
||||||
|
return str_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
stpy_get_objfile (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symtab *symtab = NULL;
|
||||||
|
PyObject *result;
|
||||||
|
|
||||||
|
STPY_REQUIRE_VALID (self, symtab);
|
||||||
|
|
||||||
|
result = objfile_to_objfile_object (symtab->objfile);
|
||||||
|
Py_XINCREF (result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
stpy_fullname (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
char *fullname;
|
||||||
|
struct symtab *symtab = NULL;
|
||||||
|
|
||||||
|
STPY_REQUIRE_VALID (self, symtab);
|
||||||
|
|
||||||
|
fullname = symtab_to_fullname (symtab);
|
||||||
|
if (fullname)
|
||||||
|
return PyString_Decode (fullname, strlen (fullname),
|
||||||
|
host_charset (), NULL);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
salpy_str (PyObject *self)
|
||||||
|
{
|
||||||
|
char *s, *filename;
|
||||||
|
sal_object *sal_obj;
|
||||||
|
PyObject *result;
|
||||||
|
struct symtab_and_line *sal = NULL;
|
||||||
|
|
||||||
|
SALPY_REQUIRE_VALID (self, sal);
|
||||||
|
|
||||||
|
sal_obj = (sal_object *) self;
|
||||||
|
filename = (sal_obj->symtab == (symtab_object *) Py_None)
|
||||||
|
? "<unknown>" : sal_obj->symtab->symtab->filename;
|
||||||
|
|
||||||
|
s = xstrprintf ("symbol and line for %s, line %d", filename,
|
||||||
|
sal->line);
|
||||||
|
|
||||||
|
result = PyString_FromString (s);
|
||||||
|
xfree (s);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stpy_dealloc (PyObject *obj)
|
||||||
|
{
|
||||||
|
symtab_object *symtab = (symtab_object *) obj;
|
||||||
|
|
||||||
|
if (symtab->prev)
|
||||||
|
symtab->prev->next = symtab->next;
|
||||||
|
else if (symtab->symtab)
|
||||||
|
{
|
||||||
|
set_objfile_data (symtab->symtab->objfile,
|
||||||
|
stpy_objfile_data_key, symtab->next);
|
||||||
|
}
|
||||||
|
if (symtab->next)
|
||||||
|
symtab->next->prev = symtab->prev;
|
||||||
|
symtab->symtab = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
salpy_get_pc (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symtab_and_line *sal = NULL;
|
||||||
|
|
||||||
|
SALPY_REQUIRE_VALID (self, sal);
|
||||||
|
|
||||||
|
return PyLong_FromUnsignedLongLong (sal->pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
salpy_get_line (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symtab_and_line *sal = NULL;
|
||||||
|
|
||||||
|
SALPY_REQUIRE_VALID (self, sal);
|
||||||
|
|
||||||
|
return PyLong_FromUnsignedLongLong (sal->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
salpy_get_symtab (PyObject *self, void *closure)
|
||||||
|
{
|
||||||
|
struct symtab_and_line *sal;
|
||||||
|
sal_object *self_sal = (sal_object *) self;
|
||||||
|
|
||||||
|
SALPY_REQUIRE_VALID (self, sal);
|
||||||
|
|
||||||
|
Py_INCREF (self_sal->symtab);
|
||||||
|
|
||||||
|
return (PyObject *) self_sal->symtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
salpy_dealloc (PyObject *self)
|
||||||
|
{
|
||||||
|
sal_object *self_sal = (sal_object *) self;
|
||||||
|
|
||||||
|
if (self_sal->prev)
|
||||||
|
self_sal->prev->next = self_sal->next;
|
||||||
|
else if (self_sal->symtab != (symtab_object * ) Py_None)
|
||||||
|
set_objfile_data (self_sal->symtab->symtab->objfile,
|
||||||
|
salpy_objfile_data_key, self_sal->next);
|
||||||
|
|
||||||
|
if (self_sal->next)
|
||||||
|
self_sal->next->prev = self_sal->prev;
|
||||||
|
|
||||||
|
Py_DECREF (self_sal->symtab);
|
||||||
|
xfree (self_sal->sal);
|
||||||
|
self_sal->ob_type->tp_free (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a sal, and a sal_object that has previously been
|
||||||
|
allocated and initialized, populate the sal_object with the
|
||||||
|
struct sal data. Also, register the sal_object life-cycle with the
|
||||||
|
life-cycle of the the object file associated with this sal, if
|
||||||
|
needed. If a failure occurs during the sal population, this
|
||||||
|
function will return NULL. */
|
||||||
|
static int
|
||||||
|
set_sal (sal_object *sal_obj, struct symtab_and_line sal)
|
||||||
|
{
|
||||||
|
symtab_object *symtab_obj;
|
||||||
|
|
||||||
|
if (sal.symtab)
|
||||||
|
{
|
||||||
|
symtab_obj = (symtab_object *) symtab_to_symtab_object (sal.symtab);
|
||||||
|
/* If a symtab existed in the sal, but it cannot be duplicated,
|
||||||
|
we exit. */
|
||||||
|
if (symtab_obj == NULL)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
symtab_obj = (symtab_object *) Py_None;
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
}
|
||||||
|
|
||||||
|
sal_obj->sal = xmemdup (&sal, sizeof (struct symtab_and_line),
|
||||||
|
sizeof (struct symtab_and_line));
|
||||||
|
sal_obj->symtab = symtab_obj;
|
||||||
|
sal_obj->prev = NULL;
|
||||||
|
|
||||||
|
/* If the SAL does not have a symtab, we do not add it to the
|
||||||
|
objfile cleanup observer linked list. */
|
||||||
|
if (sal_obj->symtab != (symtab_object *)Py_None)
|
||||||
|
{
|
||||||
|
sal_obj->next = objfile_data (sal_obj->symtab->symtab->objfile,
|
||||||
|
salpy_objfile_data_key);
|
||||||
|
if (sal_obj->next)
|
||||||
|
sal_obj->next->prev = sal_obj;
|
||||||
|
|
||||||
|
set_objfile_data (sal_obj->symtab->symtab->objfile,
|
||||||
|
salpy_objfile_data_key, sal_obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sal_obj->next = NULL;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a symtab, and a symtab_object that has previously been
|
||||||
|
allocated and initialized, populate the symtab_object with the
|
||||||
|
struct symtab data. Also, register the symtab_object life-cycle
|
||||||
|
with the life-cycle of the the object file associated with this
|
||||||
|
symtab, if needed. */
|
||||||
|
static void
|
||||||
|
set_symtab (symtab_object *obj, struct symtab *symtab)
|
||||||
|
{
|
||||||
|
obj->symtab = symtab;
|
||||||
|
obj->prev = NULL;
|
||||||
|
if (symtab)
|
||||||
|
{
|
||||||
|
obj->next = objfile_data (symtab->objfile, stpy_objfile_data_key);
|
||||||
|
if (obj->next)
|
||||||
|
obj->next->prev = obj;
|
||||||
|
set_objfile_data (symtab->objfile, stpy_objfile_data_key, obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
obj->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new symbol table (gdb.Symtab) object that encapsulates the
|
||||||
|
symtab structure from GDB. */
|
||||||
|
PyObject *
|
||||||
|
symtab_to_symtab_object (struct symtab *symtab)
|
||||||
|
{
|
||||||
|
symtab_object *symtab_obj;
|
||||||
|
|
||||||
|
symtab_obj = PyObject_New (symtab_object, &symtab_object_type);
|
||||||
|
if (symtab_obj)
|
||||||
|
set_symtab (symtab_obj, symtab);
|
||||||
|
|
||||||
|
return (PyObject *) symtab_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new symtab and line (gdb.Symtab_and_line) object
|
||||||
|
that encapsulates the symtab_and_line structure from GDB. */
|
||||||
|
PyObject *
|
||||||
|
symtab_and_line_to_sal_object (struct symtab_and_line sal)
|
||||||
|
|
||||||
|
{
|
||||||
|
sal_object *sal_obj;
|
||||||
|
symtab_object *symtab_obj;
|
||||||
|
int success = 0;
|
||||||
|
sal_obj = PyObject_New (sal_object, &sal_object_type);
|
||||||
|
|
||||||
|
if (sal_obj)
|
||||||
|
{
|
||||||
|
success = set_sal (sal_obj, sal);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
Py_DECREF (sal_obj);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (PyObject *) sal_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return struct symtab_and_line reference that is wrapped by this
|
||||||
|
object. */
|
||||||
|
struct symtab_and_line *
|
||||||
|
sal_object_to_symtab_and_line (PyObject *obj)
|
||||||
|
{
|
||||||
|
if (! PyObject_TypeCheck (obj, &sal_object_type))
|
||||||
|
return NULL;
|
||||||
|
return ((sal_object *) obj)->sal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return struct symtab reference that is wrapped by this object. */
|
||||||
|
struct symtab *
|
||||||
|
symtab_object_to_symtab (PyObject *obj)
|
||||||
|
{
|
||||||
|
if (! PyObject_TypeCheck (obj, &symtab_object_type))
|
||||||
|
return NULL;
|
||||||
|
return ((symtab_object *) obj)->symtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is called when an objfile is about to be freed.
|
||||||
|
Invalidate the symbol table as further actions on the symbol table
|
||||||
|
would result in bad data. All access to obj->symtab should be
|
||||||
|
gated by STPY_REQUIRE_VALID which will raise an exception on
|
||||||
|
invalid symbol tables. */
|
||||||
|
static void
|
||||||
|
del_objfile_symtab (struct objfile *objfile, void *datum)
|
||||||
|
{
|
||||||
|
symtab_object *obj = datum;
|
||||||
|
while (obj)
|
||||||
|
{
|
||||||
|
symtab_object *next = obj->next;
|
||||||
|
|
||||||
|
obj->symtab = NULL;
|
||||||
|
obj->next = NULL;
|
||||||
|
obj->prev = NULL;
|
||||||
|
obj = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is called when an objfile is about to be freed.
|
||||||
|
Invalidate the sal object as further actions on the sal
|
||||||
|
would result in bad data. All access to obj->sal should be
|
||||||
|
gated by SALPY_REQUIRE_VALID which will raise an exception on
|
||||||
|
invalid symbol table and line objects. */
|
||||||
|
static void
|
||||||
|
del_objfile_sal (struct objfile *objfile, void *datum)
|
||||||
|
{
|
||||||
|
sal_object *obj = datum;
|
||||||
|
while (obj)
|
||||||
|
{
|
||||||
|
sal_object *next = obj->next;
|
||||||
|
|
||||||
|
obj->symtab = NULL;
|
||||||
|
obj->next = NULL;
|
||||||
|
obj->prev = NULL;
|
||||||
|
xfree (obj->sal);
|
||||||
|
obj->sal = NULL;
|
||||||
|
|
||||||
|
obj = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdbpy_initialize_symtabs (void)
|
||||||
|
{
|
||||||
|
symtab_object_type.tp_new = PyType_GenericNew;
|
||||||
|
if (PyType_Ready (&symtab_object_type) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sal_object_type.tp_new = PyType_GenericNew;
|
||||||
|
if (PyType_Ready (&sal_object_type) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Register an objfile "free" callback so we can properly
|
||||||
|
invalidate symbol tables, and symbol table and line data
|
||||||
|
structures when an object file that is about to be
|
||||||
|
deleted. */
|
||||||
|
stpy_objfile_data_key
|
||||||
|
= register_objfile_data_with_cleanup (NULL, del_objfile_symtab);
|
||||||
|
salpy_objfile_data_key
|
||||||
|
= register_objfile_data_with_cleanup (NULL, del_objfile_sal);
|
||||||
|
|
||||||
|
Py_INCREF (&symtab_object_type);
|
||||||
|
PyModule_AddObject (gdb_module, "Symtab",
|
||||||
|
(PyObject *) &symtab_object_type);
|
||||||
|
|
||||||
|
Py_INCREF (&sal_object_type);
|
||||||
|
PyModule_AddObject (gdb_module, "Symtab_and_line",
|
||||||
|
(PyObject *) &sal_object_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static PyGetSetDef symtab_object_getset[] = {
|
||||||
|
{ "filename", stpy_get_filename, NULL,
|
||||||
|
"The symbol table's source filename.", NULL },
|
||||||
|
{ "objfile", stpy_get_objfile, NULL, "The symtab's objfile.",
|
||||||
|
NULL },
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyMethodDef symtab_object_methods[] = {
|
||||||
|
{ "fullname", stpy_fullname, METH_NOARGS,
|
||||||
|
"fullname () -> String.\n\
|
||||||
|
Return the symtab's full source filename." },
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyTypeObject symtab_object_type = {
|
||||||
|
PyObject_HEAD_INIT (NULL)
|
||||||
|
0, /*ob_size*/
|
||||||
|
"gdb.Symtab", /*tp_name*/
|
||||||
|
sizeof (symtab_object), /*tp_basicsize*/
|
||||||
|
0, /*tp_itemsize*/
|
||||||
|
stpy_dealloc, /*tp_dealloc*/
|
||||||
|
0, /*tp_print*/
|
||||||
|
0, /*tp_getattr*/
|
||||||
|
0, /*tp_setattr*/
|
||||||
|
0, /*tp_compare*/
|
||||||
|
0, /*tp_repr*/
|
||||||
|
0, /*tp_as_number*/
|
||||||
|
0, /*tp_as_sequence*/
|
||||||
|
0, /*tp_as_mapping*/
|
||||||
|
0, /*tp_hash */
|
||||||
|
0, /*tp_call*/
|
||||||
|
stpy_str, /*tp_str*/
|
||||||
|
0, /*tp_getattro*/
|
||||||
|
0, /*tp_setattro*/
|
||||||
|
0, /*tp_as_buffer*/
|
||||||
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
||||||
|
"GDB symtab object", /*tp_doc */
|
||||||
|
0, /*tp_traverse */
|
||||||
|
0, /*tp_clear */
|
||||||
|
0, /*tp_richcompare */
|
||||||
|
0, /*tp_weaklistoffset */
|
||||||
|
0, /*tp_iter */
|
||||||
|
0, /*tp_iternext */
|
||||||
|
symtab_object_methods, /*tp_methods */
|
||||||
|
0, /*tp_members */
|
||||||
|
symtab_object_getset /*tp_getset */
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyGetSetDef sal_object_getset[] = {
|
||||||
|
{ "symtab", salpy_get_symtab, NULL, "Symtab object.", NULL },
|
||||||
|
{ "pc", salpy_get_pc, NULL, "Return the symtab_and_line's pc.", NULL },
|
||||||
|
{ "line", salpy_get_line, NULL,
|
||||||
|
"Return the symtab_and_line's line.", NULL },
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyTypeObject sal_object_type = {
|
||||||
|
PyObject_HEAD_INIT (NULL)
|
||||||
|
0, /*ob_size*/
|
||||||
|
"gdb.Symtab_and_line", /*tp_name*/
|
||||||
|
sizeof (sal_object), /*tp_basicsize*/
|
||||||
|
0, /*tp_itemsize*/
|
||||||
|
salpy_dealloc, /*tp_dealloc*/
|
||||||
|
0, /*tp_print*/
|
||||||
|
0, /*tp_getattr*/
|
||||||
|
0, /*tp_setattr*/
|
||||||
|
0, /*tp_compare*/
|
||||||
|
0, /*tp_repr*/
|
||||||
|
0, /*tp_as_number*/
|
||||||
|
0, /*tp_as_sequence*/
|
||||||
|
0, /*tp_as_mapping*/
|
||||||
|
0, /*tp_hash */
|
||||||
|
0, /*tp_call*/
|
||||||
|
salpy_str, /*tp_str*/
|
||||||
|
0, /*tp_getattro*/
|
||||||
|
0, /*tp_setattro*/
|
||||||
|
0, /*tp_as_buffer*/
|
||||||
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
||||||
|
"GDB symtab_and_line object", /*tp_doc */
|
||||||
|
0, /*tp_traverse */
|
||||||
|
0, /*tp_clear */
|
||||||
|
0, /*tp_richcompare */
|
||||||
|
0, /*tp_weaklistoffset */
|
||||||
|
0, /*tp_iter */
|
||||||
|
0, /*tp_iternext */
|
||||||
|
0, /*tp_methods */
|
||||||
|
0, /*tp_members */
|
||||||
|
sal_object_getset /*tp_getset */
|
||||||
|
};
|
||||||
@@ -61,32 +61,51 @@ typedef int Py_ssize_t;
|
|||||||
#define PyEval_ReleaseLock() 0
|
#define PyEval_ReleaseLock() 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct block;
|
||||||
|
struct symbol;
|
||||||
|
struct symtab_and_line;
|
||||||
struct value;
|
struct value;
|
||||||
struct language_defn;
|
struct language_defn;
|
||||||
|
|
||||||
extern PyObject *gdb_module;
|
extern PyObject *gdb_module;
|
||||||
extern PyTypeObject value_object_type;
|
extern PyTypeObject value_object_type;
|
||||||
|
extern PyTypeObject block_object_type;
|
||||||
|
extern PyTypeObject symbol_object_type;
|
||||||
|
|
||||||
PyObject *gdbpy_history (PyObject *self, PyObject *args);
|
PyObject *gdbpy_history (PyObject *self, PyObject *args);
|
||||||
PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
|
PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
|
||||||
|
PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw);
|
||||||
PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
|
PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
|
||||||
|
PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args);
|
||||||
PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
|
PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
|
||||||
PyObject *gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
|
PyObject *gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
|
||||||
const char *encoding, struct type *type);
|
const char *encoding, struct type *type);
|
||||||
|
|
||||||
|
PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal);
|
||||||
|
PyObject *symtab_to_symtab_object (struct symtab *symtab);
|
||||||
|
PyObject *symbol_to_symbol_object (struct symbol *sym);
|
||||||
|
PyObject *block_to_block_object (struct block *block, struct objfile *objfile);
|
||||||
PyObject *value_to_value_object (struct value *v);
|
PyObject *value_to_value_object (struct value *v);
|
||||||
PyObject *type_to_type_object (struct type *);
|
PyObject *type_to_type_object (struct type *);
|
||||||
PyObject *objfile_to_objfile_object (struct objfile *);
|
PyObject *objfile_to_objfile_object (struct objfile *);
|
||||||
|
|
||||||
PyObject *objfpy_get_printers (PyObject *, void *);
|
PyObject *objfpy_get_printers (PyObject *, void *);
|
||||||
|
|
||||||
|
struct block *block_object_to_block (PyObject *obj);
|
||||||
|
struct symbol *symbol_object_to_symbol (PyObject *obj);
|
||||||
struct value *value_object_to_value (PyObject *self);
|
struct value *value_object_to_value (PyObject *self);
|
||||||
struct value *convert_value_from_python (PyObject *obj);
|
struct value *convert_value_from_python (PyObject *obj);
|
||||||
struct type *type_object_to_type (PyObject *obj);
|
struct type *type_object_to_type (PyObject *obj);
|
||||||
|
struct symtab *symtab_object_to_symtab (PyObject *obj);
|
||||||
|
struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
|
||||||
|
|
||||||
void gdbpy_initialize_values (void);
|
void gdbpy_initialize_values (void);
|
||||||
void gdbpy_initialize_frames (void);
|
void gdbpy_initialize_frames (void);
|
||||||
|
void gdbpy_initialize_symtabs (void);
|
||||||
void gdbpy_initialize_commands (void);
|
void gdbpy_initialize_commands (void);
|
||||||
|
void gdbpy_initialize_symbols (void);
|
||||||
|
void gdbpy_initialize_symtabs (void);
|
||||||
|
void gdbpy_initialize_blocks (void);
|
||||||
void gdbpy_initialize_types (void);
|
void gdbpy_initialize_types (void);
|
||||||
void gdbpy_initialize_functions (void);
|
void gdbpy_initialize_functions (void);
|
||||||
void gdbpy_initialize_objfile (void);
|
void gdbpy_initialize_objfile (void);
|
||||||
|
|||||||
@@ -644,6 +644,9 @@ Enables or disables auto-loading of Python code when an object is opened."),
|
|||||||
gdbpy_initialize_values ();
|
gdbpy_initialize_values ();
|
||||||
gdbpy_initialize_frames ();
|
gdbpy_initialize_frames ();
|
||||||
gdbpy_initialize_commands ();
|
gdbpy_initialize_commands ();
|
||||||
|
gdbpy_initialize_symbols ();
|
||||||
|
gdbpy_initialize_symtabs ();
|
||||||
|
gdbpy_initialize_blocks ();
|
||||||
gdbpy_initialize_functions ();
|
gdbpy_initialize_functions ();
|
||||||
gdbpy_initialize_types ();
|
gdbpy_initialize_types ();
|
||||||
gdbpy_initialize_objfile ();
|
gdbpy_initialize_objfile ();
|
||||||
@@ -724,7 +727,14 @@ Return a string explaining unwind stop reason." },
|
|||||||
METH_VARARGS | METH_KEYWORDS,
|
METH_VARARGS | METH_KEYWORDS,
|
||||||
"lookup_type (name [, block]) -> type\n\
|
"lookup_type (name [, block]) -> type\n\
|
||||||
Return a Type corresponding to the given name." },
|
Return a Type corresponding to the given name." },
|
||||||
|
{ "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol,
|
||||||
|
METH_VARARGS | METH_KEYWORDS,
|
||||||
|
"lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\
|
||||||
|
Return a tuple with the symbol corresponding to the given name (or None) and\n\
|
||||||
|
a boolean indicating if name is a field of the current implied argument\n\
|
||||||
|
`this' (when the current language is object-oriented)." },
|
||||||
|
{ "block_for_pc", gdbpy_block_for_pc, METH_VARARGS,
|
||||||
|
"Return the block containing the given pc value, or None." },
|
||||||
{ "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS,
|
{ "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS,
|
||||||
"parse_and_eval (String) -> Value.\n\
|
"parse_and_eval (String) -> Value.\n\
|
||||||
Parse String as an expression, evaluate it, and return the result as a Value."
|
Parse String as an expression, evaluate it, and return the result as a Value."
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
2010-02-24 Phil Muldoon <pmuldoon@redhat.com>
|
||||||
|
|
||||||
|
* Makefile.in: Add py-block and py-symbol.
|
||||||
|
* gdb.python/py-symbol.exp: New File.
|
||||||
|
* gdb.python/py-symtab.exp: New File.
|
||||||
|
* gdb.python/py-block.exp: New File.
|
||||||
|
* gdb.python/py-symbol.c: New File.
|
||||||
|
* gdb.python/py-block.c: New File.
|
||||||
|
|
||||||
2010-02-24 Phil Muldoon <pmuldoon@redhat.com>
|
2010-02-24 Phil Muldoon <pmuldoon@redhat.com>
|
||||||
|
|
||||||
PR python/11314
|
PR python/11314
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
|
|
||||||
EXECUTABLES = py-type py-value py-prettyprint py-template
|
EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
|
||||||
|
py-symbol
|
||||||
|
|
||||||
all info install-info dvi install uninstall installcheck check:
|
all info install-info dvi install uninstall installcheck check:
|
||||||
@echo "Nothing to be done for $@..."
|
@echo "Nothing to be done for $@..."
|
||||||
|
|||||||
41
gdb/testsuite/gdb.python/py-block.c
Normal file
41
gdb/testsuite/gdb.python/py-block.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int block_func (void)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
{
|
||||||
|
double i = 1.0;
|
||||||
|
double f = 2.0;
|
||||||
|
{
|
||||||
|
const char *i = "stuff";
|
||||||
|
const char *f = "foo";
|
||||||
|
const char *b = "bar";
|
||||||
|
return 0; /* Block break here. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
block_func ();
|
||||||
|
return 0; /* Break at end. */
|
||||||
|
}
|
||||||
79
gdb/testsuite/gdb.python/py-block.exp
Normal file
79
gdb/testsuite/gdb.python/py-block.exp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
# This file is part of the GDB testsuite. It tests the mechanism
|
||||||
|
# exposing values to Python.
|
||||||
|
|
||||||
|
if $tracelevel then {
|
||||||
|
strace $tracelevel
|
||||||
|
}
|
||||||
|
|
||||||
|
set testfile "py-block"
|
||||||
|
set srcfile ${testfile}.c
|
||||||
|
set binfile ${objdir}/${subdir}/${testfile}
|
||||||
|
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||||
|
untested "Couldn't compile ${srcfile}"
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a command in GDB, and report a failure if a Python exception is thrown.
|
||||||
|
# If report_pass is true, report a pass if no exception is thrown.
|
||||||
|
proc gdb_py_test_silent_cmd {cmd name report_pass} {
|
||||||
|
global gdb_prompt
|
||||||
|
|
||||||
|
gdb_test_multiple $cmd $name {
|
||||||
|
-re "Traceback.*$gdb_prompt $" { fail $name }
|
||||||
|
-re "$gdb_prompt $" { if $report_pass { pass $name } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start with a fresh gdb.
|
||||||
|
gdb_exit
|
||||||
|
gdb_start
|
||||||
|
gdb_reinitialize_dir $srcdir/$subdir
|
||||||
|
gdb_load ${binfile}
|
||||||
|
|
||||||
|
# Skip all tests if Python scripting is not enabled.
|
||||||
|
if { [skip_python_tests] } { continue }
|
||||||
|
|
||||||
|
if ![runto_main] then {
|
||||||
|
fail "Can't run to main"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
global hex decimal
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Block break here."]
|
||||||
|
gdb_continue_to_breakpoint "Block break here."
|
||||||
|
|
||||||
|
# Test initial innermost block.
|
||||||
|
gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
|
||||||
|
gdb_py_test_silent_cmd "python block = frame.block()" "Get block" 0
|
||||||
|
gdb_test "python print block" "<gdb.Block object at $hex>" "Check block not None"
|
||||||
|
gdb_test "python print block.function" "None" "First anonymous block"
|
||||||
|
gdb_test "python print block.start" "${decimal}" "Check start not None"
|
||||||
|
gdb_test "python print block.end" "${decimal}" "Check end not None"
|
||||||
|
|
||||||
|
# Move up superblock(s) until we reach function block_func.
|
||||||
|
gdb_test "python block = block.superblock" "" "Get superblock"
|
||||||
|
gdb_test "python print block.function" "None" "Second anonymous block"
|
||||||
|
gdb_test "python block = block.superblock" "" "Get superblock"
|
||||||
|
gdb_test "python print block.function" "block_func"
|
||||||
|
|
||||||
|
# Switch frames, then test for main block.
|
||||||
|
gdb_test "up" ""
|
||||||
|
gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
|
||||||
|
gdb_py_test_silent_cmd "python block = frame.block()" "Get block" 0
|
||||||
|
gdb_test "python print block" "<gdb.Block object at $hex>" "Check block not None"
|
||||||
|
gdb_test "python print block.function" "main" "main block"
|
||||||
62
gdb/testsuite/gdb.python/py-symbol.c
Normal file
62
gdb/testsuite/gdb.python/py-symbol.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
class SimpleClass
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int i;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void seti (int arg)
|
||||||
|
{
|
||||||
|
i = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
int valueofi (void)
|
||||||
|
{
|
||||||
|
return i; /* Break in class. */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int func (int arg)
|
||||||
|
{
|
||||||
|
int i = 2;
|
||||||
|
i = i * arg;
|
||||||
|
return arg; /* Block break here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
#ifdef __cplusplus
|
||||||
|
SimpleClass sclass;
|
||||||
|
#endif
|
||||||
|
int a = 0;
|
||||||
|
int result;
|
||||||
|
enum tag {one, two, three};
|
||||||
|
enum tag t = one;
|
||||||
|
|
||||||
|
result = func (42);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
sclass.seti (42);
|
||||||
|
sclass.valueofi ();
|
||||||
|
#endif
|
||||||
|
return 0; /* Break at end. */
|
||||||
|
}
|
||||||
132
gdb/testsuite/gdb.python/py-symbol.exp
Normal file
132
gdb/testsuite/gdb.python/py-symbol.exp
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
# This file is part of the GDB testsuite. It tests the mechanism
|
||||||
|
# exposing values to Python.
|
||||||
|
|
||||||
|
if $tracelevel then {
|
||||||
|
strace $tracelevel
|
||||||
|
}
|
||||||
|
|
||||||
|
set testfile "py-symbol"
|
||||||
|
set srcfile ${testfile}.c
|
||||||
|
set binfile ${objdir}/${subdir}/${testfile}
|
||||||
|
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||||
|
untested "Couldn't compile ${srcfile}"
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a command in GDB, and report a failure if a Python exception is thrown.
|
||||||
|
# If report_pass is true, report a pass if no exception is thrown.
|
||||||
|
proc gdb_py_test_silent_cmd {cmd name report_pass} {
|
||||||
|
global gdb_prompt
|
||||||
|
|
||||||
|
gdb_test_multiple $cmd $name {
|
||||||
|
-re "Traceback.*$gdb_prompt $" { fail $name }
|
||||||
|
-re "$gdb_prompt $" { if $report_pass { pass $name } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start with a fresh gdb.
|
||||||
|
gdb_exit
|
||||||
|
gdb_start
|
||||||
|
gdb_reinitialize_dir $srcdir/$subdir
|
||||||
|
gdb_load ${binfile}
|
||||||
|
|
||||||
|
# Skip all tests if Python scripting is not enabled.
|
||||||
|
if { [skip_python_tests] } { continue }
|
||||||
|
|
||||||
|
if ![runto_main] then {
|
||||||
|
fail "Can't run to main"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
global hex decimal
|
||||||
|
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Block break here."]
|
||||||
|
gdb_continue_to_breakpoint "Block break here."
|
||||||
|
gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
|
||||||
|
gdb_py_test_silent_cmd "python block = frame.block()" "Get block" 0
|
||||||
|
|
||||||
|
# Test is_argument attribute.
|
||||||
|
gdb_py_test_silent_cmd "python arg = gdb.lookup_symbol(\"arg\")" "Get variable a" 0
|
||||||
|
gdb_test "python print arg\[0\].is_variable" "False" "Test arg.is_variable"
|
||||||
|
gdb_test "python print arg\[0\].is_constant" "False" "Test arg.is_constant"
|
||||||
|
gdb_test "python print arg\[0\].is_argument" "True" "Test arg.is_argument"
|
||||||
|
gdb_test "python print arg\[0\].is_function" "False" "Test arg.is_function"
|
||||||
|
|
||||||
|
# Test is_function attribute.
|
||||||
|
gdb_py_test_silent_cmd "python func = frame.block().function" "Get block" 0
|
||||||
|
gdb_test "python print func.is_variable" "False" "Test func.is_variable"
|
||||||
|
gdb_test "python print func.is_constant" "False" "Test func.is_constant"
|
||||||
|
gdb_test "python print func.is_argument" "False" "Test func.is_argument"
|
||||||
|
gdb_test "python print func.is_function" "True" "Test func.is_function"
|
||||||
|
gdb_test "python print func.name" "func" "Test func.name"
|
||||||
|
gdb_test "python print func.print_name" "func" "Test func.print_name"
|
||||||
|
gdb_test "python print func.linkage_name" "func" "Test func.linkage_name"
|
||||||
|
gdb_test "python print func.addr_class == gdb.SYMBOL_LOC_BLOCK" "True" "Test func.addr_class"
|
||||||
|
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Break at end."]
|
||||||
|
gdb_continue_to_breakpoint "Break at end."
|
||||||
|
gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
|
||||||
|
|
||||||
|
# Test is_variable attribute.
|
||||||
|
gdb_py_test_silent_cmd "python a = gdb.lookup_symbol(\'a\')" "Get variable a" 0
|
||||||
|
gdb_test "python print a\[0\].is_variable" "True" "Test a.is_variable"
|
||||||
|
gdb_test "python print a\[0\].is_constant" "False" "Test a.is_constant"
|
||||||
|
gdb_test "python print a\[0\].is_argument" "False" "Test a.is_argument"
|
||||||
|
gdb_test "python print a\[0\].is_function" "False" "Test a.is_function"
|
||||||
|
gdb_test "python print a\[0\].addr_class == gdb.SYMBOL_LOC_COMPUTED" "True" "Test a.addr_class"
|
||||||
|
|
||||||
|
# Test is_constant attribute
|
||||||
|
gdb_py_test_silent_cmd "python t = gdb.lookup_symbol(\"one\")" "Get variable a" 0
|
||||||
|
gdb_test "python print t\[0\].is_variable" "False" "Test t.is_variable"
|
||||||
|
gdb_test "python print t\[0\].is_constant" "True" "Test t.is_constant"
|
||||||
|
gdb_test "python print t\[0\].is_argument" "False" "Test t.is_argument"
|
||||||
|
gdb_test "python print t\[0\].is_function" "False" "Test t.is_function"
|
||||||
|
gdb_test "python print t\[0\].addr_class == gdb.SYMBOL_LOC_CONST" "True" "Test t.addr_class"
|
||||||
|
gdb_test "python print t\[0\].symtab" "gdb.python/py-symbol.c.*" "Get symtab"
|
||||||
|
|
||||||
|
# C++ tests
|
||||||
|
# Recompile binary.
|
||||||
|
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug c++"] != "" } {
|
||||||
|
untested "Couldn't compile ${srcfile} in c++ mode"
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start with a fresh gdb.
|
||||||
|
gdb_exit
|
||||||
|
gdb_start
|
||||||
|
gdb_reinitialize_dir $srcdir/$subdir
|
||||||
|
gdb_load ${binfile}
|
||||||
|
|
||||||
|
if ![runto_main] then {
|
||||||
|
fail "Can't run to main"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Break in class."]
|
||||||
|
gdb_continue_to_breakpoint "Break in class."
|
||||||
|
|
||||||
|
gdb_py_test_silent_cmd "python cplusframe = gdb.selected_frame()" "Get Frame" 0
|
||||||
|
gdb_py_test_silent_cmd "python cplusfunc = cplusframe.block().function" "Get block" 0
|
||||||
|
gdb_test "python print cplusfunc.is_variable" "False" "Test func.is_variable"
|
||||||
|
gdb_test "python print cplusfunc.is_constant" "False" "Test func.is_constant"
|
||||||
|
gdb_test "python print cplusfunc.is_argument" "False" "Test func.is_argument"
|
||||||
|
gdb_test "python print cplusfunc.is_function" "True" "Test func.is_function"
|
||||||
|
gdb_test "python print cplusfunc.name" "SimpleClass::valueofi().*" "Test func.name"
|
||||||
|
gdb_test "python print cplusfunc.print_name" "SimpleClass::valueofi().*" "Test func.print_name"
|
||||||
|
gdb_test "python print cplusfunc.linkage_name" "_ZN11SimpleClass8valueofiEv" "Test func.linkage_name"
|
||||||
|
gdb_test "python print cplusfunc.addr_class == gdb.SYMBOL_LOC_BLOCK" "True" "Test func.addr_class"
|
||||||
73
gdb/testsuite/gdb.python/py-symtab.exp
Normal file
73
gdb/testsuite/gdb.python/py-symtab.exp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
# This file is part of the GDB testsuite. It tests the mechanism
|
||||||
|
# exposing values to Python.
|
||||||
|
|
||||||
|
if $tracelevel then {
|
||||||
|
strace $tracelevel
|
||||||
|
}
|
||||||
|
|
||||||
|
set testfile "py-symbol"
|
||||||
|
set srcfile ${testfile}.c
|
||||||
|
set binfile ${objdir}/${subdir}/${testfile}
|
||||||
|
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||||
|
untested "Couldn't compile ${srcfile}"
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a command in GDB, and report a failure if a Python exception is thrown.
|
||||||
|
# If report_pass is true, report a pass if no exception is thrown.
|
||||||
|
proc gdb_py_test_silent_cmd {cmd name report_pass} {
|
||||||
|
global gdb_prompt
|
||||||
|
|
||||||
|
gdb_test_multiple $cmd $name {
|
||||||
|
-re "Traceback.*$gdb_prompt $" { fail $name }
|
||||||
|
-re "$gdb_prompt $" { if $report_pass { pass $name } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start with a fresh gdb.
|
||||||
|
gdb_exit
|
||||||
|
gdb_start
|
||||||
|
gdb_reinitialize_dir $srcdir/$subdir
|
||||||
|
gdb_load ${binfile}
|
||||||
|
|
||||||
|
# Skip all tests if Python scripting is not enabled.
|
||||||
|
if { [skip_python_tests] } { continue }
|
||||||
|
|
||||||
|
if ![runto_main] then {
|
||||||
|
fail "Can't run to main"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
global hex decimal
|
||||||
|
|
||||||
|
# Setup and get the symbol table.
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Block break here."]
|
||||||
|
gdb_continue_to_breakpoint "Block break here."
|
||||||
|
gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0
|
||||||
|
gdb_py_test_silent_cmd "python sal = frame.find_sal()" "Get block" 0
|
||||||
|
gdb_py_test_silent_cmd "python symtab = sal.symtab" "Get block" 0
|
||||||
|
|
||||||
|
# Test sal.
|
||||||
|
gdb_test "python print sal.symtab" "gdb/testsuite/gdb.python/py-symbol.c.*" "Test symtab"
|
||||||
|
gdb_test "python print sal.pc" "${decimal}" "Test sal.pc"
|
||||||
|
gdb_test "python print sal.line" "42" "Test sal.line"
|
||||||
|
|
||||||
|
# Test symbol table.
|
||||||
|
gdb_test "python print symtab.filename" "testsuite/gdb.python/py-symbol.c.*" "Test symtab.filename"
|
||||||
|
gdb_test "python print symtab.objfile" "<gdb.Objfile object at ${hex}>" "Test symtab.objfile"
|
||||||
|
gdb_test "python print symtab.fullname()" "testsuite/gdb.python/py-symbol.c.*" "Test symtab.fullname"
|
||||||
Reference in New Issue
Block a user