Extension Language API
* configure.ac (libpython checking): Remove all but python.o from CONFIG_OBS. Remove all but python.c from CONFIG_SRCS. * configure: Regenerate. * Makefile.in (SFILES): Add extension.c. (HFILES_NO_SRCDIR): Add extension.h, extension-priv.h (COMMON_OBS): Add extension.o. * extension.h: New file. * extension-priv.h: New file. * extension.c: New file. * python/python-internal.h: #include "extension.h". (gdbpy_auto_load_enabled): Declare. (gdbpy_apply_val_pretty_printer): Declare. (gdbpy_apply_frame_filter): Declare. (gdbpy_preserve_values): Declare. (gdbpy_breakpoint_cond_says_stop): Declare. (gdbpy_breakpoint_has_cond): Declare. (void source_python_script_for_objfile): Delete. * python/python.c: #include "extension-priv.h". Delete inclusion of "observer.h". (extension_language_python): Moved here and renamed from script_language_python in py-auto-load.c. Redefined to be of type extension_language_defn. (python_extension_script_ops): New global. (python_extension_ops): New global. (struct python_env): New member previous_active. (restore_python_env): Call restore_active_ext_lang. (ensure_python_env): Call set_active_ext_lang. (gdbpy_clear_quit_flag): Renamed from clear_quit_flag, made static. New arg extlang. (gdbpy_set_quit_flag): Renamed from set_quit_flag, made static. New arg extlang. (gdbpy_check_quit_flag): Renamed from check_quit_flag, made static. New arg extlang. (gdbpy_eval_from_control_command): Renamed from eval_python_from_control_command, made static. New arg extlang. (gdbpy_source_script) Renamed from source_python_script, made static. New arg extlang. (gdbpy_before_prompt_hook): Renamed from before_prompt_hook. Change result to int. New arg extlang. (gdbpy_source_objfile_script): Renamed from source_python_script_for_objfile, made static. New arg extlang. (gdbpy_start_type_printers): Renamed from start_type_printers, made static. New args extlang, extlang_printers. Change result type to "void". (gdbpy_apply_type_printers): Renamed from apply_type_printers, made static. New arg extlang. Rename arg printers to extlang_printers and change type to ext_lang_type_printers *. (gdbpy_free_type_printers): Renamed from free_type_printers, made static. Replace argument arg with extlang, extlang_printers. (!HAVE_PYTHON, eval_python_from_control_command): Delete. (!HAVE_PYTHON, source_python_script): Delete. (!HAVE_PYTHON, gdbpy_should_stop): Delete. (!HAVE_PYTHON, gdbpy_breakpoint_has_py_cond): Delete. (!HAVE_PYTHON, start_type_printers): Delete. (!HAVE_PYTHON, apply_type_printers): Delete. (!HAVE_PYTHON, free_type_printers): Delete. (_initialize_python): Delete call to observer_attach_before_prompt. (finalize_python): Set/restore active extension language. (gdbpy_finish_initialization) Renamed from finish_python_initialization, made static. New arg extlang. (gdbpy_initialized): New function. * python/python.h: #include "extension.h". Delete #include "value.h", "mi/mi-cmds.h". (extension_language_python): Declare. (GDBPY_AUTO_FILE_NAME): Delete. (enum py_bt_status): Moved to extension.h and renamed to ext_lang_bt_status. (enum frame_filter_flags): Moved to extension.h. (enum py_frame_args): Moved to extension.h and renamed to ext_lang_frame_args. (finish_python_initialization): Delete. (eval_python_from_control_command): Delete. (source_python_script): Delete. (apply_val_pretty_printer): Delete. (apply_frame_filter): Delete. (preserve_python_values): Delete. (gdbpy_script_language_defn): Delete. (gdbpy_should_stop, gdbpy_breakpoint_has_py_cond): Delete. (start_type_printers, apply_type_printers, free_type_printers): Delete. * auto-load.c: #include "extension.h". (GDB_AUTO_FILE_NAME): Delete. (auto_load_gdb_scripts_enabled): Make public. New arg extlang. (script_language_gdb): Delete, moved to extension.c and renamed to extension_language_gdb. (source_gdb_script_for_objfile): Delete. (auto_load_pspace_info): New member unsupported_script_warning_printed. (loaded_script): Change type of language member to struct extension_language_defn *. (init_loaded_scripts_info): Initialize unsupported_script_warning_printed. (maybe_add_script): Make static. Change type of language arg to struct extension_language_defn *. (clear_section_scripts): Reset unsupported_script_warning_printed. (auto_load_objfile_script_1): Rewrite to use extension language API. (auto_load_objfile_script): Make public. Remove support-compiled-in and auto-load-enabled checks, moved to auto_load_scripts_for_objfile. (source_section_scripts): Rewrite to use extension language API. (load_auto_scripts_for_objfile): Rewrite to use auto_load_scripts_for_objfile. (collect_matching_scripts_data): Change type of language member to struct extension_language_defn *. (auto_load_info_scripts): Change type of language arg to struct extension_language_defn *. (unsupported_script_warning_print): New function. (script_not_found_warning_print): Make static. (_initialize_auto_load): Rewrite construction of scripts-directory help. * auto-load.h (struct objfile): Add forward decl. (struct script_language): Delete. (struct auto_load_pspace_info): Add forward decl. (struct extension_language_defn): Add forward decl. (maybe_add_script): Delete. (auto_load_objfile_script): Declare. (script_not_found_warning_print): Delete. (auto_load_info_scripts): Update prototype. (auto_load_gdb_scripts_enabled): Declare. * python/py-auto-load.c (gdbpy_auto_load_enabled): Renamed from auto_load_python_scripts_enabled and made public. (script_language_python): Delete, moved to python.c. (gdbpy_script_language_defn): Delete. (info_auto_load_python_scripts): Update to use extension_language_python. * breakpoint.c (condition_command): Replace call to gdbpy_breakpoint_has_py_cond with call to get_breakpoint_cond_ext_lang. (bpstat_check_breakpoint_conditions): Replace call to gdbpy_should_stop with call to breakpoint_ext_lang_cond_says_stop. * python/py-breakpoint.c (gdbpy_breakpoint_cond_says_stop): Renamed from gdbpy_should_stop. Change result type to enum scr_bp_stop. New arg slang. Return SCR_BP_STOP_UNSET if py_bp_object is NULL. (gdbpy_breakpoint_has_cond): Renamed from gdbpy_breakpoint_has_py_cond. New arg slang. (local_setattro): Print name of extension language with existing stop condition. * valprint.c (val_print, value_print): Update to call apply_ext_lang_val_pretty_printer. * cp-valprint.c (cp_print_value): Update call to apply_ext_lang_val_pretty_printer. * python/py-prettyprint.c: Remove #ifdef HAVE_PYTHON. (gdbpy_apply_val_pretty_printer): Renamed from apply_val_pretty_printer. New arg extlang. (!HAVE_PYTHON, apply_val_pretty_printer): Delete. * cli/cli-cmds.c (source_script_from_stream): Rewrite to use extension language API. * cli/cli-script.c (execute_control_command): Update to call eval_ext_lang_from_control_command. * mi/mi-cmd-stack.c (mi_cmd_stack_list_frames): Update to use enum ext_lang_bt_status values. Update call to apply_ext_lang_frame_filter. (mi_cmd_stack_list_locals): Ditto. (mi_cmd_stack_list_args): Ditto. (mi_cmd_stack_list_variables): Ditto. * mi/mi-main.c: Delete #include "python/python-internal.h". Add #include "extension.h". (mi_cmd_list_features): Replace reference to python internal variable gdb_python_initialized with call to ext_lang_initialized_p. * stack.c (backtrace_command_1): Update to use enum ext_lang_bt_status. Update to use enum ext_lang_frame_args. Update to call apply_ext_lang_frame_filter. * python/py-framefilter.c (extract_sym): Update to use enum ext_lang_bt_status. (extract_value, py_print_type, py_print_value): Ditto. (py_print_single_arg, enumerate_args, enumerate_locals): Ditto. (py_mi_print_variables, py_print_locals, py_print_args): Ditto. (py_print_frame): Ditto. (gdbpy_apply_frame_filter): Renamed from apply_frame_filter. New arg extlang. Update to use enum ext_lang_bt_status. * top.c (gdb_init): Delete #ifdef HAVE_PYTHON call to finish_python_initialization. Replace with call to finish_ext_lang_initialization. * typeprint.c (do_free_global_table): Update to call free_ext_lang_type_printers. (create_global_typedef_table): Update to call start_ext_lang_type_printers. (find_global_typedef): Update to call apply_ext_lang_type_printers. * typeprint.h (struct ext_lang_type_printers): Add forward decl. (type_print_options): Change type of global_printers from "void *" to "struct ext_lang_type_printers *". * value.c (preserve_values): Update to call preserve_ext_lang_values. * python/py-value.c: Remove #ifdef HAVE_PYTHON. (gdbpy_preserve_values): Renamed from preserve_python_values. New arg extlang. (!HAVE_PYTHON, preserve_python_values): Delete. * utils.c (quit_flag): Delete, moved to extension.c. (clear_quit_flag, set_quit_flag, check_quit_flag): Delete, moved to extension.c. * eval.c: Delete #include "python/python.h". * main.c: Delete #include "python/python.h". * defs.h: Update comment. testsuite/ * gdb.python/py-breakpoint.exp (test_bkpt_eval_funcs): Update expected output. * gdb.gdb/python-interrupts.exp: New file.
This commit is contained in:
parent
6af7998535
commit
6dddc817c1
36 changed files with 2285 additions and 718 deletions
285
gdb/extension-priv.h
Normal file
285
gdb/extension-priv.h
Normal file
|
@ -0,0 +1,285 @@
|
|||
/* Private implementation details of interface between gdb and its
|
||||
extension languages.
|
||||
|
||||
Copyright (C) 2013 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/>. */
|
||||
|
||||
#ifndef EXTENSION_PRIV_H
|
||||
#define EXTENSION_PRIV_H
|
||||
|
||||
#include "extension.h"
|
||||
|
||||
/* The return code for some API calls. */
|
||||
|
||||
enum ext_lang_rc
|
||||
{
|
||||
/* The operation completed successfully. */
|
||||
EXT_LANG_RC_OK,
|
||||
|
||||
/* The operation was not performed (e.g., no pretty-printer). */
|
||||
EXT_LANG_RC_NOP,
|
||||
|
||||
/* There was an error (e.g., Python error while printing a value).
|
||||
When an error occurs no further extension languages are tried.
|
||||
This is to preserve existing behaviour, and because it's convenient
|
||||
for Python developers.
|
||||
Note: This is different than encountering a memory error trying to read
|
||||
a value for pretty-printing. Here we're referring to, e.g., programming
|
||||
errors that trigger an exception in the extension language. */
|
||||
EXT_LANG_RC_ERROR
|
||||
};
|
||||
|
||||
/* High level description of an extension/scripting language.
|
||||
An entry for each is compiled into GDB regardless of whether the support
|
||||
is present. This is done so that we can issue meaningful errors if the
|
||||
support is not compiled in. */
|
||||
|
||||
struct extension_language_defn
|
||||
{
|
||||
/* Enum of the extension language. */
|
||||
enum extension_language language;
|
||||
|
||||
/* The name of the extension language, lowercase. E.g., python. */
|
||||
const char *name;
|
||||
|
||||
/* The capitalized name of the extension language.
|
||||
For python this is "Python". For gdb this is "GDB". */
|
||||
const char *capitalized_name;
|
||||
|
||||
/* The file suffix of this extension language. E.g., ".py". */
|
||||
const char *suffix;
|
||||
|
||||
/* The suffix of per-objfile scripts to auto-load.
|
||||
E.g., When the program loads libfoo.so, look for libfoo.so-gdb.py. */
|
||||
const char *auto_load_suffix;
|
||||
|
||||
/* We support embedding external extension language code in GDB's own
|
||||
scripting language. We do this by having a special command that begins
|
||||
the extension language snippet, and terminate it with "end".
|
||||
This specifies the control type used to implement this. */
|
||||
enum command_control_type cli_control_type;
|
||||
|
||||
/* A pointer to the "methods" to load scripts in this language,
|
||||
or NULL if the support is not compiled into GDB. */
|
||||
const struct extension_language_script_ops *script_ops;
|
||||
|
||||
/* Either a pointer to the "methods" of the extension language interface
|
||||
or NULL if the support is not compiled into GDB.
|
||||
This is also NULL for GDB's own scripting language which is relatively
|
||||
primitive, and doesn't provide these features. */
|
||||
const struct extension_language_ops *ops;
|
||||
};
|
||||
|
||||
/* The interface for loading scripts from external extension languages,
|
||||
as well as GDB's own scripting language.
|
||||
All of these methods are required to be implemented. */
|
||||
|
||||
struct extension_language_script_ops
|
||||
{
|
||||
/* Load a script. This is called, e.g., via the "source" command.
|
||||
If there's an error while processing the script this function may,
|
||||
but is not required to, throw an error. */
|
||||
script_sourcer_func *script_sourcer;
|
||||
|
||||
/* Load a script attached to an objfile.
|
||||
If there's an error while processing the script this function may,
|
||||
but is not required to, throw an error. */
|
||||
objfile_script_sourcer_func *objfile_script_sourcer;
|
||||
|
||||
/* Return non-zero if auto-loading scripts in this extension language
|
||||
is enabled. */
|
||||
int (*auto_load_enabled) (const struct extension_language_defn *);
|
||||
};
|
||||
|
||||
/* The interface for making calls from GDB to an external extension
|
||||
language. This is for non-script-loading related functionality, like
|
||||
pretty-printing, etc. The reason these are separated out is GDB's own
|
||||
scripting language makes use of extension_language_script_opts, but it
|
||||
makes no use of these. There is no (current) intention to split
|
||||
extension_language_ops up any further.
|
||||
All of these methods are optional and may be NULL, except where
|
||||
otherwise indicated. */
|
||||
|
||||
struct extension_language_ops
|
||||
{
|
||||
/* Called at the end of gdb initialization to give the extension language
|
||||
an opportunity to finish up. This is useful for things like adding
|
||||
new commands where one has to wait until gdb itself is initialized. */
|
||||
void (*finish_initialization) (const struct extension_language_defn *);
|
||||
|
||||
/* Return non-zero if the extension language successfully initialized.
|
||||
This method is required. */
|
||||
int (*initialized) (const struct extension_language_defn *);
|
||||
|
||||
/* Process a sequence of commands embedded in GDB's own scripting language.
|
||||
E.g.,
|
||||
python
|
||||
print 42
|
||||
end */
|
||||
void (*eval_from_control_command) (const struct extension_language_defn *,
|
||||
struct command_line *);
|
||||
|
||||
/* Type-printing support:
|
||||
start_type_printers, apply_type_printers, free_type_printers.
|
||||
These methods are optional and may be NULL, but if one of them is
|
||||
implemented then they all must be. */
|
||||
|
||||
/* Called before printing a type. */
|
||||
void (*start_type_printers) (const struct extension_language_defn *,
|
||||
struct ext_lang_type_printers *);
|
||||
|
||||
/* Try to pretty-print TYPE. If successful the pretty-printed type is
|
||||
stored in *PRETTIED_TYPE, and the caller must free it.
|
||||
Returns EXT_LANG_RC_OK upon success, EXT_LANG_RC_NOP if the type
|
||||
is not recognized, and EXT_LANG_RC_ERROR if an error was encountered.
|
||||
This function has a bit of a funny name, since it actually applies
|
||||
recognizers, but this seemed clearer given the start_type_printers
|
||||
and free_type_printers functions. */
|
||||
enum ext_lang_rc (*apply_type_printers)
|
||||
(const struct extension_language_defn *,
|
||||
const struct ext_lang_type_printers *,
|
||||
struct type *, char **prettied_type);
|
||||
|
||||
/* Called after a type has been printed to give the type pretty-printer
|
||||
mechanism an opportunity to clean up. */
|
||||
void (*free_type_printers) (const struct extension_language_defn *,
|
||||
struct ext_lang_type_printers *);
|
||||
|
||||
/* Try to pretty-print a value of type TYPE located at VALADDR
|
||||
+ EMBEDDED_OFFSET, which came from the inferior at address ADDRESS
|
||||
+ EMBEDDED_OFFSET, onto stdio stream STREAM according to OPTIONS.
|
||||
VAL is the whole object that came from ADDRESS. VALADDR must point to
|
||||
the head of VAL's contents buffer.
|
||||
Returns EXT_LANG_RC_OK upon success, EXT_LANG_RC_NOP if the value
|
||||
is not recognized, and EXT_LANG_RC_ERROR if an error was encountered. */
|
||||
enum ext_lang_rc (*apply_val_pretty_printer)
|
||||
(const struct extension_language_defn *,
|
||||
struct type *type, const gdb_byte *valaddr,
|
||||
int embedded_offset, CORE_ADDR address,
|
||||
struct ui_file *stream, int recurse,
|
||||
const struct value *val, const struct value_print_options *options,
|
||||
const struct language_defn *language);
|
||||
|
||||
/* GDB access to the "frame filter" feature.
|
||||
FRAME is the source frame to start frame-filter invocation. FLAGS is an
|
||||
integer holding the flags for printing. The following elements of
|
||||
the FRAME_FILTER_FLAGS enum denotes the make-up of FLAGS:
|
||||
PRINT_LEVEL is a flag indicating whether to print the frame's
|
||||
relative level in the output. PRINT_FRAME_INFO is a flag that
|
||||
indicates whether this function should print the frame
|
||||
information, PRINT_ARGS is a flag that indicates whether to print
|
||||
frame arguments, and PRINT_LOCALS, likewise, with frame local
|
||||
variables. ARGS_TYPE is an enumerator describing the argument
|
||||
format, OUT is the output stream to print. FRAME_LOW is the
|
||||
beginning of the slice of frames to print, and FRAME_HIGH is the
|
||||
upper limit of the frames to count. Returns SCR_BT_ERROR on error,
|
||||
or SCR_BT_COMPLETED on success. */
|
||||
enum ext_lang_bt_status (*apply_frame_filter)
|
||||
(const struct extension_language_defn *,
|
||||
struct frame_info *frame, int flags, enum ext_lang_frame_args args_type,
|
||||
struct ui_out *out, int frame_low, int frame_high);
|
||||
|
||||
/* Update values held by the extension language when OBJFILE is discarded.
|
||||
New global types must be created for every such value, which must then be
|
||||
updated to use the new types.
|
||||
This function typically just iterates over all appropriate values and
|
||||
calls preserve_one_value for each one.
|
||||
COPIED_TYPES is used to prevent cycles / duplicates and is passed to
|
||||
preserve_one_value. */
|
||||
void (*preserve_values) (const struct extension_language_defn *,
|
||||
struct objfile *objfile, htab_t copied_types);
|
||||
|
||||
/* Return non-zero if there is a stop condition for the breakpoint.
|
||||
This is used to implement the restriction that a breakpoint may have
|
||||
at most one condition. */
|
||||
int (*breakpoint_has_cond) (const struct extension_language_defn *,
|
||||
struct breakpoint *);
|
||||
|
||||
/* Return a value of enum ext_lang_bp_stop indicating if there is a stop
|
||||
condition for the breakpoint, and if so whether the program should
|
||||
stop. This is called when the program has stopped at the specified
|
||||
breakpoint.
|
||||
While breakpoints can have at most one condition, this is called for
|
||||
every extension language, even if another extension language has a
|
||||
"stop" method: other kinds of breakpoints may be implemented using
|
||||
this method, e.g., "finish breakpoints" in Python. */
|
||||
enum ext_lang_bp_stop (*breakpoint_cond_says_stop)
|
||||
(const struct extension_language_defn *, struct breakpoint *);
|
||||
|
||||
/* The next three are used to connect GDB's SIGINT handling with the
|
||||
extension language's.
|
||||
|
||||
Terminology: If an extension language can use GDB's SIGINT handling then
|
||||
we say the extension language has "cooperative SIGINT handling".
|
||||
Python is an example of this.
|
||||
|
||||
These need not be implemented, but if one of them is implemented
|
||||
then they all must be. */
|
||||
|
||||
/* Clear the SIGINT indicator. */
|
||||
void (*clear_quit_flag) (const struct extension_language_defn *);
|
||||
|
||||
/* Set the SIGINT indicator.
|
||||
This is called by GDB's SIGINT handler and must be async-safe. */
|
||||
void (*set_quit_flag) (const struct extension_language_defn *);
|
||||
|
||||
/* Return non-zero if a SIGINT has occurred.
|
||||
This is expected to also clear the indicator. */
|
||||
int (*check_quit_flag) (const struct extension_language_defn *);
|
||||
|
||||
/* Called before gdb prints its prompt, giving extension languages an
|
||||
opportunity to change it with set_prompt.
|
||||
Returns EXT_LANG_RC_OK if the prompt was changed, EXT_LANG_RC_NOP if
|
||||
the prompt was not changed, and EXT_LANG_RC_ERROR if an error was
|
||||
encountered.
|
||||
Extension languages are called in order, and once the prompt is
|
||||
changed or an error occurs no further languages are called. */
|
||||
enum ext_lang_rc (*before_prompt) (const struct extension_language_defn *,
|
||||
const char *current_gdb_prompt);
|
||||
};
|
||||
|
||||
/* State necessary to restore a signal handler to its previous value. */
|
||||
|
||||
struct signal_handler
|
||||
{
|
||||
/* Non-zero if "handler" has been set. */
|
||||
int handler_saved;
|
||||
|
||||
/* The signal handler. */
|
||||
RETSIGTYPE (*handler) ();
|
||||
};
|
||||
|
||||
/* State necessary to restore the currently active extension language
|
||||
to is previous value. */
|
||||
|
||||
struct active_ext_lang_state
|
||||
{
|
||||
/* The previously active extension language. */
|
||||
const struct extension_language_defn *ext_lang;
|
||||
|
||||
/* Its SIGINT handler. */
|
||||
struct signal_handler sigint_handler;
|
||||
};
|
||||
|
||||
extern const struct extension_language_defn *get_active_ext_lang (void);
|
||||
|
||||
extern struct active_ext_lang_state *set_active_ext_lang
|
||||
(const struct extension_language_defn *);
|
||||
|
||||
extern void restore_active_ext_lang (struct active_ext_lang_state *previous);
|
||||
|
||||
#endif /* EXTENSION_PRIV_H */
|
Loading…
Add table
Add a link
Reference in a new issue