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
205
gdb/ChangeLog
205
gdb/ChangeLog
|
@ -1,3 +1,208 @@
|
|||
2014-02-06 Doug Evans <xdje42@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2014-02-06 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 7.7 released.
|
||||
|
|
|
@ -739,7 +739,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
|
|||
dwarf2expr.c dwarf2loc.c dwarf2read.c dwarf2-frame.c \
|
||||
dwarf2-frame-tailcall.c \
|
||||
elfread.c environ.c eval.c event-loop.c event-top.c \
|
||||
exceptions.c expprint.c \
|
||||
exceptions.c expprint.c extension.c \
|
||||
f-exp.y f-lang.c f-typeprint.c f-valprint.c filesystem.c \
|
||||
findcmd.c findvar.c frame.c frame-base.c frame-unwind.c \
|
||||
gdbarch.c arch-utils.c gdb_bfd.c gdb_obstack.c \
|
||||
|
@ -826,6 +826,7 @@ tui/tui-windata.h tui/tui-data.h tui/tui-win.h tui/tui-stack.h \
|
|||
tui/tui-winsource.h tui/tui-regs.h tui/tui-io.h tui/tui-layout.h \
|
||||
tui/tui-source.h sol2-tdep.h gregset.h sh-tdep.h sh64-tdep.h \
|
||||
expression.h score-tdep.h gdb_select.h ser-tcp.h \
|
||||
extension.h extension-priv.h \
|
||||
build-id.h buildsym.h valprint.h \
|
||||
typeprint.h mi/mi-getopt.h mi/mi-parse.h mi/mi-console.h \
|
||||
mi/mi-out.h mi/mi-main.h mi/mi-common.h mi/mi-cmds.h linux-nat.h \
|
||||
|
@ -912,6 +913,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
|
|||
infcmd.o infrun.o \
|
||||
expprint.o environ.o stack.o thread.o \
|
||||
exceptions.o \
|
||||
extension.o \
|
||||
filesystem.o \
|
||||
filestuff.o \
|
||||
inf-child.o \
|
||||
|
|
210
gdb/auto-load.c
210
gdb/auto-load.c
|
@ -20,7 +20,6 @@
|
|||
#include "defs.h"
|
||||
#include "auto-load.h"
|
||||
#include "progspace.h"
|
||||
#include "python/python.h"
|
||||
#include "gdb_regex.h"
|
||||
#include "ui-out.h"
|
||||
#include "filenames.h"
|
||||
|
@ -39,6 +38,8 @@
|
|||
#include "fnmatch.h"
|
||||
#include "top.h"
|
||||
#include "filestuff.h"
|
||||
#include "extension.h"
|
||||
#include "python/python.h"
|
||||
|
||||
/* The section to look in for auto-loaded scripts (in file formats that
|
||||
support sections).
|
||||
|
@ -48,12 +49,14 @@
|
|||
followed by the path of a python script to load. */
|
||||
#define AUTO_SECTION_NAME ".debug_gdb_scripts"
|
||||
|
||||
/* The suffix of per-objfile scripts to auto-load as non-Python command files.
|
||||
E.g. When the program loads libfoo.so, look for libfoo-gdb.gdb. */
|
||||
#define GDB_AUTO_FILE_NAME "-gdb.gdb"
|
||||
static int maybe_add_script (struct auto_load_pspace_info *pspace_info,
|
||||
int loaded, const char *name,
|
||||
const char *full_path,
|
||||
const struct extension_language_defn *language);
|
||||
|
||||
static void source_gdb_script_for_objfile (struct objfile *objfile, FILE *file,
|
||||
const char *filename);
|
||||
static int unsupported_script_warning_print (struct auto_load_pspace_info *);
|
||||
|
||||
static int script_not_found_warning_print (struct auto_load_pspace_info *);
|
||||
|
||||
/* Value of the 'set debug auto-load' configuration variable. */
|
||||
static int debug_auto_load = 0;
|
||||
|
@ -89,8 +92,8 @@ show_auto_load_gdb_scripts (struct ui_file *file, int from_tty,
|
|||
|
||||
/* Return non-zero if auto-loading gdb scripts is enabled. */
|
||||
|
||||
static int
|
||||
auto_load_gdb_scripts_enabled (void)
|
||||
int
|
||||
auto_load_gdb_scripts_enabled (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return auto_load_gdb_scripts;
|
||||
}
|
||||
|
@ -516,29 +519,6 @@ For more information about this security protection see the\n\
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Definition of script language for GDB canned sequences of commands. */
|
||||
|
||||
static const struct script_language script_language_gdb =
|
||||
{
|
||||
"gdb",
|
||||
GDB_AUTO_FILE_NAME,
|
||||
auto_load_gdb_scripts_enabled,
|
||||
source_gdb_script_for_objfile
|
||||
};
|
||||
|
||||
static void
|
||||
source_gdb_script_for_objfile (struct objfile *objfile, FILE *file,
|
||||
const char *filename)
|
||||
{
|
||||
volatile struct gdb_exception e;
|
||||
|
||||
TRY_CATCH (e, RETURN_MASK_ALL)
|
||||
{
|
||||
script_from_file (file, filename);
|
||||
}
|
||||
exception_print (gdb_stderr, e);
|
||||
}
|
||||
|
||||
/* For scripts specified in .debug_gdb_scripts, multiple objfiles may load
|
||||
the same script. There's no point in loading the script multiple times,
|
||||
and there can be a lot of objfiles and scripts, so we keep track of scripts
|
||||
|
@ -549,6 +529,10 @@ struct auto_load_pspace_info
|
|||
/* For each program space we keep track of loaded scripts. */
|
||||
struct htab *loaded_scripts;
|
||||
|
||||
/* Non-zero if we've issued the warning about an auto-load script not being
|
||||
supported. We only want to issue this warning once. */
|
||||
int unsupported_script_warning_printed;
|
||||
|
||||
/* Non-zero if we've issued the warning about an auto-load script not being
|
||||
found. We only want to issue this warning once. */
|
||||
int script_not_found_warning_printed;
|
||||
|
@ -568,7 +552,7 @@ struct loaded_script
|
|||
/* Non-zero if this script has been loaded. */
|
||||
int loaded;
|
||||
|
||||
const struct script_language *language;
|
||||
const struct extension_language_defn *language;
|
||||
};
|
||||
|
||||
/* Per-program-space data key. */
|
||||
|
@ -638,6 +622,7 @@ init_loaded_scripts_info (struct auto_load_pspace_info *pspace_info)
|
|||
eq_loaded_script_entry,
|
||||
xfree);
|
||||
|
||||
pspace_info->unsupported_script_warning_printed = FALSE;
|
||||
pspace_info->script_not_found_warning_printed = FALSE;
|
||||
}
|
||||
|
||||
|
@ -661,10 +646,10 @@ get_auto_load_pspace_data_for_loading (struct program_space *pspace)
|
|||
been found). FULL_PATH is NULL if the script wasn't found. The result is
|
||||
true if the script was already in the hash table. */
|
||||
|
||||
int
|
||||
static int
|
||||
maybe_add_script (struct auto_load_pspace_info *pspace_info, int loaded,
|
||||
const char *name, const char *full_path,
|
||||
const struct script_language *language)
|
||||
const struct extension_language_defn *language)
|
||||
{
|
||||
struct htab *htab = pspace_info->loaded_scripts;
|
||||
struct loaded_script **slot, entry;
|
||||
|
@ -716,6 +701,7 @@ clear_section_scripts (void)
|
|||
{
|
||||
htab_delete (info->loaded_scripts);
|
||||
info->loaded_scripts = NULL;
|
||||
info->unsupported_script_warning_printed = FALSE;
|
||||
info->script_not_found_warning_printed = FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -726,17 +712,18 @@ clear_section_scripts (void)
|
|||
|
||||
static int
|
||||
auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
|
||||
const struct script_language *language)
|
||||
const struct extension_language_defn *language)
|
||||
{
|
||||
char *filename, *debugfile;
|
||||
int len, retval;
|
||||
FILE *input;
|
||||
struct cleanup *cleanups;
|
||||
const char *suffix = ext_lang_auto_load_suffix (language);
|
||||
|
||||
len = strlen (realname);
|
||||
filename = xmalloc (len + strlen (language->suffix) + 1);
|
||||
filename = xmalloc (len + strlen (suffix) + 1);
|
||||
memcpy (filename, realname, len);
|
||||
strcpy (filename + len, language->suffix);
|
||||
strcpy (filename + len, suffix);
|
||||
|
||||
cleanups = make_cleanup (xfree, filename);
|
||||
|
||||
|
@ -794,8 +781,8 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
|
|||
= file_is_auto_load_safe (filename,
|
||||
_("auto-load: Loading %s script \"%s\""
|
||||
" by extension for objfile \"%s\".\n"),
|
||||
language->name, filename,
|
||||
objfile_name (objfile));
|
||||
ext_lang_name (language),
|
||||
filename, objfile_name (objfile));
|
||||
|
||||
/* Add this script to the hash table too so
|
||||
"info auto-load ${lang}-scripts" can print it. */
|
||||
|
@ -809,7 +796,16 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
|
|||
and these scripts are required to be idempotent under multiple
|
||||
loads anyway. */
|
||||
if (is_safe)
|
||||
language->source_script_for_objfile (objfile, input, debugfile);
|
||||
{
|
||||
objfile_script_sourcer_func *sourcer
|
||||
= ext_lang_objfile_script_sourcer (language);
|
||||
|
||||
/* We shouldn't get here if support for the language isn't
|
||||
compiled in. And the extension language is required to implement
|
||||
this function. */
|
||||
gdb_assert (sourcer != NULL);
|
||||
sourcer (language, objfile, input, debugfile);
|
||||
}
|
||||
|
||||
retval = 1;
|
||||
}
|
||||
|
@ -823,21 +819,12 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
|
|||
/* Look for the auto-load script in LANGUAGE associated with OBJFILE and load
|
||||
it. */
|
||||
|
||||
static void
|
||||
void
|
||||
auto_load_objfile_script (struct objfile *objfile,
|
||||
const struct script_language *language)
|
||||
const struct extension_language_defn *language)
|
||||
{
|
||||
char *realname;
|
||||
struct cleanup *cleanups;
|
||||
|
||||
/* Skip this script if support has not been compiled in or
|
||||
auto-loading it has been disabled. */
|
||||
if (language == NULL
|
||||
|| !language->auto_load_enabled ())
|
||||
return;
|
||||
|
||||
realname = gdb_realpath (objfile_name (objfile));
|
||||
cleanups = make_cleanup (xfree, realname);
|
||||
char *realname = gdb_realpath (objfile_name (objfile));
|
||||
struct cleanup *cleanups = make_cleanup (xfree, realname);
|
||||
|
||||
if (!auto_load_objfile_script_1 (objfile, realname, language))
|
||||
{
|
||||
|
@ -892,7 +879,9 @@ source_section_scripts (struct objfile *objfile, const char *section_name,
|
|||
struct cleanup *back_to;
|
||||
/* At the moment we only support python scripts in .debug_gdb_scripts,
|
||||
but that can change. */
|
||||
const struct script_language *language = gdbpy_script_language_defn ();
|
||||
const struct extension_language_defn *language
|
||||
= &extension_language_python;
|
||||
objfile_script_sourcer_func *sourcer;
|
||||
|
||||
if (*p != 1)
|
||||
{
|
||||
|
@ -922,10 +911,34 @@ source_section_scripts (struct objfile *objfile, const char *section_name,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Skip this script if support has not been compiled in or
|
||||
auto-loading it has been disabled. */
|
||||
if (language == NULL
|
||||
|| !language->auto_load_enabled ())
|
||||
/* Until we support more types of records in .debug_gdb_scripts we do
|
||||
all the processing here. The expectation is to add a new
|
||||
extension_language_script_ops "method" that handles all the records
|
||||
for the language. For now we can just use
|
||||
extension_language_script_ops.objfile_script_sourcer. */
|
||||
|
||||
/* Skip this script if support is not compiled in. */
|
||||
sourcer = ext_lang_objfile_script_sourcer (language);
|
||||
if (sourcer == NULL)
|
||||
{
|
||||
/* We don't throw an error, the program is still debuggable. */
|
||||
if (!unsupported_script_warning_print (pspace_info))
|
||||
{
|
||||
warning (_("Unsupported auto-load scripts referenced in"
|
||||
" %s section\n"
|
||||
"of file %s.\n"
|
||||
"Use `info auto-load %s-scripts [REGEXP]'"
|
||||
" to list them."),
|
||||
section_name, objfile_name (objfile),
|
||||
ext_lang_name (language));
|
||||
}
|
||||
/* We *could* still try to open it, but there's no point. */
|
||||
maybe_add_script (pspace_info, 0, file, NULL, language);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip this script if auto-loading it has been disabled. */
|
||||
if (!ext_lang_auto_load_enabled (language))
|
||||
{
|
||||
/* No message is printed, just skip it. */
|
||||
continue;
|
||||
|
@ -944,8 +957,8 @@ source_section_scripts (struct objfile *objfile, const char *section_name,
|
|||
_("auto-load: Loading %s script "
|
||||
"\"%s\" from section \"%s\" of "
|
||||
"objfile \"%s\".\n"),
|
||||
language->name, full_path, section_name,
|
||||
objfile_name (objfile)))
|
||||
ext_lang_name (language), full_path,
|
||||
section_name, objfile_name (objfile)))
|
||||
opened = 0;
|
||||
}
|
||||
else
|
||||
|
@ -964,7 +977,8 @@ source_section_scripts (struct objfile *objfile, const char *section_name,
|
|||
warning (_("Missing auto-load scripts referenced in section %s\n\
|
||||
of file %s\n\
|
||||
Use `info auto-load %s-scripts [REGEXP]' to list them."),
|
||||
section_name, objfile_name (objfile), language->name);
|
||||
section_name, objfile_name (objfile),
|
||||
ext_lang_name (language));
|
||||
}
|
||||
|
||||
in_hash_table = maybe_add_script (pspace_info, opened, file, full_path,
|
||||
|
@ -972,10 +986,7 @@ Use `info auto-load %s-scripts [REGEXP]' to list them."),
|
|||
|
||||
/* If this file is not currently loaded, load it. */
|
||||
if (opened && !in_hash_table)
|
||||
{
|
||||
gdb_assert (language->source_script_for_objfile != NULL);
|
||||
language->source_script_for_objfile (objfile, stream, full_path);
|
||||
}
|
||||
sourcer (language, objfile, stream, full_path);
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
@ -1020,9 +1031,9 @@ load_auto_scripts_for_objfile (struct objfile *objfile)
|
|||
if (!global_auto_load || (objfile->flags & OBJF_NOT_FILENAME) != 0)
|
||||
return;
|
||||
|
||||
/* Load any scripts for this objfile. e.g. foo-gdb.gdb, foo-gdb.py. */
|
||||
auto_load_objfile_script (objfile, &script_language_gdb);
|
||||
auto_load_objfile_script (objfile, gdbpy_script_language_defn ());
|
||||
/* Load any extension language scripts for this objfile.
|
||||
E.g., foo-gdb.gdb, foo-gdb.py. */
|
||||
auto_load_ext_lang_scripts_for_objfile (objfile);
|
||||
|
||||
/* Load any scripts mentioned in AUTO_SECTION_NAME (.debug_gdb_scripts). */
|
||||
auto_load_section_scripts (objfile, AUTO_SECTION_NAME);
|
||||
|
@ -1056,7 +1067,7 @@ struct collect_matching_scripts_data
|
|||
{
|
||||
VEC (loaded_script_ptr) **scripts_p;
|
||||
|
||||
const struct script_language *language;
|
||||
const struct extension_language_defn *language;
|
||||
};
|
||||
|
||||
/* Traversal function for htab_traverse.
|
||||
|
@ -1122,7 +1133,7 @@ char auto_load_info_scripts_pattern_nl[] = "";
|
|||
|
||||
void
|
||||
auto_load_info_scripts (char *pattern, int from_tty,
|
||||
const struct script_language *language)
|
||||
const struct extension_language_defn *language)
|
||||
{
|
||||
struct ui_out *uiout = current_uiout;
|
||||
struct auto_load_pspace_info *pspace_info;
|
||||
|
@ -1205,7 +1216,7 @@ auto_load_info_scripts (char *pattern, int from_tty,
|
|||
static void
|
||||
info_auto_load_gdb_scripts (char *pattern, int from_tty)
|
||||
{
|
||||
auto_load_info_scripts (pattern, from_tty, &script_language_gdb);
|
||||
auto_load_info_scripts (pattern, from_tty, &extension_language_gdb);
|
||||
}
|
||||
|
||||
/* Implement 'info auto-load local-gdbinit'. */
|
||||
|
@ -1223,11 +1234,25 @@ info_auto_load_local_gdbinit (char *args, int from_tty)
|
|||
auto_load_local_gdbinit_pathname);
|
||||
}
|
||||
|
||||
/* Return non-zero if UNSUPPORTED_SCRIPT_WARNING_PRINTED of PSPACE_INFO was
|
||||
unset before calling this function. Always set
|
||||
UNSUPPORTED_SCRIPT_WARNING_PRINTED of PSPACE_INFO. */
|
||||
|
||||
static int
|
||||
unsupported_script_warning_print (struct auto_load_pspace_info *pspace_info)
|
||||
{
|
||||
int retval = !pspace_info->unsupported_script_warning_printed;
|
||||
|
||||
pspace_info->unsupported_script_warning_printed = 1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Return non-zero if SCRIPT_NOT_FOUND_WARNING_PRINTED of PSPACE_INFO was unset
|
||||
before calling this function. Always set SCRIPT_NOT_FOUND_WARNING_PRINTED
|
||||
of PSPACE_INFO. */
|
||||
|
||||
int
|
||||
static int
|
||||
script_not_found_warning_print (struct auto_load_pspace_info *pspace_info)
|
||||
{
|
||||
int retval = !pspace_info->script_not_found_warning_printed;
|
||||
|
@ -1369,7 +1394,7 @@ void
|
|||
_initialize_auto_load (void)
|
||||
{
|
||||
struct cmd_list_element *cmd;
|
||||
char *scripts_directory_help;
|
||||
char *scripts_directory_help, *gdb_name_help, *python_name_help;
|
||||
|
||||
auto_load_pspace_data
|
||||
= register_program_space_data_with_cleanup (NULL,
|
||||
|
@ -1413,27 +1438,34 @@ Usage: info auto-load local-gdbinit"),
|
|||
auto_load_info_cmdlist_get ());
|
||||
|
||||
auto_load_dir = xstrdup (AUTO_LOAD_DIR);
|
||||
scripts_directory_help = xstrprintf (
|
||||
|
||||
gdb_name_help
|
||||
= xstrprintf (_("\
|
||||
GDB scripts: OBJFILE%s\n"),
|
||||
ext_lang_auto_load_suffix (&extension_language_gdb));
|
||||
python_name_help = NULL;
|
||||
#ifdef HAVE_PYTHON
|
||||
_("\
|
||||
Automatically loaded Python scripts (named OBJFILE%s) and GDB scripts\n\
|
||||
(named OBJFILE%s) are located in one of the directories listed by this\n\
|
||||
option.\n\
|
||||
%s"),
|
||||
GDBPY_AUTO_FILE_NAME,
|
||||
#else
|
||||
_("\
|
||||
Automatically loaded GDB scripts (named OBJFILE%s) are located in one\n\
|
||||
of the directories listed by this option.\n\
|
||||
%s"),
|
||||
python_name_help
|
||||
= xstrprintf (_("\
|
||||
Python scripts: OBJFILE%s\n"),
|
||||
ext_lang_auto_load_suffix (&extension_language_python));
|
||||
#endif
|
||||
GDB_AUTO_FILE_NAME,
|
||||
_("\
|
||||
scripts_directory_help
|
||||
= xstrprintf (_("\
|
||||
Automatically loaded scripts are located in one of the directories listed\n\
|
||||
by this option.\n\
|
||||
\n\
|
||||
Script names:\n\
|
||||
%s%s\
|
||||
\n\
|
||||
This option is ignored for the kinds of scripts \
|
||||
having 'set auto-load ... off'.\n\
|
||||
Directories listed here need to be present also \
|
||||
in the 'set auto-load safe-path'\n\
|
||||
option."));
|
||||
option."),
|
||||
gdb_name_help,
|
||||
python_name_help ? python_name_help : "");
|
||||
|
||||
add_setshow_optional_filename_cmd ("scripts-directory", class_support,
|
||||
&auto_load_dir, _("\
|
||||
Set the list of directories from which to load auto-loaded scripts."), _("\
|
||||
|
@ -1443,6 +1475,8 @@ Show the list of directories from which to load auto-loaded scripts."),
|
|||
auto_load_set_cmdlist_get (),
|
||||
auto_load_show_cmdlist_get ());
|
||||
xfree (scripts_directory_help);
|
||||
xfree (python_name_help);
|
||||
xfree (gdb_name_help);
|
||||
|
||||
auto_load_safe_path = xstrdup (AUTO_LOAD_SAFE_PATH);
|
||||
auto_load_safe_path_vec_update ();
|
||||
|
|
|
@ -20,25 +20,10 @@
|
|||
#ifndef AUTO_LOAD_H
|
||||
#define AUTO_LOAD_H 1
|
||||
|
||||
struct objfile;
|
||||
struct program_space;
|
||||
|
||||
struct script_language
|
||||
{
|
||||
/* The name of the language, lowercase. */
|
||||
const char *name;
|
||||
|
||||
/* The suffix added to objfiles to get their auto-load script.
|
||||
E.g., "-gdb.py". */
|
||||
const char *suffix;
|
||||
|
||||
/* Returns non-zero if auto-loading scripts in this language is enabled. */
|
||||
int (*auto_load_enabled) (void);
|
||||
|
||||
/* Worker routine to load the script. It has already been opened and
|
||||
deemed safe to load. */
|
||||
void (*source_script_for_objfile) (struct objfile *objfile, FILE *file,
|
||||
const char *filename);
|
||||
};
|
||||
struct auto_load_pspace_info;
|
||||
struct extension_language_defn;
|
||||
|
||||
extern int global_auto_load;
|
||||
|
||||
|
@ -48,16 +33,12 @@ extern int auto_load_local_gdbinit_loaded;
|
|||
|
||||
extern struct auto_load_pspace_info *
|
||||
get_auto_load_pspace_data_for_loading (struct program_space *pspace);
|
||||
extern int maybe_add_script (struct auto_load_pspace_info *pspace_info,
|
||||
int loaded, const char *name,
|
||||
const char *full_path,
|
||||
const struct script_language *language);
|
||||
extern void auto_load_objfile_script (struct objfile *objfile,
|
||||
const struct extension_language_defn *);
|
||||
extern void load_auto_scripts_for_objfile (struct objfile *objfile);
|
||||
extern int
|
||||
script_not_found_warning_print (struct auto_load_pspace_info *pspace_info);
|
||||
extern char auto_load_info_scripts_pattern_nl[];
|
||||
extern void auto_load_info_scripts (char *pattern, int from_tty,
|
||||
const struct script_language *language);
|
||||
const struct extension_language_defn *);
|
||||
|
||||
extern struct cmd_list_element **auto_load_set_cmdlist_get (void);
|
||||
extern struct cmd_list_element **auto_load_show_cmdlist_get (void);
|
||||
|
@ -66,4 +47,7 @@ extern struct cmd_list_element **auto_load_info_cmdlist_get (void);
|
|||
extern int file_is_auto_load_safe (const char *filename,
|
||||
const char *debug_fmt, ...);
|
||||
|
||||
extern int auto_load_gdb_scripts_enabled
|
||||
(const struct extension_language_defn *extlang);
|
||||
|
||||
#endif /* AUTO_LOAD_H */
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
#undef savestring
|
||||
|
||||
#include "mi/mi-common.h"
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
|
||||
/* Enums for exception-handling support. */
|
||||
enum exception_event_kind
|
||||
|
@ -1047,14 +1047,18 @@ condition_command (char *arg, int from_tty)
|
|||
ALL_BREAKPOINTS (b)
|
||||
if (b->number == bnum)
|
||||
{
|
||||
/* Check if this breakpoint has a Python object assigned to
|
||||
it, and if it has a definition of the "stop"
|
||||
method. This method and conditions entered into GDB from
|
||||
the CLI are mutually exclusive. */
|
||||
if (b->py_bp_object
|
||||
&& gdbpy_breakpoint_has_py_cond (b->py_bp_object))
|
||||
error (_("Cannot set a condition where a Python 'stop' "
|
||||
"method has been defined in the breakpoint."));
|
||||
/* Check if this breakpoint has a "stop" method implemented in an
|
||||
extension language. This method and conditions entered into GDB
|
||||
from the CLI are mutually exclusive. */
|
||||
const struct extension_language_defn *extlang
|
||||
= get_breakpoint_cond_ext_lang (b, EXT_LANG_NONE);
|
||||
|
||||
if (extlang != NULL)
|
||||
{
|
||||
error (_("Only one stop condition allowed. There is currently"
|
||||
" a %s stop condition defined for this breakpoint."),
|
||||
ext_lang_capitalized_name (extlang));
|
||||
}
|
||||
set_breakpoint_condition (b, p, from_tty);
|
||||
|
||||
if (is_breakpoint (b))
|
||||
|
@ -5188,9 +5192,9 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Evaluate Python breakpoints that have a "stop" method implemented. */
|
||||
if (b->py_bp_object)
|
||||
bs->stop = gdbpy_should_stop (b->py_bp_object);
|
||||
/* Evaluate extension language breakpoints that have a "stop" method
|
||||
implemented. */
|
||||
bs->stop = breakpoint_ext_lang_cond_says_stop (b);
|
||||
|
||||
if (is_watchpoint (b))
|
||||
{
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#include "cli/cli-cmds.h"
|
||||
#include "cli/cli-utils.h"
|
||||
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
|
||||
#ifdef TUI
|
||||
#include "tui/tui.h" /* For tui_active et.al. */
|
||||
|
@ -522,21 +522,33 @@ find_and_open_script (const char *script_file, int search_path,
|
|||
static void
|
||||
source_script_from_stream (FILE *stream, const char *file)
|
||||
{
|
||||
if (script_ext_mode != script_ext_off
|
||||
&& strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py"))
|
||||
if (script_ext_mode != script_ext_off)
|
||||
{
|
||||
if (have_python ())
|
||||
source_python_script (stream, file);
|
||||
else if (script_ext_mode == script_ext_soft)
|
||||
const struct extension_language_defn *extlang
|
||||
= get_ext_lang_of_file (file);
|
||||
|
||||
if (extlang != NULL)
|
||||
{
|
||||
/* Fallback to GDB script mode. */
|
||||
script_from_file (stream, file);
|
||||
if (ext_lang_present_p (extlang))
|
||||
{
|
||||
script_sourcer_func *sourcer
|
||||
= ext_lang_script_sourcer (extlang);
|
||||
|
||||
gdb_assert (sourcer != NULL);
|
||||
sourcer (extlang, stream, file);
|
||||
return;
|
||||
}
|
||||
else if (script_ext_mode == script_ext_soft)
|
||||
{
|
||||
/* Assume the file is a gdb script.
|
||||
This is handled below. */
|
||||
}
|
||||
else
|
||||
throw_ext_lang_unsupported (extlang);
|
||||
}
|
||||
else
|
||||
error (_("Python scripting is not supported in this copy of GDB."));
|
||||
}
|
||||
else
|
||||
script_from_file (stream, file);
|
||||
|
||||
script_from_file (stream, file);
|
||||
}
|
||||
|
||||
/* Worker to perform the "source" command.
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "cli/cli-script.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
#include "interps.h"
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
@ -590,7 +590,7 @@ execute_control_command (struct command_line *cmd)
|
|||
|
||||
case python_control:
|
||||
{
|
||||
eval_python_from_control_command (cmd);
|
||||
eval_ext_lang_from_control_command (cmd);
|
||||
ret = simple_control;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -8672,11 +8672,10 @@ rm -f conftest.err conftest.$ac_ext
|
|||
$as_echo "${python_has_threads}" >&6; }
|
||||
CPPFLAGS="${saved_CPPFLAGS}"
|
||||
else
|
||||
# Even if Python support is not compiled in, we need to have these files
|
||||
# included.
|
||||
CONFIG_OBS="$CONFIG_OBS python.o py-value.o py-prettyprint.o py-auto-load.o"
|
||||
CONFIG_SRCS="$CONFIG_SRCS python/python.c python/py-value.c \
|
||||
python/py-prettyprint.c python/py-auto-load.c"
|
||||
# Even if Python support is not compiled in, we need to have this file
|
||||
# included so that the "python" command, et.al., still exists.
|
||||
CONFIG_OBS="$CONFIG_OBS python.o"
|
||||
CONFIG_SRCS="$CONFIG_SRCS python/python.c"
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -1045,11 +1045,10 @@ if test "${have_libpython}" != no; then
|
|||
AC_MSG_RESULT(${python_has_threads})
|
||||
CPPFLAGS="${saved_CPPFLAGS}"
|
||||
else
|
||||
# Even if Python support is not compiled in, we need to have these files
|
||||
# included.
|
||||
CONFIG_OBS="$CONFIG_OBS python.o py-value.o py-prettyprint.o py-auto-load.o"
|
||||
CONFIG_SRCS="$CONFIG_SRCS python/python.c python/py-value.c \
|
||||
python/py-prettyprint.c python/py-auto-load.c"
|
||||
# Even if Python support is not compiled in, we need to have this file
|
||||
# included so that the "python" command, et.al., still exists.
|
||||
CONFIG_OBS="$CONFIG_OBS python.o"
|
||||
CONFIG_SRCS="$CONFIG_SRCS python/python.c"
|
||||
fi
|
||||
AC_SUBST(PYTHON_CFLAGS)
|
||||
AC_SUBST(PYTHON_CPPFLAGS)
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "valprint.h"
|
||||
#include "cp-support.h"
|
||||
#include "language.h"
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
#include "exceptions.h"
|
||||
#include "typeprint.h"
|
||||
|
||||
|
@ -584,17 +584,17 @@ cp_print_value (struct type *type, struct type *real_type,
|
|||
{
|
||||
int result = 0;
|
||||
|
||||
/* Attempt to run the Python pretty-printers on the
|
||||
/* Attempt to run an extension language pretty-printer on the
|
||||
baseclass if possible. */
|
||||
if (!options->raw)
|
||||
result = apply_val_pretty_printer (baseclass, base_valaddr,
|
||||
thisoffset + boffset,
|
||||
value_address (base_val),
|
||||
stream, recurse, base_val,
|
||||
options, current_language);
|
||||
result
|
||||
= apply_ext_lang_val_pretty_printer (baseclass, base_valaddr,
|
||||
thisoffset + boffset,
|
||||
value_address (base_val),
|
||||
stream, recurse,
|
||||
base_val, options,
|
||||
current_language);
|
||||
|
||||
|
||||
|
||||
if (!result)
|
||||
cp_print_value_fields (baseclass, thistype, base_valaddr,
|
||||
thisoffset + boffset,
|
||||
|
|
|
@ -159,13 +159,9 @@ extern char *debug_file_directory;
|
|||
handler. Otherwise, SIGINT simply sets a flag; code that might
|
||||
take a long time, and which ought to be interruptible, checks this
|
||||
flag using the QUIT macro.
|
||||
|
||||
If GDB is built with Python support, it uses Python's low-level
|
||||
interface to implement the flag. This approach makes it possible
|
||||
for Python and GDB SIGINT handling to coexist seamlessly.
|
||||
|
||||
If GDB is built without Python, it instead uses its traditional
|
||||
variables. */
|
||||
These functions use the extension_language_ops API to allow extension
|
||||
language(s) and GDB SIGINT handling to coexist seamlessly. */
|
||||
|
||||
/* Clear the quit flag. */
|
||||
extern void clear_quit_flag (void);
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "valprint.h"
|
||||
#include "gdb_obstack.h"
|
||||
#include "objfiles.h"
|
||||
#include "python/python.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -0,0 +1,871 @@
|
|||
/* 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/>. */
|
||||
|
||||
/* Note: With few exceptions, external functions and variables in this file
|
||||
have "ext_lang" in the name, and no other symbol in gdb does. */
|
||||
|
||||
#include "defs.h"
|
||||
#include <signal.h>
|
||||
#include "auto-load.h"
|
||||
#include "breakpoint.h"
|
||||
#include "event-top.h"
|
||||
#include "extension.h"
|
||||
#include "extension-priv.h"
|
||||
#include "observer.h"
|
||||
#include "cli/cli-script.h"
|
||||
#include "python/python.h"
|
||||
|
||||
/* Iterate over all external extension languages, regardless of whether the
|
||||
support has been compiled in or not.
|
||||
This does not include GDB's own scripting language. */
|
||||
|
||||
#define ALL_EXTENSION_LANGUAGES(i, extlang) \
|
||||
for (/*int*/ i = 0, extlang = extension_languages[0]; \
|
||||
extlang != NULL; \
|
||||
extlang = extension_languages[++i])
|
||||
|
||||
/* Iterate over all external extension languages that are supported.
|
||||
This does not include GDB's own scripting language. */
|
||||
|
||||
#define ALL_ENABLED_EXTENSION_LANGUAGES(i, extlang) \
|
||||
for (/*int*/ i = 0, extlang = extension_languages[0]; \
|
||||
extlang != NULL; \
|
||||
extlang = extension_languages[++i]) \
|
||||
if (extlang->ops != NULL)
|
||||
|
||||
static script_sourcer_func source_gdb_script;
|
||||
static objfile_script_sourcer_func source_gdb_objfile_script;
|
||||
|
||||
/* GDB's own scripting language.
|
||||
This exists, in part, to support auto-loading ${prog}-gdb.gdb scripts. */
|
||||
|
||||
static const struct extension_language_script_ops
|
||||
extension_language_gdb_script_ops =
|
||||
{
|
||||
source_gdb_script,
|
||||
source_gdb_objfile_script,
|
||||
auto_load_gdb_scripts_enabled
|
||||
};
|
||||
|
||||
const struct extension_language_defn extension_language_gdb =
|
||||
{
|
||||
EXT_LANG_GDB,
|
||||
"gdb",
|
||||
"GDB",
|
||||
|
||||
/* We fall back to interpreting a script as a GDB script if it doesn't
|
||||
match the other scripting languages, but for consistency's sake
|
||||
give it a formal suffix. */
|
||||
".gdb",
|
||||
"-gdb.gdb",
|
||||
|
||||
/* cli_control_type: This is never used: GDB's own scripting language
|
||||
has a variety of control types (if, while, etc.). */
|
||||
commands_control,
|
||||
|
||||
&extension_language_gdb_script_ops,
|
||||
|
||||
/* The rest of the extension language interface isn't supported by GDB's own
|
||||
extension/scripting language. */
|
||||
NULL
|
||||
};
|
||||
|
||||
/* NULL-terminated table of all external (non-native) extension languages.
|
||||
|
||||
The order of appearance in the table is important.
|
||||
When multiple extension languages provide the same feature, for example
|
||||
a pretty-printer for a particular type, which one gets used?
|
||||
The algorithm employed here is "the first one wins". For example, in
|
||||
the case of pretty-printers this means the first one to provide a
|
||||
pretty-printed value is the one that is used. This algorithm is employed
|
||||
throughout. */
|
||||
|
||||
static const struct extension_language_defn * const extension_languages[] =
|
||||
{
|
||||
/* To preserve existing behaviour, python should always appear first. */
|
||||
&extension_language_python,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Return a pointer to the struct extension_language_defn object of
|
||||
extension language LANG.
|
||||
This always returns a non-NULL pointer, even if support for the language
|
||||
is not compiled into this copy of GDB. */
|
||||
|
||||
const struct extension_language_defn *
|
||||
get_ext_lang_defn (enum extension_language lang)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
gdb_assert (lang != EXT_LANG_NONE);
|
||||
|
||||
if (lang == EXT_LANG_GDB)
|
||||
return &extension_language_gdb;
|
||||
|
||||
ALL_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->language == lang)
|
||||
return extlang;
|
||||
}
|
||||
|
||||
gdb_assert_not_reached ("unable to find extension_language_defn");
|
||||
}
|
||||
|
||||
/* Return TRUE if FILE has extension EXTENSION. */
|
||||
|
||||
static int
|
||||
has_extension (const char *file, const char *extension)
|
||||
{
|
||||
int file_len = strlen (file);
|
||||
int extension_len = strlen (extension);
|
||||
|
||||
return (file_len > extension_len
|
||||
&& strcmp (&file[file_len - extension_len], extension) == 0);
|
||||
}
|
||||
|
||||
/* Return the extension language of FILE, or NULL if
|
||||
the extension language of FILE is not recognized.
|
||||
This is done by looking at the file's suffix. */
|
||||
|
||||
const struct extension_language_defn *
|
||||
get_ext_lang_of_file (const char *file)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (has_extension (file, extlang->suffix))
|
||||
return extlang;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return non-zero if support for the specified extension language
|
||||
is compiled in. */
|
||||
|
||||
int
|
||||
ext_lang_present_p (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return extlang->script_ops != NULL;
|
||||
}
|
||||
|
||||
/* Return non-zero if the specified extension language has successfully
|
||||
initialized. */
|
||||
|
||||
int
|
||||
ext_lang_initialized_p (const struct extension_language_defn *extlang)
|
||||
{
|
||||
if (extlang->ops != NULL)
|
||||
{
|
||||
/* This method is required. */
|
||||
gdb_assert (extlang->ops->initialized != NULL);
|
||||
return extlang->ops->initialized (extlang);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Throw an error indicating EXTLANG is not supported in this copy of GDB. */
|
||||
|
||||
void
|
||||
throw_ext_lang_unsupported (const struct extension_language_defn *extlang)
|
||||
{
|
||||
error (_("Scripting in the \"%s\" language is not supported"
|
||||
" in this copy of GDB."),
|
||||
ext_lang_capitalized_name (extlang));
|
||||
}
|
||||
|
||||
/* Methods for GDB's own extension/scripting language. */
|
||||
|
||||
/* The extension_language_script_ops.script_sourcer "method". */
|
||||
|
||||
static void
|
||||
source_gdb_script (const struct extension_language_defn *extlang,
|
||||
FILE *stream, const char *file)
|
||||
{
|
||||
script_from_file (stream, file);
|
||||
}
|
||||
|
||||
/* The extension_language_script_ops.objfile_script_sourcer "method". */
|
||||
|
||||
static void
|
||||
source_gdb_objfile_script (const struct extension_language_defn *extlang,
|
||||
struct objfile *objfile,
|
||||
FILE *stream, const char *file)
|
||||
{
|
||||
script_from_file (stream, file);
|
||||
}
|
||||
|
||||
/* Accessors for "public" attributes of struct extension_language. */
|
||||
|
||||
/* Return the "name" field of EXTLANG. */
|
||||
|
||||
const char *
|
||||
ext_lang_name (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return extlang->name;
|
||||
}
|
||||
|
||||
/* Return the "capitalized_name" field of EXTLANG. */
|
||||
|
||||
const char *
|
||||
ext_lang_capitalized_name (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return extlang->capitalized_name;
|
||||
}
|
||||
|
||||
/* Return the "suffix" field of EXTLANG. */
|
||||
|
||||
const char *
|
||||
ext_lang_suffix (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return extlang->suffix;
|
||||
}
|
||||
|
||||
/* Return the "auto_load_suffix" field of EXTLANG. */
|
||||
|
||||
const char *
|
||||
ext_lang_auto_load_suffix (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return extlang->auto_load_suffix;
|
||||
}
|
||||
|
||||
/* extension_language_script_ops wrappers. */
|
||||
|
||||
/* Return the script "sourcer" function for EXTLANG.
|
||||
This is the function that loads and processes a script.
|
||||
If support for this language isn't compiled in, NULL is returned. */
|
||||
|
||||
script_sourcer_func *
|
||||
ext_lang_script_sourcer (const struct extension_language_defn *extlang)
|
||||
{
|
||||
if (extlang->script_ops == NULL)
|
||||
return NULL;
|
||||
|
||||
/* The extension language is required to implement this function. */
|
||||
gdb_assert (extlang->script_ops->script_sourcer != NULL);
|
||||
|
||||
return extlang->script_ops->script_sourcer;
|
||||
}
|
||||
|
||||
/* Return the objfile script "sourcer" function for EXTLANG.
|
||||
This is the function that loads and processes a script for a particular
|
||||
objfile.
|
||||
If support for this language isn't compiled in, NULL is returned. */
|
||||
|
||||
objfile_script_sourcer_func *
|
||||
ext_lang_objfile_script_sourcer (const struct extension_language_defn *extlang)
|
||||
{
|
||||
if (extlang->script_ops == NULL)
|
||||
return NULL;
|
||||
|
||||
/* The extension language is required to implement this function. */
|
||||
gdb_assert (extlang->script_ops->objfile_script_sourcer != NULL);
|
||||
|
||||
return extlang->script_ops->objfile_script_sourcer;
|
||||
}
|
||||
|
||||
/* Return non-zero if auto-loading of EXTLANG scripts is enabled.
|
||||
Zero is returned if support for this language isn't compiled in. */
|
||||
|
||||
int
|
||||
ext_lang_auto_load_enabled (const struct extension_language_defn *extlang)
|
||||
{
|
||||
if (extlang->script_ops == NULL)
|
||||
return 0;
|
||||
|
||||
/* The extension language is required to implement this function. */
|
||||
gdb_assert (extlang->script_ops->auto_load_enabled != NULL);
|
||||
|
||||
return extlang->script_ops->auto_load_enabled (extlang);
|
||||
}
|
||||
|
||||
/* Functions that iterate over all extension languages.
|
||||
These only iterate over external extension languages, not including
|
||||
GDB's own extension/scripting language, unless otherwise indicated. */
|
||||
|
||||
/* Wrapper to call the extension_language_ops.finish_initialization "method"
|
||||
for each compiled-in extension language. */
|
||||
|
||||
void
|
||||
finish_ext_lang_initialization (void)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->ops->finish_initialization != NULL)
|
||||
extlang->ops->finish_initialization (extlang);
|
||||
}
|
||||
}
|
||||
|
||||
/* Invoke the appropriate extension_language_ops.eval_from_control_command
|
||||
method to perform CMD, which is a list of commands in an extension language.
|
||||
|
||||
This function is what implements, for example:
|
||||
|
||||
python
|
||||
print 42
|
||||
end
|
||||
|
||||
in a GDB script. */
|
||||
|
||||
void
|
||||
eval_ext_lang_from_control_command (struct command_line *cmd)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->cli_control_type == cmd->control_type)
|
||||
{
|
||||
if (extlang->ops->eval_from_control_command != NULL)
|
||||
{
|
||||
extlang->ops->eval_from_control_command (extlang, cmd);
|
||||
return;
|
||||
}
|
||||
/* The requested extension language is not supported in this GDB. */
|
||||
throw_ext_lang_unsupported (extlang);
|
||||
}
|
||||
}
|
||||
|
||||
gdb_assert_not_reached ("unknown extension language in command_line");
|
||||
}
|
||||
|
||||
/* Search for and load scripts for OBJFILE written in extension languages.
|
||||
This includes GDB's own scripting language.
|
||||
|
||||
This function is what implements the loading of OBJFILE-gdb.py and
|
||||
OBJFILE-gdb.gdb. */
|
||||
|
||||
void
|
||||
auto_load_ext_lang_scripts_for_objfile (struct objfile *objfile)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
extlang = &extension_language_gdb;
|
||||
if (ext_lang_auto_load_enabled (extlang))
|
||||
auto_load_objfile_script (objfile, extlang);
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (ext_lang_auto_load_enabled (extlang))
|
||||
auto_load_objfile_script (objfile, extlang);
|
||||
}
|
||||
}
|
||||
|
||||
/* Interface to type pretty-printers implemented in an extension language. */
|
||||
|
||||
/* Call this at the start when preparing to pretty-print a type.
|
||||
The result is a pointer to an opaque object (to the caller) to be passed
|
||||
to apply_ext_lang_type_printers and free_ext_lang_type_printers.
|
||||
|
||||
We don't know in advance which extension language will provide a
|
||||
pretty-printer for the type, so all are initialized. */
|
||||
|
||||
struct ext_lang_type_printers *
|
||||
start_ext_lang_type_printers (void)
|
||||
{
|
||||
struct ext_lang_type_printers *printers
|
||||
= XCNEW (struct ext_lang_type_printers);
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->ops->start_type_printers != NULL)
|
||||
extlang->ops->start_type_printers (extlang, printers);
|
||||
}
|
||||
|
||||
return printers;
|
||||
}
|
||||
|
||||
/* Iteratively try the type pretty-printers specified by PRINTERS
|
||||
according to the standard search order (specified by extension_languages),
|
||||
returning the result of the first one that succeeds.
|
||||
If there was an error, or if no printer succeeds, then NULL is returned. */
|
||||
|
||||
char *
|
||||
apply_ext_lang_type_printers (struct ext_lang_type_printers *printers,
|
||||
struct type *type)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
char *result = NULL;
|
||||
enum ext_lang_rc rc;
|
||||
|
||||
if (extlang->ops->apply_type_printers == NULL)
|
||||
continue;
|
||||
rc = extlang->ops->apply_type_printers (extlang, printers, type,
|
||||
&result);
|
||||
switch (rc)
|
||||
{
|
||||
case EXT_LANG_RC_OK:
|
||||
gdb_assert (result != NULL);
|
||||
return result;
|
||||
case EXT_LANG_RC_ERROR:
|
||||
return NULL;
|
||||
case EXT_LANG_RC_NOP:
|
||||
break;
|
||||
default:
|
||||
gdb_assert_not_reached ("bad return from apply_type_printers");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Call this after pretty-printing a type to release all memory held
|
||||
by PRINTERS. */
|
||||
|
||||
void
|
||||
free_ext_lang_type_printers (struct ext_lang_type_printers *printers)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->ops->free_type_printers != NULL)
|
||||
extlang->ops->free_type_printers (extlang, printers);
|
||||
}
|
||||
|
||||
xfree (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 non-zero if the value was successfully pretty-printed.
|
||||
|
||||
Extension languages are tried in the order specified by
|
||||
extension_languages. The first one to provide a pretty-printed
|
||||
value "wins".
|
||||
|
||||
If an error is encountered in a pretty-printer, no further extension
|
||||
languages are tried.
|
||||
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. */
|
||||
|
||||
int
|
||||
apply_ext_lang_val_pretty_printer (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)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
enum ext_lang_rc rc;
|
||||
|
||||
if (extlang->ops->apply_val_pretty_printer == NULL)
|
||||
continue;
|
||||
rc = extlang->ops->apply_val_pretty_printer (extlang, type, valaddr,
|
||||
embedded_offset, address,
|
||||
stream, recurse, val,
|
||||
options, language);
|
||||
switch (rc)
|
||||
{
|
||||
case EXT_LANG_RC_OK:
|
||||
return 1;
|
||||
case EXT_LANG_RC_ERROR:
|
||||
return 0;
|
||||
case EXT_LANG_RC_NOP:
|
||||
break;
|
||||
default:
|
||||
gdb_assert_not_reached ("bad return from apply_val_pretty_printer");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 EXT_LANG_BT_ERROR on error,
|
||||
or EXT_LANG_BT_COMPLETED on success.
|
||||
|
||||
Extension languages are tried in the order specified by
|
||||
extension_languages. The first one to provide a filter "wins".
|
||||
If there is an error (EXT_LANG_BT_ERROR) it is reported immediately
|
||||
rather than trying filters in other extension languages. */
|
||||
|
||||
enum ext_lang_bt_status
|
||||
apply_ext_lang_frame_filter (struct frame_info *frame, int flags,
|
||||
enum ext_lang_frame_args args_type,
|
||||
struct ui_out *out,
|
||||
int frame_low, int frame_high)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
enum ext_lang_bt_status status;
|
||||
|
||||
if (extlang->ops->apply_frame_filter == NULL)
|
||||
continue;
|
||||
status = extlang->ops->apply_frame_filter (extlang, frame, flags,
|
||||
args_type, out,
|
||||
frame_low, frame_high);
|
||||
/* We use the filters from the first extension language that has
|
||||
applicable filters. Also, an error is reported immediately
|
||||
rather than continue trying. */
|
||||
if (status != EXT_LANG_BT_NO_FILTERS)
|
||||
return status;
|
||||
}
|
||||
|
||||
return EXT_LANG_BT_NO_FILTERS;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
The 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_ext_lang_values (struct objfile *objfile, htab_t copied_types)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->ops->preserve_values != NULL)
|
||||
extlang->ops->preserve_values (extlang, objfile, copied_types);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a stop condition implemented in an extension language for
|
||||
breakpoint B, return a pointer to the extension language's definition.
|
||||
Otherwise return NULL.
|
||||
If SKIP_LANG is not EXT_LANG_NONE, skip checking this language.
|
||||
This is for the case where we're setting a new condition: Only one
|
||||
condition is allowed, so when setting a condition for any particular
|
||||
extension language, we need to check if any other extension language
|
||||
already has a condition set. */
|
||||
|
||||
const struct extension_language_defn *
|
||||
get_breakpoint_cond_ext_lang (struct breakpoint *b,
|
||||
enum extension_language skip_lang)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->language != skip_lang
|
||||
&& extlang->ops->breakpoint_has_cond != NULL
|
||||
&& extlang->ops->breakpoint_has_cond (extlang, b))
|
||||
return extlang;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return whether a stop condition for breakpoint B says to stop.
|
||||
True is also returned if there is no stop condition for B. */
|
||||
|
||||
int
|
||||
breakpoint_ext_lang_cond_says_stop (struct breakpoint *b)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
enum ext_lang_bp_stop stop = EXT_LANG_BP_STOP_UNSET;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
/* There is a rule that a breakpoint can have at most one of any of a
|
||||
CLI or extension language condition. However, Python hacks in "finish
|
||||
breakpoints" on top of the "stop" check, so we have to call this for
|
||||
every language, even if we could first determine whether a "stop"
|
||||
method exists. */
|
||||
if (extlang->ops->breakpoint_cond_says_stop != NULL)
|
||||
{
|
||||
enum ext_lang_bp_stop this_stop
|
||||
= extlang->ops->breakpoint_cond_says_stop (extlang, b);
|
||||
|
||||
if (this_stop != EXT_LANG_BP_STOP_UNSET)
|
||||
{
|
||||
/* Even though we have to check every extension language, only
|
||||
one of them can return yes/no (because only one of them
|
||||
can have a "stop" condition). */
|
||||
gdb_assert (stop == EXT_LANG_BP_STOP_UNSET);
|
||||
stop = this_stop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stop == EXT_LANG_BP_STOP_NO ? 0 : 1;
|
||||
}
|
||||
|
||||
/* ^C/SIGINT support.
|
||||
This requires cooperation with the extension languages so the support
|
||||
is defined here. */
|
||||
|
||||
/* This flag tracks quit requests when we haven't called out to an
|
||||
extension language. it also holds quit requests when we transition to
|
||||
an extension language that doesn't have cooperative SIGINT handling. */
|
||||
static int quit_flag;
|
||||
|
||||
/* The current extension language we've called out to, or
|
||||
extension_language_gdb if there isn't one.
|
||||
This must be set everytime we call out to an extension language, and reset
|
||||
to the previous value when it returns. Note that the previous value may
|
||||
be a different (or the same) extension language. */
|
||||
static const struct extension_language_defn *active_ext_lang
|
||||
= &extension_language_gdb;
|
||||
|
||||
/* Return the currently active extension language. */
|
||||
|
||||
const struct extension_language_defn *
|
||||
get_active_ext_lang (void)
|
||||
{
|
||||
return active_ext_lang;
|
||||
}
|
||||
|
||||
/* Install a SIGINT handler. */
|
||||
|
||||
static void
|
||||
install_sigint_handler (const struct signal_handler *handler_state)
|
||||
{
|
||||
gdb_assert (handler_state->handler_saved);
|
||||
|
||||
signal (SIGINT, handler_state->handler);
|
||||
}
|
||||
|
||||
/* Install GDB's SIGINT handler, storing the previous version in *PREVIOUS.
|
||||
As a simple optimization, if the previous version was GDB's SIGINT handler
|
||||
then mark the previous handler as not having been saved, and thus it won't
|
||||
be restored. */
|
||||
|
||||
static void
|
||||
install_gdb_sigint_handler (struct signal_handler *previous)
|
||||
{
|
||||
/* Save here to simplify comparison. */
|
||||
RETSIGTYPE (*handle_sigint_for_compare) () = handle_sigint;
|
||||
|
||||
previous->handler = signal (SIGINT, handle_sigint);
|
||||
if (previous->handler != handle_sigint_for_compare)
|
||||
previous->handler_saved = 1;
|
||||
else
|
||||
previous->handler_saved = 0;
|
||||
}
|
||||
|
||||
/* Set the currently active extension language to NOW_ACTIVE.
|
||||
The result is a pointer to a malloc'd block of memory to pass to
|
||||
restore_active_ext_lang.
|
||||
|
||||
N.B. This function must be called every time we call out to an extension
|
||||
language, and the result must be passed to restore_active_ext_lang
|
||||
afterwards.
|
||||
|
||||
If there is a pending SIGINT it is "moved" to the now active extension
|
||||
language, if it supports cooperative SIGINT handling (i.e., it provides
|
||||
{clear,set,check}_quit_flag methods). If the extension language does not
|
||||
support cooperative SIGINT handling, then the SIGINT is left queued and
|
||||
we require the non-cooperative extension language to call check_quit_flag
|
||||
at appropriate times.
|
||||
It is important for the extension language to call check_quit_flag if it
|
||||
installs its own SIGINT handler to prevent the situation where a SIGINT
|
||||
is queued on entry, extension language code runs for a "long" time possibly
|
||||
serving one or more SIGINTs, and then returns. Upon return, if
|
||||
check_quit_flag is not called, the original SIGINT will be thrown.
|
||||
Non-cooperative extension languages are free to install their own SIGINT
|
||||
handler but the original must be restored upon return, either itself
|
||||
or via restore_active_ext_lang. */
|
||||
|
||||
struct active_ext_lang_state *
|
||||
set_active_ext_lang (const struct extension_language_defn *now_active)
|
||||
{
|
||||
struct active_ext_lang_state *previous
|
||||
= XCNEW (struct active_ext_lang_state);
|
||||
|
||||
previous->ext_lang = active_ext_lang;
|
||||
active_ext_lang = now_active;
|
||||
|
||||
/* If the newly active extension language uses cooperative SIGINT handling
|
||||
then ensure GDB's SIGINT handler is installed. */
|
||||
if (now_active->language == EXT_LANG_GDB
|
||||
|| now_active->ops->check_quit_flag != NULL)
|
||||
install_gdb_sigint_handler (&previous->sigint_handler);
|
||||
|
||||
/* If there's a SIGINT recorded in the cooperative extension languages,
|
||||
move it to the new language, or save it in GDB's global flag if the newly
|
||||
active extension language doesn't use cooperative SIGINT handling. */
|
||||
if (check_quit_flag ())
|
||||
set_quit_flag ();
|
||||
|
||||
return previous;
|
||||
}
|
||||
|
||||
/* Restore active extension language from PREVIOUS. */
|
||||
|
||||
void
|
||||
restore_active_ext_lang (struct active_ext_lang_state *previous)
|
||||
{
|
||||
const struct extension_language_defn *current = active_ext_lang;
|
||||
|
||||
active_ext_lang = previous->ext_lang;
|
||||
|
||||
/* Restore the previous SIGINT handler if one was saved. */
|
||||
if (previous->sigint_handler.handler_saved)
|
||||
install_sigint_handler (&previous->sigint_handler);
|
||||
|
||||
/* If there's a SIGINT recorded in the cooperative extension languages,
|
||||
move it to the new language, or save it in GDB's global flag if the newly
|
||||
active extension language doesn't use cooperative SIGINT handling. */
|
||||
if (check_quit_flag ())
|
||||
set_quit_flag ();
|
||||
|
||||
xfree (previous);
|
||||
}
|
||||
|
||||
/* Clear the quit flag.
|
||||
The flag is cleared in all extension languages,
|
||||
not just the currently active one. */
|
||||
|
||||
void
|
||||
clear_quit_flag (void)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->ops->clear_quit_flag != NULL)
|
||||
extlang->ops->clear_quit_flag (extlang);
|
||||
}
|
||||
|
||||
quit_flag = 0;
|
||||
}
|
||||
|
||||
/* Set the quit flag.
|
||||
This only sets the flag in the currently active extension language.
|
||||
If the currently active extension language does not have cooperative
|
||||
SIGINT handling, then GDB's global flag is set, and it is up to the
|
||||
extension language to call check_quit_flag. The extension language
|
||||
is free to install its own SIGINT handler, but we still need to handle
|
||||
the transition. */
|
||||
|
||||
void
|
||||
set_quit_flag (void)
|
||||
{
|
||||
if (active_ext_lang->ops != NULL
|
||||
&& active_ext_lang->ops->set_quit_flag != NULL)
|
||||
active_ext_lang->ops->set_quit_flag (active_ext_lang);
|
||||
else
|
||||
quit_flag = 1;
|
||||
}
|
||||
|
||||
/* Return true if the quit flag has been set, false otherwise.
|
||||
Note: The flag is cleared as a side-effect.
|
||||
The flag is checked in all extension languages that support cooperative
|
||||
SIGINT handling, not just the current one. This simplifies transitions. */
|
||||
|
||||
int
|
||||
check_quit_flag (void)
|
||||
{
|
||||
int i, result = 0;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->ops->check_quit_flag != NULL)
|
||||
if (extlang->ops->check_quit_flag (extlang) != 0)
|
||||
result = 1;
|
||||
}
|
||||
|
||||
/* This is written in a particular way to avoid races. */
|
||||
if (quit_flag)
|
||||
{
|
||||
quit_flag = 0;
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Called via an observer before gdb prints its prompt.
|
||||
Iterate over the extension languages giving them a chance to
|
||||
change the prompt. The first one to change the prompt wins,
|
||||
and no further languages are tried. */
|
||||
|
||||
static void
|
||||
ext_lang_before_prompt (const char *current_gdb_prompt)
|
||||
{
|
||||
int i;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
enum ext_lang_rc rc;
|
||||
|
||||
if (extlang->ops->before_prompt == NULL)
|
||||
continue;
|
||||
rc = extlang->ops->before_prompt (extlang, current_gdb_prompt);
|
||||
switch (rc)
|
||||
{
|
||||
case EXT_LANG_RC_OK:
|
||||
case EXT_LANG_RC_ERROR:
|
||||
return;
|
||||
case EXT_LANG_RC_NOP:
|
||||
break;
|
||||
default:
|
||||
gdb_assert_not_reached ("bad return from before_prompt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern initialize_file_ftype _initialize_extension;
|
||||
|
||||
void
|
||||
_initialize_extension (void)
|
||||
{
|
||||
observer_attach_before_prompt (ext_lang_before_prompt);
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
/* 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_H
|
||||
#define EXTENSION_H
|
||||
|
||||
#include "mi/mi-cmds.h" /* For PRINT_NO_VALUES, etc. */
|
||||
|
||||
struct breakpoint;
|
||||
struct command_line;
|
||||
struct frame_info;
|
||||
struct language_defn;
|
||||
struct objfile;
|
||||
struct extension_language_defn;
|
||||
struct type;
|
||||
struct ui_file;
|
||||
struct ui_out;
|
||||
struct value;
|
||||
struct value_print_options;
|
||||
|
||||
/* A function to load and process a script file.
|
||||
The file has been opened and is ready to be read from the beginning.
|
||||
Any exceptions are not caught, and are passed to the caller. */
|
||||
typedef void script_sourcer_func (const struct extension_language_defn *,
|
||||
FILE *stream, const char *filename);
|
||||
|
||||
/* A function to load and process a script for an objfile.
|
||||
The file has been opened and is ready to be read from the beginning.
|
||||
Any exceptions are not caught, and are passed to the caller. */
|
||||
typedef void objfile_script_sourcer_func
|
||||
(const struct extension_language_defn *,
|
||||
struct objfile *, FILE *stream, const char *filename);
|
||||
|
||||
/* Enum of each extension(/scripting) language. */
|
||||
|
||||
enum extension_language
|
||||
{
|
||||
EXT_LANG_NONE,
|
||||
EXT_LANG_GDB,
|
||||
EXT_LANG_PYTHON
|
||||
};
|
||||
|
||||
/* Extension language frame-filter status return values. */
|
||||
|
||||
enum ext_lang_bt_status
|
||||
{
|
||||
/* Return when an error has occurred in processing frame filters,
|
||||
or when printing the stack. */
|
||||
EXT_LANG_BT_ERROR = -1,
|
||||
|
||||
/* Return from internal routines to indicate that the function
|
||||
succeeded. */
|
||||
EXT_LANG_BT_OK = 1,
|
||||
|
||||
/* Return when the frame filter process is complete, and all
|
||||
operations have succeeded. */
|
||||
EXT_LANG_BT_COMPLETED = 2,
|
||||
|
||||
/* Return when the frame filter process is complete, but there
|
||||
were no filter registered and enabled to process. */
|
||||
EXT_LANG_BT_NO_FILTERS = 3
|
||||
};
|
||||
|
||||
/* Flags to pass to apply_extlang_frame_filter. */
|
||||
|
||||
enum frame_filter_flags
|
||||
{
|
||||
/* Set this flag if frame level is to be printed. */
|
||||
PRINT_LEVEL = 1,
|
||||
|
||||
/* Set this flag if frame information is to be printed. */
|
||||
PRINT_FRAME_INFO = 2,
|
||||
|
||||
/* Set this flag if frame arguments are to be printed. */
|
||||
PRINT_ARGS = 4,
|
||||
|
||||
/* Set this flag if frame locals are to be printed. */
|
||||
PRINT_LOCALS = 8,
|
||||
};
|
||||
|
||||
/* A choice of the different frame argument printing strategies that
|
||||
can occur in different cases of frame filter instantiation. */
|
||||
|
||||
enum ext_lang_frame_args
|
||||
{
|
||||
/* Print no values for arguments when invoked from the MI. */
|
||||
NO_VALUES = PRINT_NO_VALUES,
|
||||
|
||||
MI_PRINT_ALL_VALUES = PRINT_ALL_VALUES,
|
||||
|
||||
/* Print only simple values (what MI defines as "simple") for
|
||||
arguments when invoked from the MI. */
|
||||
MI_PRINT_SIMPLE_VALUES = PRINT_SIMPLE_VALUES,
|
||||
|
||||
/* Print only scalar values for arguments when invoked from the CLI. */
|
||||
CLI_SCALAR_VALUES,
|
||||
|
||||
/* Print all values for arguments when invoked from the CLI. */
|
||||
CLI_ALL_VALUES
|
||||
};
|
||||
|
||||
/* The possible results of
|
||||
extension_language_ops.breakpoint_cond_says_stop. */
|
||||
|
||||
enum ext_lang_bp_stop
|
||||
{
|
||||
/* No "stop" condition is set. */
|
||||
EXT_LANG_BP_STOP_UNSET,
|
||||
|
||||
/* A "stop" condition is set, and it says "don't stop". */
|
||||
EXT_LANG_BP_STOP_NO,
|
||||
|
||||
/* A "stop" condition is set, and it says "stop". */
|
||||
EXT_LANG_BP_STOP_YES
|
||||
};
|
||||
|
||||
/* Table of type printers associated with the global typedef table. */
|
||||
|
||||
struct ext_lang_type_printers
|
||||
{
|
||||
/* Type-printers from Python. */
|
||||
void *py_type_printers;
|
||||
};
|
||||
|
||||
/* The interface for gdb's own extension(/scripting) language. */
|
||||
extern const struct extension_language_defn extension_language_gdb;
|
||||
|
||||
extern const struct extension_language_defn *get_ext_lang_defn
|
||||
(enum extension_language lang);
|
||||
|
||||
extern const struct extension_language_defn *get_ext_lang_of_file
|
||||
(const char *file);
|
||||
|
||||
extern int ext_lang_present_p (const struct extension_language_defn *);
|
||||
|
||||
extern int ext_lang_initialized_p (const struct extension_language_defn *);
|
||||
|
||||
extern void throw_ext_lang_unsupported
|
||||
(const struct extension_language_defn *);
|
||||
|
||||
/* Accessors for "public" attributes of the extension language definition. */
|
||||
|
||||
extern enum extension_language ext_lang_kind
|
||||
(const struct extension_language_defn *);
|
||||
|
||||
extern const char *ext_lang_name (const struct extension_language_defn *);
|
||||
|
||||
extern const char *ext_lang_capitalized_name
|
||||
(const struct extension_language_defn *);
|
||||
|
||||
extern const char *ext_lang_suffix (const struct extension_language_defn *);
|
||||
|
||||
extern const char *ext_lang_auto_load_suffix
|
||||
(const struct extension_language_defn *);
|
||||
|
||||
extern script_sourcer_func *ext_lang_script_sourcer
|
||||
(const struct extension_language_defn *);
|
||||
|
||||
extern objfile_script_sourcer_func *ext_lang_objfile_script_sourcer
|
||||
(const struct extension_language_defn *);
|
||||
|
||||
extern int ext_lang_auto_load_enabled (const struct extension_language_defn *);
|
||||
|
||||
/* Wrappers for each extension language API function that iterate over all
|
||||
extension languages. */
|
||||
|
||||
extern void finish_ext_lang_initialization (void);
|
||||
|
||||
extern void eval_ext_lang_from_control_command (struct command_line *cmd);
|
||||
|
||||
extern void auto_load_ext_lang_scripts_for_objfile (struct objfile *);
|
||||
|
||||
extern struct ext_lang_type_printers *start_ext_lang_type_printers (void);
|
||||
|
||||
extern char *apply_ext_lang_type_printers (struct ext_lang_type_printers *,
|
||||
struct type *);
|
||||
|
||||
extern void free_ext_lang_type_printers (struct ext_lang_type_printers *);
|
||||
|
||||
extern int apply_ext_lang_val_pretty_printer
|
||||
(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);
|
||||
|
||||
extern enum ext_lang_bt_status apply_ext_lang_frame_filter
|
||||
(struct frame_info *frame, int flags, enum ext_lang_frame_args args_type,
|
||||
struct ui_out *out, int frame_low, int frame_high);
|
||||
|
||||
extern void preserve_ext_lang_values (struct objfile *, htab_t copied_types);
|
||||
|
||||
extern const struct extension_language_defn *get_breakpoint_cond_ext_lang
|
||||
(struct breakpoint *b, enum extension_language skip_lang);
|
||||
|
||||
extern int breakpoint_ext_lang_cond_says_stop (struct breakpoint *);
|
||||
|
||||
#endif /* EXTENSION_H */
|
|
@ -39,7 +39,6 @@
|
|||
#include "main.h"
|
||||
#include "source.h"
|
||||
#include "cli/cli-cmds.h"
|
||||
#include "python/python.h"
|
||||
#include "objfiles.h"
|
||||
#include "auto-load.h"
|
||||
#include "maint.h"
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "exceptions.h"
|
||||
#include "utils.h"
|
||||
#include "mi-getopt.h"
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
#include <ctype.h>
|
||||
#include "mi-parse.h"
|
||||
|
||||
|
@ -69,7 +69,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
|
|||
int i;
|
||||
struct cleanup *cleanup_stack;
|
||||
struct frame_info *fi;
|
||||
enum py_bt_status result = PY_BT_ERROR;
|
||||
enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
|
||||
int raw_arg = 0;
|
||||
int oind = 0;
|
||||
enum opt
|
||||
|
@ -141,14 +141,14 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
|
|||
if (py_frame_low == -1)
|
||||
py_frame_low++;
|
||||
|
||||
result = apply_frame_filter (get_current_frame (), flags,
|
||||
NO_VALUES, current_uiout,
|
||||
py_frame_low, frame_high);
|
||||
result = apply_ext_lang_frame_filter (get_current_frame (), flags,
|
||||
NO_VALUES, current_uiout,
|
||||
py_frame_low, frame_high);
|
||||
}
|
||||
|
||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||
if "--no-frame-filters" has been specified from the command. */
|
||||
if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS)
|
||||
if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS)
|
||||
{
|
||||
/* Now let's print the frames up to frame_high, or until there are
|
||||
frames in the stack. */
|
||||
|
@ -200,7 +200,7 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc)
|
|||
{
|
||||
struct frame_info *frame;
|
||||
int raw_arg = 0;
|
||||
enum py_bt_status result = PY_BT_ERROR;
|
||||
enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
|
||||
int print_value;
|
||||
int oind = 0;
|
||||
int skip_unavailable = 0;
|
||||
|
@ -254,13 +254,13 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc)
|
|||
{
|
||||
int flags = PRINT_LEVEL | PRINT_LOCALS;
|
||||
|
||||
result = apply_frame_filter (frame, flags, print_value,
|
||||
current_uiout, 0, 0);
|
||||
result = apply_ext_lang_frame_filter (frame, flags, print_value,
|
||||
current_uiout, 0, 0);
|
||||
}
|
||||
|
||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||
if "--no-frame-filters" has been specified from the command. */
|
||||
if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS)
|
||||
if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS)
|
||||
{
|
||||
list_args_or_locals (locals, print_value, frame,
|
||||
skip_unavailable);
|
||||
|
@ -284,7 +284,7 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
|
|||
int raw_arg = 0;
|
||||
int oind = 0;
|
||||
int skip_unavailable = 0;
|
||||
enum py_bt_status result = PY_BT_ERROR;
|
||||
enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
|
||||
enum opt
|
||||
{
|
||||
NO_FRAME_FILTERS,
|
||||
|
@ -360,14 +360,14 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
|
|||
if (py_frame_low == -1)
|
||||
py_frame_low++;
|
||||
|
||||
result = apply_frame_filter (get_current_frame (), flags,
|
||||
print_values, current_uiout,
|
||||
py_frame_low, frame_high);
|
||||
result = apply_ext_lang_frame_filter (get_current_frame (), flags,
|
||||
print_values, current_uiout,
|
||||
py_frame_low, frame_high);
|
||||
}
|
||||
|
||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||
if "--no-frame-filters" has been specified from the command. */
|
||||
if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS)
|
||||
if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS)
|
||||
{
|
||||
/* Now let's print the frames up to frame_high, or until there are
|
||||
frames in the stack. */
|
||||
|
@ -397,7 +397,7 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc)
|
|||
{
|
||||
struct frame_info *frame;
|
||||
int raw_arg = 0;
|
||||
enum py_bt_status result = PY_BT_ERROR;
|
||||
enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
|
||||
int print_value;
|
||||
int oind = 0;
|
||||
int skip_unavailable = 0;
|
||||
|
@ -450,13 +450,13 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc)
|
|||
{
|
||||
int flags = PRINT_LEVEL | PRINT_ARGS | PRINT_LOCALS;
|
||||
|
||||
result = apply_frame_filter (frame, flags, print_value,
|
||||
current_uiout, 0, 0);
|
||||
result = apply_ext_lang_frame_filter (frame, flags, print_value,
|
||||
current_uiout, 0, 0);
|
||||
}
|
||||
|
||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||
if "--no-frame-filters" has been specified from the command. */
|
||||
if (! frame_filters || raw_arg || result == PY_BT_NO_FILTERS)
|
||||
if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS)
|
||||
{
|
||||
list_args_or_locals (all, print_value, frame,
|
||||
skip_unavailable);
|
||||
|
|
|
@ -52,9 +52,7 @@
|
|||
#include "ctf.h"
|
||||
#include "ada-lang.h"
|
||||
#include "linespec.h"
|
||||
#ifdef HAVE_PYTHON
|
||||
#include "python/python-internal.h"
|
||||
#endif
|
||||
#include "extension.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -1820,10 +1818,8 @@ mi_cmd_list_features (char *command, char **argv, int argc)
|
|||
ui_out_field_string (uiout, NULL, "undefined-command-error-code");
|
||||
ui_out_field_string (uiout, NULL, "exec-run-start-option");
|
||||
|
||||
#if HAVE_PYTHON
|
||||
if (gdb_python_initialized)
|
||||
if (ext_lang_initialized_p (get_ext_lang_defn (EXT_LANG_PYTHON)))
|
||||
ui_out_field_string (uiout, NULL, "python");
|
||||
#endif
|
||||
|
||||
do_cleanups (cleanup);
|
||||
return;
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
#include "objfiles.h"
|
||||
#include "python.h"
|
||||
#include "auto-load.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "python-internal.h"
|
||||
|
||||
/* User-settable option to enable/disable auto-loading of Python scripts:
|
||||
|
@ -45,38 +42,21 @@ show_auto_load_python_scripts (struct ui_file *file, int from_tty,
|
|||
fprintf_filtered (file, _("Auto-loading of Python scripts is %s.\n"), value);
|
||||
}
|
||||
|
||||
/* Return non-zero if auto-loading Python scripts is enabled. */
|
||||
/* Return non-zero if auto-loading Python scripts is enabled.
|
||||
This is the extension_language_script_ops.auto_load_enabled "method". */
|
||||
|
||||
static int
|
||||
auto_load_python_scripts_enabled (void)
|
||||
int
|
||||
gdbpy_auto_load_enabled (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return auto_load_python_scripts;
|
||||
}
|
||||
|
||||
/* Definition of script language for Python scripts. */
|
||||
|
||||
static const struct script_language script_language_python =
|
||||
{
|
||||
"python",
|
||||
GDBPY_AUTO_FILE_NAME,
|
||||
auto_load_python_scripts_enabled,
|
||||
source_python_script_for_objfile
|
||||
};
|
||||
|
||||
/* Return the Python script language definition. */
|
||||
|
||||
const struct script_language *
|
||||
gdbpy_script_language_defn (void)
|
||||
{
|
||||
return &script_language_python;
|
||||
}
|
||||
|
||||
/* Wrapper for "info auto-load python-scripts". */
|
||||
|
||||
static void
|
||||
info_auto_load_python_scripts (char *pattern, int from_tty)
|
||||
{
|
||||
auto_load_info_scripts (pattern, from_tty, &script_language_python);
|
||||
auto_load_info_scripts (pattern, from_tty, &extension_language_python);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -125,16 +105,3 @@ Print the list of automatically loaded Python scripts, deprecated."));
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* ! HAVE_PYTHON */
|
||||
|
||||
/* Return the Python script language definition.
|
||||
Since support isn't compiled in, return NULL. */
|
||||
|
||||
const struct script_language *
|
||||
gdbpy_script_language_defn (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* ! HAVE_PYTHON */
|
||||
|
|
|
@ -750,15 +750,22 @@ gdbpy_breakpoints (PyObject *self, PyObject *args)
|
|||
stopped at the breakpoint. Otherwise the inferior will be
|
||||
allowed to continue. */
|
||||
|
||||
int
|
||||
gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
|
||||
enum ext_lang_bp_stop
|
||||
gdbpy_breakpoint_cond_says_stop (const struct extension_language_defn *extlang,
|
||||
struct breakpoint *b)
|
||||
{
|
||||
int stop = 1;
|
||||
|
||||
int stop;
|
||||
struct gdbpy_breakpoint_object *bp_obj = b->py_bp_object;
|
||||
PyObject *py_bp = (PyObject *) bp_obj;
|
||||
struct breakpoint *b = bp_obj->bp;
|
||||
struct gdbarch *garch = b->gdbarch ? b->gdbarch : get_current_arch ();
|
||||
struct cleanup *cleanup = ensure_python_env (garch, current_language);
|
||||
struct gdbarch *garch;
|
||||
struct cleanup *cleanup;
|
||||
|
||||
if (bp_obj == NULL)
|
||||
return EXT_LANG_BP_STOP_UNSET;
|
||||
|
||||
stop = -1;
|
||||
garch = b->gdbarch ? b->gdbarch : get_current_arch ();
|
||||
cleanup = ensure_python_env (garch, current_language);
|
||||
|
||||
if (bp_obj->is_finish_bp)
|
||||
bpfinishpy_pre_stop_hook (bp_obj);
|
||||
|
@ -767,6 +774,7 @@ gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
|
|||
{
|
||||
PyObject *result = PyObject_CallMethod (py_bp, stop_func, NULL);
|
||||
|
||||
stop = 1;
|
||||
if (result)
|
||||
{
|
||||
int evaluate = PyObject_IsTrue (result);
|
||||
|
@ -790,7 +798,9 @@ gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
|
|||
|
||||
do_cleanups (cleanup);
|
||||
|
||||
return stop;
|
||||
if (stop < 0)
|
||||
return EXT_LANG_BP_STOP_UNSET;
|
||||
return stop ? EXT_LANG_BP_STOP_YES : EXT_LANG_BP_STOP_NO;
|
||||
}
|
||||
|
||||
/* Checks if the "stop" method exists in this breakpoint.
|
||||
|
@ -798,17 +808,21 @@ gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
|
|||
conditions. */
|
||||
|
||||
int
|
||||
gdbpy_breakpoint_has_py_cond (struct gdbpy_breakpoint_object *bp_obj)
|
||||
gdbpy_breakpoint_has_cond (const struct extension_language_defn *extlang,
|
||||
struct breakpoint *b)
|
||||
{
|
||||
int has_func = 0;
|
||||
PyObject *py_bp = (PyObject *) bp_obj;
|
||||
struct gdbarch *garch = bp_obj->bp->gdbarch ? bp_obj->bp->gdbarch :
|
||||
get_current_arch ();
|
||||
struct cleanup *cleanup = ensure_python_env (garch, current_language);
|
||||
int has_func;
|
||||
PyObject *py_bp;
|
||||
struct gdbarch *garch;
|
||||
struct cleanup *cleanup;
|
||||
|
||||
if (py_bp != NULL)
|
||||
has_func = PyObject_HasAttrString (py_bp, stop_func);
|
||||
if (b->py_bp_object == NULL)
|
||||
return 0;
|
||||
|
||||
py_bp = (PyObject *) b->py_bp_object;
|
||||
garch = b->gdbarch ? b->gdbarch : get_current_arch ();
|
||||
cleanup = ensure_python_env (garch, current_language);
|
||||
has_func = PyObject_HasAttrString (py_bp, stop_func);
|
||||
do_cleanups (cleanup);
|
||||
|
||||
return has_func;
|
||||
|
@ -947,16 +961,30 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v)
|
|||
return -1;
|
||||
|
||||
/* If the attribute trying to be set is the "stop" method,
|
||||
but we already have a condition set in the CLI, disallow this
|
||||
operation. */
|
||||
if (strcmp (attr, stop_func) == 0 && obj->bp->cond_string)
|
||||
but we already have a condition set in the CLI or other extension
|
||||
language, disallow this operation. */
|
||||
if (strcmp (attr, stop_func) == 0)
|
||||
{
|
||||
xfree (attr);
|
||||
PyErr_SetString (PyExc_RuntimeError,
|
||||
_("Cannot set 'stop' method. There is an " \
|
||||
"existing GDB condition attached to the " \
|
||||
"breakpoint."));
|
||||
return -1;
|
||||
const struct extension_language_defn *extlang = NULL;
|
||||
|
||||
if (obj->bp->cond_string != NULL)
|
||||
extlang = get_ext_lang_defn (EXT_LANG_GDB);
|
||||
if (extlang == NULL)
|
||||
extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON);
|
||||
if (extlang != NULL)
|
||||
{
|
||||
char *error_text;
|
||||
|
||||
xfree (attr);
|
||||
error_text
|
||||
= xstrprintf (_("Only one stop condition allowed. There is"
|
||||
" currently a %s stop condition defined for"
|
||||
" this breakpoint."),
|
||||
ext_lang_capitalized_name (extlang));
|
||||
PyErr_SetString (PyExc_RuntimeError, error_text);
|
||||
xfree (error_text);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
xfree (attr);
|
||||
|
|
|
@ -48,17 +48,17 @@ enum mi_print_types
|
|||
this will be set to NULL. LANGUAGE is also a pass-through argument
|
||||
denoting the language attributed to the Symbol. In the case of SYM
|
||||
being NULL, this will be set to the current language. Returns
|
||||
PY_BT_ERROR on error with the appropriate Python exception set, and
|
||||
PY_BT_OK on success. */
|
||||
EXT_LANG_BT_ERROR on error with the appropriate Python exception set, and
|
||||
EXT_LANG_BT_OK on success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
extract_sym (PyObject *obj, char **name, struct symbol **sym,
|
||||
const struct language_defn **language)
|
||||
{
|
||||
PyObject *result = PyObject_CallMethod (obj, "symbol", NULL);
|
||||
|
||||
if (result == NULL)
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
|
||||
/* For 'symbol' callback, the function can return a symbol or a
|
||||
string. */
|
||||
|
@ -68,7 +68,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
|
|||
Py_DECREF (result);
|
||||
|
||||
if (*name == NULL)
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
/* If the API returns a string (and not a symbol), then there is
|
||||
no symbol derived language available and the frame filter has
|
||||
either overridden the symbol with a string, or supplied a
|
||||
|
@ -90,7 +90,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
|
|||
PyErr_SetString (PyExc_RuntimeError,
|
||||
_("Unexpected value. Expecting a "
|
||||
"gdb.Symbol or a Python string."));
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
/* Duplicate the symbol name, so the caller has consistency
|
||||
|
@ -106,7 +106,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
|
|||
*language = current_language;
|
||||
}
|
||||
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
}
|
||||
|
||||
/* Helper function to extract a value from an object that conforms to
|
||||
|
@ -114,11 +114,11 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
|
|||
the value from. VALUE is a pass-through argument where the value
|
||||
will be written. If the object does not have the value attribute,
|
||||
or provides the Python None for a value, VALUE will be set to NULL
|
||||
and this function will return as successful. Returns PY_BT_ERROR
|
||||
on error with the appropriate Python exception set, and PY_BT_OK on
|
||||
and this function will return as successful. Returns EXT_LANG_BT_ERROR
|
||||
on error with the appropriate Python exception set, and EXT_LANG_BT_OK on
|
||||
success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
extract_value (PyObject *obj, struct value **value)
|
||||
{
|
||||
if (PyObject_HasAttrString (obj, "value"))
|
||||
|
@ -126,7 +126,7 @@ extract_value (PyObject *obj, struct value **value)
|
|||
PyObject *vresult = PyObject_CallMethod (obj, "value", NULL);
|
||||
|
||||
if (vresult == NULL)
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
|
||||
/* The Python code has returned 'None' for a value, so we set
|
||||
value to NULL. This flags that GDB should read the
|
||||
|
@ -135,7 +135,7 @@ extract_value (PyObject *obj, struct value **value)
|
|||
{
|
||||
Py_DECREF (vresult);
|
||||
*value = NULL;
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -143,15 +143,15 @@ extract_value (PyObject *obj, struct value **value)
|
|||
Py_DECREF (vresult);
|
||||
|
||||
if (*value == NULL)
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
*value = NULL;
|
||||
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
}
|
||||
|
||||
/* MI prints only certain values according to the type of symbol and
|
||||
|
@ -195,11 +195,11 @@ mi_should_print (struct symbol *sym, enum mi_print_types type)
|
|||
/* Helper function which outputs a type name extracted from VAL to a
|
||||
"type" field in the output stream OUT. OUT is the ui-out structure
|
||||
the type name will be output too, and VAL is the value that the
|
||||
type will be extracted from. Returns PY_BT_ERROR on error, with
|
||||
any GDB exceptions converted to a Python exception, or PY_BT_OK on
|
||||
type will be extracted from. Returns EXT_LANG_BT_ERROR on error, with
|
||||
any GDB exceptions converted to a Python exception, or EXT_LANG_BT_OK on
|
||||
success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
py_print_type (struct ui_out *out, struct value *val)
|
||||
{
|
||||
volatile struct gdb_exception except;
|
||||
|
@ -220,10 +220,10 @@ py_print_type (struct ui_out *out, struct value *val)
|
|||
if (except.reason < 0)
|
||||
{
|
||||
gdbpy_convert_exception (except);
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
}
|
||||
|
||||
/* Helper function which outputs a value to an output field in a
|
||||
|
@ -231,15 +231,15 @@ py_print_type (struct ui_out *out, struct value *val)
|
|||
VAL is the value that will be printed, OPTS contains the value
|
||||
printing options, ARGS_TYPE is an enumerator describing the
|
||||
argument format, and LANGUAGE is the language_defn that the value
|
||||
will be printed with. Returns PY_BT_ERROR on error, with any GDB
|
||||
exceptions converted to a Python exception, or PY_BT_OK on
|
||||
will be printed with. Returns EXT_LANG_BT_ERROR on error, with any GDB
|
||||
exceptions converted to a Python exception, or EXT_LANG_BT_OK on
|
||||
success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
py_print_value (struct ui_out *out, struct value *val,
|
||||
const struct value_print_options *opts,
|
||||
int indent,
|
||||
enum py_frame_args args_type,
|
||||
enum ext_lang_frame_args args_type,
|
||||
const struct language_defn *language)
|
||||
{
|
||||
int should_print = 0;
|
||||
|
@ -265,7 +265,7 @@ py_print_value (struct ui_out *out, struct value *val,
|
|||
if (except.reason < 0)
|
||||
{
|
||||
gdbpy_convert_exception (except);
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
if (args_type == MI_PRINT_ALL_VALUES)
|
||||
|
@ -295,11 +295,11 @@ py_print_value (struct ui_out *out, struct value *val,
|
|||
if (except.reason < 0)
|
||||
{
|
||||
gdbpy_convert_exception (except);
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
}
|
||||
|
||||
/* Helper function to call a Python method and extract an iterator
|
||||
|
@ -350,16 +350,16 @@ get_py_iter_from_func (PyObject *filter, char *func)
|
|||
ARGS_TYPE is an enumerator describing the argument format,
|
||||
PRINT_ARGS_FIELD is a flag which indicates if we output "ARGS=1"
|
||||
in MI output in commands where both arguments and locals are
|
||||
printed. Returns PY_BT_ERROR on error, with any GDB exceptions
|
||||
converted to a Python exception, or PY_BT_OK on success. */
|
||||
printed. Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions
|
||||
converted to a Python exception, or EXT_LANG_BT_OK on success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
py_print_single_arg (struct ui_out *out,
|
||||
const char *sym_name,
|
||||
struct frame_arg *fa,
|
||||
struct value *fv,
|
||||
const struct value_print_options *opts,
|
||||
enum py_frame_args args_type,
|
||||
enum ext_lang_frame_args args_type,
|
||||
int print_args_field,
|
||||
const struct language_defn *language)
|
||||
{
|
||||
|
@ -435,7 +435,7 @@ py_print_single_arg (struct ui_out *out,
|
|||
types. */
|
||||
if (args_type == MI_PRINT_SIMPLE_VALUES)
|
||||
{
|
||||
if (py_print_type (out, val) == PY_BT_ERROR)
|
||||
if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
do_cleanups (cleanups);
|
||||
goto error;
|
||||
|
@ -455,7 +455,7 @@ py_print_single_arg (struct ui_out *out,
|
|||
if (args_type != NO_VALUES)
|
||||
{
|
||||
if (py_print_value (out, val, opts, 0, args_type, language)
|
||||
== PY_BT_ERROR)
|
||||
== EXT_LANG_BT_ERROR)
|
||||
{
|
||||
do_cleanups (cleanups);
|
||||
goto error;
|
||||
|
@ -471,10 +471,10 @@ py_print_single_arg (struct ui_out *out,
|
|||
goto error;
|
||||
}
|
||||
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
|
||||
error:
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
/* Helper function to loop over frame arguments provided by the
|
||||
|
@ -484,14 +484,14 @@ py_print_single_arg (struct ui_out *out,
|
|||
enumerator describing the argument format, PRINT_ARGS_FIELD is a
|
||||
flag which indicates if we output "ARGS=1" in MI output in commands
|
||||
where both arguments and locals are printed, and FRAME is the
|
||||
backing frame. Returns PY_BT_ERROR on error, with any GDB
|
||||
exceptions converted to a Python exception, or PY_BT_OK on
|
||||
backing frame. Returns EXT_LANG_BT_ERROR on error, with any GDB
|
||||
exceptions converted to a Python exception, or EXT_LANG_BT_OK on
|
||||
success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
enumerate_args (PyObject *iter,
|
||||
struct ui_out *out,
|
||||
enum py_frame_args args_type,
|
||||
enum ext_lang_frame_args args_type,
|
||||
int print_args_field,
|
||||
struct frame_info *frame)
|
||||
{
|
||||
|
@ -533,17 +533,17 @@ enumerate_args (PyObject *iter,
|
|||
char *sym_name;
|
||||
struct symbol *sym;
|
||||
struct value *val;
|
||||
enum py_bt_status success = PY_BT_ERROR;
|
||||
enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
|
||||
|
||||
success = extract_sym (item, &sym_name, &sym, &language);
|
||||
if (success == PY_BT_ERROR)
|
||||
if (success == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
Py_DECREF (item);
|
||||
goto error;
|
||||
}
|
||||
|
||||
success = extract_value (item, &val);
|
||||
if (success == PY_BT_ERROR)
|
||||
if (success == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
xfree (sym_name);
|
||||
Py_DECREF (item);
|
||||
|
@ -597,7 +597,7 @@ enumerate_args (PyObject *iter,
|
|||
NULL, &opts,
|
||||
args_type,
|
||||
print_args_field,
|
||||
NULL) == PY_BT_ERROR)
|
||||
NULL) == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
xfree (arg.error);
|
||||
xfree (entryarg.error);
|
||||
|
@ -625,9 +625,9 @@ enumerate_args (PyObject *iter,
|
|||
}
|
||||
}
|
||||
|
||||
if (py_print_single_arg (out, NULL, &entryarg, NULL,
|
||||
&opts, args_type,
|
||||
print_args_field, NULL) == PY_BT_ERROR)
|
||||
if (py_print_single_arg (out, NULL, &entryarg, NULL, &opts,
|
||||
args_type, print_args_field, NULL)
|
||||
== EXT_LANG_BT_ERROR)
|
||||
{
|
||||
xfree (arg.error);
|
||||
xfree (entryarg.error);
|
||||
|
@ -646,7 +646,7 @@ enumerate_args (PyObject *iter,
|
|||
{
|
||||
if (py_print_single_arg (out, sym_name, NULL, val, &opts,
|
||||
args_type, print_args_field,
|
||||
language) == PY_BT_ERROR)
|
||||
language) == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
xfree (sym_name);
|
||||
goto error;
|
||||
|
@ -688,10 +688,10 @@ enumerate_args (PyObject *iter,
|
|||
}
|
||||
}
|
||||
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
|
||||
error:
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -703,14 +703,14 @@ enumerate_args (PyObject *iter,
|
|||
the argument format, PRINT_ARGS_FIELD is flag which indicates
|
||||
whether to output the ARGS field in the case of
|
||||
-stack-list-variables and FRAME is the backing frame. Returns
|
||||
PY_BT_ERROR on error, with any GDB exceptions converted to a Python
|
||||
exception, or PY_BT_OK on success. */
|
||||
EXT_LANG_BT_ERROR on error, with any GDB exceptions converted to a Python
|
||||
exception, or EXT_LANG_BT_OK on success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
enumerate_locals (PyObject *iter,
|
||||
struct ui_out *out,
|
||||
int indent,
|
||||
enum py_frame_args args_type,
|
||||
enum ext_lang_frame_args args_type,
|
||||
int print_args_field,
|
||||
struct frame_info *frame)
|
||||
{
|
||||
|
@ -725,7 +725,7 @@ enumerate_locals (PyObject *iter,
|
|||
const struct language_defn *language;
|
||||
char *sym_name;
|
||||
struct value *val;
|
||||
enum py_bt_status success = PY_BT_ERROR;
|
||||
enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
|
||||
struct symbol *sym;
|
||||
volatile struct gdb_exception except;
|
||||
int local_indent = 8 + (8 * indent);
|
||||
|
@ -734,7 +734,7 @@ enumerate_locals (PyObject *iter,
|
|||
locals_cleanups = make_cleanup_py_decref (item);
|
||||
|
||||
success = extract_sym (item, &sym_name, &sym, &language);
|
||||
if (success == PY_BT_ERROR)
|
||||
if (success == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
do_cleanups (locals_cleanups);
|
||||
goto error;
|
||||
|
@ -743,7 +743,7 @@ enumerate_locals (PyObject *iter,
|
|||
make_cleanup (xfree, sym_name);
|
||||
|
||||
success = extract_value (item, &val);
|
||||
if (success == PY_BT_ERROR)
|
||||
if (success == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
do_cleanups (locals_cleanups);
|
||||
goto error;
|
||||
|
@ -801,7 +801,7 @@ enumerate_locals (PyObject *iter,
|
|||
|
||||
if (args_type == MI_PRINT_SIMPLE_VALUES)
|
||||
{
|
||||
if (py_print_type (out, val) == PY_BT_ERROR)
|
||||
if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
do_cleanups (locals_cleanups);
|
||||
goto error;
|
||||
|
@ -815,7 +815,7 @@ enumerate_locals (PyObject *iter,
|
|||
int val_indent = (indent + 1) * 4;
|
||||
|
||||
if (py_print_value (out, val, &opts, val_indent, args_type,
|
||||
language) == PY_BT_ERROR)
|
||||
language) == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
do_cleanups (locals_cleanups);
|
||||
goto error;
|
||||
|
@ -826,7 +826,7 @@ enumerate_locals (PyObject *iter,
|
|||
if (args_type != NO_VALUES)
|
||||
{
|
||||
if (py_print_value (out, val, &opts, 0, args_type,
|
||||
language) == PY_BT_ERROR)
|
||||
language) == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
do_cleanups (locals_cleanups);
|
||||
goto error;
|
||||
|
@ -850,19 +850,19 @@ enumerate_locals (PyObject *iter,
|
|||
if (item == NULL && PyErr_Occurred ())
|
||||
goto error;
|
||||
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
|
||||
error:
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
/* Helper function for -stack-list-variables. Returns PY_BT_ERROR on
|
||||
error, or PY_BT_OK on success. */
|
||||
/* Helper function for -stack-list-variables. Returns EXT_LANG_BT_ERROR on
|
||||
error, or EXT_LANG_BT_OK on success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
py_mi_print_variables (PyObject *filter, struct ui_out *out,
|
||||
struct value_print_options *opts,
|
||||
enum py_frame_args args_type,
|
||||
enum ext_lang_frame_args args_type,
|
||||
struct frame_info *frame)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
|
@ -882,30 +882,31 @@ py_mi_print_variables (PyObject *filter, struct ui_out *out,
|
|||
make_cleanup_ui_out_list_begin_end (out, "variables");
|
||||
|
||||
if (args_iter != Py_None)
|
||||
if (enumerate_args (args_iter, out, args_type, 1, frame) == PY_BT_ERROR)
|
||||
if (enumerate_args (args_iter, out, args_type, 1, frame)
|
||||
== EXT_LANG_BT_ERROR)
|
||||
goto error;
|
||||
|
||||
if (locals_iter != Py_None)
|
||||
if (enumerate_locals (locals_iter, out, 1, args_type, 1, frame)
|
||||
== PY_BT_ERROR)
|
||||
== EXT_LANG_BT_ERROR)
|
||||
goto error;
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
|
||||
error:
|
||||
do_cleanups (old_chain);
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
/* Helper function for printing locals. This function largely just
|
||||
creates the wrapping tuple, and calls enumerate_locals. Returns
|
||||
PY_BT_ERROR on error, or PY_BT_OK on success.*/
|
||||
EXT_LANG_BT_ERROR on error, or EXT_LANG_BT_OK on success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
py_print_locals (PyObject *filter,
|
||||
struct ui_out *out,
|
||||
enum py_frame_args args_type,
|
||||
enum ext_lang_frame_args args_type,
|
||||
int indent,
|
||||
struct frame_info *frame)
|
||||
{
|
||||
|
@ -920,26 +921,26 @@ py_print_locals (PyObject *filter,
|
|||
|
||||
if (locals_iter != Py_None)
|
||||
if (enumerate_locals (locals_iter, out, indent, args_type,
|
||||
0, frame) == PY_BT_ERROR)
|
||||
0, frame) == EXT_LANG_BT_ERROR)
|
||||
goto locals_error;
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return PY_BT_OK;;
|
||||
return EXT_LANG_BT_OK;
|
||||
|
||||
locals_error:
|
||||
do_cleanups (old_chain);
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
/* Helper function for printing frame arguments. This function
|
||||
largely just creates the wrapping tuple, and calls enumerate_args.
|
||||
Returns PY_BT_ERROR on error, with any GDB exceptions converted to
|
||||
a Python exception, or PY_BT_OK on success. */
|
||||
Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions converted to
|
||||
a Python exception, or EXT_LANG_BT_OK on success. */
|
||||
|
||||
static enum py_bt_status
|
||||
static enum ext_lang_bt_status
|
||||
py_print_args (PyObject *filter,
|
||||
struct ui_out *out,
|
||||
enum py_frame_args args_type,
|
||||
enum ext_lang_frame_args args_type,
|
||||
struct frame_info *frame)
|
||||
{
|
||||
PyObject *args_iter = get_py_iter_from_func (filter, "frame_args");
|
||||
|
@ -964,7 +965,8 @@ py_print_args (PyObject *filter,
|
|||
}
|
||||
|
||||
if (args_iter != Py_None)
|
||||
if (enumerate_args (args_iter, out, args_type, 0, frame) == PY_BT_ERROR)
|
||||
if (enumerate_args (args_iter, out, args_type, 0, frame)
|
||||
== EXT_LANG_BT_ERROR)
|
||||
goto args_error;
|
||||
|
||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||
|
@ -979,11 +981,11 @@ py_print_args (PyObject *filter,
|
|||
}
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return PY_BT_OK;
|
||||
return EXT_LANG_BT_OK;
|
||||
|
||||
args_error:
|
||||
do_cleanups (old_chain);
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
/* Print a single frame to the designated output stream, detecting
|
||||
|
@ -997,12 +999,13 @@ py_print_args (PyObject *filter,
|
|||
(in the case of elided frames), and LEVELS_PRINTED is a hash-table
|
||||
containing all the frames level that have already been printed.
|
||||
If a frame level has been printed, do not print it again (in the
|
||||
case of elided frames). Returns PY_BT_ERROR on error, with any
|
||||
GDB exceptions converted to a Python exception, or PY_BT_COMPLETED
|
||||
case of elided frames). Returns EXT_LANG_BT_ERROR on error, with any
|
||||
GDB exceptions converted to a Python exception, or EXT_LANG_BT_COMPLETED
|
||||
on success. */
|
||||
|
||||
static enum py_bt_status
|
||||
py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
||||
static enum ext_lang_bt_status
|
||||
py_print_frame (PyObject *filter, int flags,
|
||||
enum ext_lang_frame_args args_type,
|
||||
struct ui_out *out, int indent, htab_t levels_printed)
|
||||
{
|
||||
int has_addr = 0;
|
||||
|
@ -1052,12 +1055,12 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
|||
if (print_locals && print_args && ! print_frame_info)
|
||||
{
|
||||
if (py_mi_print_variables (filter, out, &opts,
|
||||
args_type, frame) == PY_BT_ERROR)
|
||||
args_type, frame) == EXT_LANG_BT_ERROR)
|
||||
goto error;
|
||||
else
|
||||
{
|
||||
do_cleanups (cleanup_stack);
|
||||
return PY_BT_COMPLETED;
|
||||
return EXT_LANG_BT_COMPLETED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1230,7 +1233,7 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
|||
wrong. */
|
||||
if (print_args)
|
||||
{
|
||||
if (py_print_args (filter, out, args_type, frame) == PY_BT_ERROR)
|
||||
if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR)
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -1334,7 +1337,7 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
|||
if (print_locals)
|
||||
{
|
||||
if (py_print_locals (filter, out, args_type, indent,
|
||||
frame) == PY_BT_ERROR)
|
||||
frame) == EXT_LANG_BT_ERROR)
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -1355,12 +1358,12 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
|||
|
||||
while ((item = PyIter_Next (elided)))
|
||||
{
|
||||
enum py_bt_status success = py_print_frame (item, flags,
|
||||
args_type, out,
|
||||
indent,
|
||||
levels_printed);
|
||||
enum ext_lang_bt_status success = py_print_frame (item, flags,
|
||||
args_type, out,
|
||||
indent,
|
||||
levels_printed);
|
||||
|
||||
if (success == PY_BT_ERROR)
|
||||
if (success == EXT_LANG_BT_ERROR)
|
||||
{
|
||||
Py_DECREF (item);
|
||||
goto error;
|
||||
|
@ -1374,11 +1377,11 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
|||
|
||||
|
||||
do_cleanups (cleanup_stack);
|
||||
return PY_BT_COMPLETED;
|
||||
return EXT_LANG_BT_COMPLETED;
|
||||
|
||||
error:
|
||||
do_cleanups (cleanup_stack);
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
||||
/* Helper function to initiate frame filter invocation at starting
|
||||
|
@ -1456,26 +1459,25 @@ bootstrap_python_frame_filters (struct frame_info *frame,
|
|||
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 PY_BT_ERROR on error,
|
||||
or PY_BT_COMPLETED on success.*/
|
||||
|
||||
enum py_bt_status
|
||||
apply_frame_filter (struct frame_info *frame, int flags,
|
||||
enum py_frame_args args_type,
|
||||
struct ui_out *out, int frame_low,
|
||||
int frame_high)
|
||||
upper limit of the frames to count. Returns EXT_LANG_BT_ERROR on error,
|
||||
or EXT_LANG_BT_COMPLETED on success. */
|
||||
|
||||
enum ext_lang_bt_status
|
||||
gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
|
||||
struct frame_info *frame, int flags,
|
||||
enum ext_lang_frame_args args_type,
|
||||
struct ui_out *out, int frame_low, int frame_high)
|
||||
{
|
||||
struct gdbarch *gdbarch = NULL;
|
||||
struct cleanup *cleanups;
|
||||
enum py_bt_status success = PY_BT_ERROR;
|
||||
enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
|
||||
PyObject *iterable;
|
||||
volatile struct gdb_exception except;
|
||||
PyObject *item;
|
||||
htab_t levels_printed;
|
||||
|
||||
if (!gdb_python_initialized)
|
||||
return PY_BT_NO_FILTERS;
|
||||
return EXT_LANG_BT_NO_FILTERS;
|
||||
|
||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
|
@ -1484,7 +1486,7 @@ apply_frame_filter (struct frame_info *frame, int flags,
|
|||
if (except.reason < 0)
|
||||
{
|
||||
/* Let gdb try to print the stack trace. */
|
||||
return PY_BT_NO_FILTERS;
|
||||
return EXT_LANG_BT_NO_FILTERS;
|
||||
}
|
||||
|
||||
cleanups = ensure_python_env (gdbarch, current_language);
|
||||
|
@ -1501,14 +1503,14 @@ apply_frame_filter (struct frame_info *frame, int flags,
|
|||
where GDB cannot initialize the frame filters (most likely
|
||||
due to incorrect auto-load paths), GDB has printed nothing.
|
||||
In this case it is OK to print the default backtrace after
|
||||
printing the error message. GDB returns PY_BT_NO_FILTERS
|
||||
printing the error message. GDB returns EXT_LANG_BT_NO_FILTERS
|
||||
here to signify there are no filters after printing the
|
||||
initialization error. This return code will trigger a
|
||||
default backtrace. */
|
||||
|
||||
gdbpy_print_stack ();
|
||||
do_cleanups (cleanups);
|
||||
return PY_BT_NO_FILTERS;
|
||||
return EXT_LANG_BT_NO_FILTERS;
|
||||
}
|
||||
|
||||
/* If iterable is None, then there are no frame filters registered.
|
||||
|
@ -1517,7 +1519,7 @@ apply_frame_filter (struct frame_info *frame, int flags,
|
|||
make_cleanup_py_decref (iterable);
|
||||
if (iterable == Py_None)
|
||||
{
|
||||
success = PY_BT_NO_FILTERS;
|
||||
success = EXT_LANG_BT_NO_FILTERS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1534,7 +1536,7 @@ apply_frame_filter (struct frame_info *frame, int flags,
|
|||
|
||||
/* Do not exit on error printing a single frame. Print the
|
||||
error and continue with other frames. */
|
||||
if (success == PY_BT_ERROR)
|
||||
if (success == EXT_LANG_BT_ERROR)
|
||||
gdbpy_print_stack ();
|
||||
|
||||
Py_DECREF (item);
|
||||
|
@ -1552,5 +1554,5 @@ apply_frame_filter (struct frame_info *frame, int flags,
|
|||
error:
|
||||
gdbpy_print_stack ();
|
||||
do_cleanups (cleanups);
|
||||
return PY_BT_ERROR;
|
||||
return EXT_LANG_BT_ERROR;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,8 @@
|
|||
#include "symtab.h"
|
||||
#include "language.h"
|
||||
#include "valprint.h"
|
||||
|
||||
#include "extension-priv.h"
|
||||
#include "python.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
#include "python-internal.h"
|
||||
|
||||
/* Return type of print_string_repr. */
|
||||
|
@ -300,7 +298,7 @@ print_stack_unless_memory_error (struct ui_file *stream)
|
|||
gdbpy_print_stack ();
|
||||
}
|
||||
|
||||
/* Helper for apply_val_pretty_printer which calls to_string and
|
||||
/* Helper for gdbpy_apply_val_pretty_printer which calls to_string and
|
||||
formats the result. */
|
||||
|
||||
static enum string_repr_result
|
||||
|
@ -467,7 +465,7 @@ push_dummy_python_frame (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Helper for apply_val_pretty_printer that formats children of the
|
||||
/* Helper for gdbpy_apply_val_pretty_printer that formats children of the
|
||||
printer, if any exist. If is_py_none is true, then nothing has
|
||||
been printed by to_string, and format output accordingly. */
|
||||
static void
|
||||
|
@ -686,13 +684,14 @@ print_children (PyObject *printer, const char *hint,
|
|||
do_cleanups (cleanups);
|
||||
}
|
||||
|
||||
int
|
||||
apply_val_pretty_printer (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)
|
||||
enum ext_lang_rc
|
||||
gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
|
||||
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)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_type_arch (type);
|
||||
PyObject *printer = NULL;
|
||||
|
@ -700,15 +699,15 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
|
|||
struct value *value;
|
||||
char *hint = NULL;
|
||||
struct cleanup *cleanups;
|
||||
int result = 0;
|
||||
enum ext_lang_rc result = EXT_LANG_RC_NOP;
|
||||
enum string_repr_result print_result;
|
||||
|
||||
/* No pretty-printer support for unavailable values. */
|
||||
if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
|
||||
return 0;
|
||||
return EXT_LANG_RC_NOP;
|
||||
|
||||
if (!gdb_python_initialized)
|
||||
return 0;
|
||||
return EXT_LANG_RC_NOP;
|
||||
|
||||
cleanups = ensure_python_env (gdbarch, language);
|
||||
|
||||
|
@ -728,18 +727,27 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
|
|||
|
||||
val_obj = value_to_value_object (value);
|
||||
if (! val_obj)
|
||||
goto done;
|
||||
{
|
||||
result = EXT_LANG_RC_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Find the constructor. */
|
||||
printer = find_pretty_printer (val_obj);
|
||||
Py_DECREF (val_obj);
|
||||
|
||||
if (printer == NULL)
|
||||
goto done;
|
||||
{
|
||||
result = EXT_LANG_RC_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
make_cleanup_py_decref (printer);
|
||||
if (printer == Py_None)
|
||||
goto done;
|
||||
{
|
||||
result = EXT_LANG_RC_NOP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If we are printing a map, we want some special formatting. */
|
||||
hint = gdbpy_get_display_hint (printer);
|
||||
|
@ -752,8 +760,7 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
|
|||
print_children (printer, hint, stream, recurse, options, language,
|
||||
print_result == string_repr_none);
|
||||
|
||||
result = 1;
|
||||
|
||||
result = EXT_LANG_RC_OK;
|
||||
|
||||
done:
|
||||
if (PyErr_Occurred ())
|
||||
|
@ -838,18 +845,3 @@ gdbpy_default_visualizer (PyObject *self, PyObject *args)
|
|||
cons = find_pretty_printer (val_obj);
|
||||
return cons;
|
||||
}
|
||||
|
||||
#else /* HAVE_PYTHON */
|
||||
|
||||
int
|
||||
apply_val_pretty_printer (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)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PYTHON */
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "cp-abi.h"
|
||||
#include "python.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "python-internal.h"
|
||||
|
||||
/* Even though Python scalar types directly map to host types, we use
|
||||
|
@ -163,7 +161,8 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
|
|||
/* Iterate over all the Value objects, calling preserve_one_value on
|
||||
each. */
|
||||
void
|
||||
preserve_python_values (struct objfile *objfile, htab_t copied_types)
|
||||
gdbpy_preserve_values (const struct extension_language_defn *extlang,
|
||||
struct objfile *objfile, htab_t copied_types)
|
||||
{
|
||||
value_object *iter;
|
||||
|
||||
|
@ -1702,13 +1701,3 @@ PyTypeObject value_object_type = {
|
|||
0, /* tp_alloc */
|
||||
valpy_new /* tp_new */
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
preserve_python_values (struct objfile *objfile, htab_t copied_types)
|
||||
{
|
||||
/* Nothing. */
|
||||
}
|
||||
|
||||
#endif /* HAVE_PYTHON */
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef GDB_PYTHON_INTERNAL_H
|
||||
#define GDB_PYTHON_INTERNAL_H
|
||||
|
||||
#include "extension.h"
|
||||
|
||||
/* These WITH_* macros are defined by the CPython API checker that
|
||||
comes with the Python plugin for GCC. See:
|
||||
https://gcc-python-plugin.readthedocs.org/en/latest/cpychecker.html
|
||||
|
@ -279,7 +281,33 @@ typedef struct
|
|||
|
||||
extern struct cmd_list_element *set_python_list;
|
||||
extern struct cmd_list_element *show_python_list;
|
||||
|
||||
/* extension_language_script_ops "methods". */
|
||||
|
||||
extern int gdbpy_auto_load_enabled (const struct extension_language_defn *);
|
||||
|
||||
/* extension_language_ops "methods". */
|
||||
|
||||
extern enum ext_lang_rc gdbpy_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);
|
||||
extern enum ext_lang_bt_status gdbpy_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);
|
||||
extern void gdbpy_preserve_values (const struct extension_language_defn *,
|
||||
struct objfile *objfile,
|
||||
htab_t copied_types);
|
||||
extern enum ext_lang_bp_stop gdbpy_breakpoint_cond_says_stop
|
||||
(const struct extension_language_defn *, struct breakpoint *);
|
||||
extern int gdbpy_breakpoint_has_cond (const struct extension_language_defn *,
|
||||
struct breakpoint *b);
|
||||
|
||||
PyObject *gdbpy_history (PyObject *self, PyObject *args);
|
||||
PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
|
||||
PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
|
||||
|
@ -436,9 +464,6 @@ extern const struct language_defn *python_language;
|
|||
|
||||
void gdbpy_print_stack (void);
|
||||
|
||||
void source_python_script_for_objfile (struct objfile *objfile, FILE *file,
|
||||
const char *filename);
|
||||
|
||||
PyObject *python_string_to_unicode (PyObject *obj);
|
||||
char *unicode_to_target_string (PyObject *unicode_str);
|
||||
char *python_string_to_target_string (PyObject *obj);
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#include "serial.h"
|
||||
#include "readline/tilde.h"
|
||||
#include "python.h"
|
||||
#include "extension-priv.h"
|
||||
#include "cli/cli-utils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/* Declared constants and enum for python stack printing. */
|
||||
|
@ -56,6 +56,34 @@ static const char *const python_excp_enums[] =
|
|||
the default. */
|
||||
static const char *gdbpy_should_print_stack = python_excp_message;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
/* Forward decls, these are defined later. */
|
||||
static const struct extension_language_script_ops python_extension_script_ops;
|
||||
static const struct extension_language_ops python_extension_ops;
|
||||
#endif
|
||||
|
||||
/* The main struct describing GDB's interface to the Python
|
||||
extension language. */
|
||||
const struct extension_language_defn extension_language_python =
|
||||
{
|
||||
EXT_LANG_PYTHON,
|
||||
"python",
|
||||
"Python",
|
||||
|
||||
".py",
|
||||
"-gdb.py",
|
||||
|
||||
python_control,
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
&python_extension_script_ops,
|
||||
&python_extension_ops
|
||||
#else
|
||||
NULL,
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "libiberty.h"
|
||||
|
@ -69,7 +97,6 @@ static const char *gdbpy_should_print_stack = python_excp_message;
|
|||
#include "version.h"
|
||||
#include "target.h"
|
||||
#include "gdbthread.h"
|
||||
#include "observer.h"
|
||||
#include "interps.h"
|
||||
#include "event-top.h"
|
||||
|
||||
|
@ -104,6 +131,64 @@ PyObject *gdbpy_gdb_error;
|
|||
/* The `gdb.MemoryError' exception. */
|
||||
PyObject *gdbpy_gdb_memory_error;
|
||||
|
||||
static script_sourcer_func gdbpy_source_script;
|
||||
static objfile_script_sourcer_func gdbpy_source_objfile_script;
|
||||
static void gdbpy_finish_initialization
|
||||
(const struct extension_language_defn *);
|
||||
static int gdbpy_initialized (const struct extension_language_defn *);
|
||||
static void gdbpy_eval_from_control_command
|
||||
(const struct extension_language_defn *, struct command_line *cmd);
|
||||
static void gdbpy_start_type_printers (const struct extension_language_defn *,
|
||||
struct ext_lang_type_printers *);
|
||||
static enum ext_lang_rc gdbpy_apply_type_printers
|
||||
(const struct extension_language_defn *,
|
||||
const struct ext_lang_type_printers *, struct type *, char **);
|
||||
static void gdbpy_free_type_printers (const struct extension_language_defn *,
|
||||
struct ext_lang_type_printers *);
|
||||
static void gdbpy_clear_quit_flag (const struct extension_language_defn *);
|
||||
static void gdbpy_set_quit_flag (const struct extension_language_defn *);
|
||||
static int gdbpy_check_quit_flag (const struct extension_language_defn *);
|
||||
static enum ext_lang_rc gdbpy_before_prompt_hook
|
||||
(const struct extension_language_defn *, const char *current_gdb_prompt);
|
||||
|
||||
/* The interface between gdb proper and loading of python scripts. */
|
||||
|
||||
static const struct extension_language_script_ops python_extension_script_ops =
|
||||
{
|
||||
gdbpy_source_script,
|
||||
gdbpy_source_objfile_script,
|
||||
gdbpy_auto_load_enabled
|
||||
};
|
||||
|
||||
/* The interface between gdb proper and python extensions. */
|
||||
|
||||
static const struct extension_language_ops python_extension_ops =
|
||||
{
|
||||
gdbpy_finish_initialization,
|
||||
gdbpy_initialized,
|
||||
|
||||
gdbpy_eval_from_control_command,
|
||||
|
||||
gdbpy_start_type_printers,
|
||||
gdbpy_apply_type_printers,
|
||||
gdbpy_free_type_printers,
|
||||
|
||||
gdbpy_apply_val_pretty_printer,
|
||||
|
||||
gdbpy_apply_frame_filter,
|
||||
|
||||
gdbpy_preserve_values,
|
||||
|
||||
gdbpy_breakpoint_has_cond,
|
||||
gdbpy_breakpoint_cond_says_stop,
|
||||
|
||||
gdbpy_clear_quit_flag,
|
||||
gdbpy_set_quit_flag,
|
||||
gdbpy_check_quit_flag,
|
||||
|
||||
gdbpy_before_prompt_hook
|
||||
};
|
||||
|
||||
/* Architecture and language to be used in callbacks from
|
||||
the Python interpreter. */
|
||||
struct gdbarch *python_gdbarch;
|
||||
|
@ -114,6 +199,7 @@ const struct language_defn *python_language;
|
|||
|
||||
struct python_env
|
||||
{
|
||||
struct active_ext_lang_state *previous_active;
|
||||
PyGILState_STATE state;
|
||||
struct gdbarch *gdbarch;
|
||||
const struct language_defn *language;
|
||||
|
@ -138,11 +224,17 @@ restore_python_env (void *p)
|
|||
PyGILState_Release (env->state);
|
||||
python_gdbarch = env->gdbarch;
|
||||
python_language = env->language;
|
||||
|
||||
restore_active_ext_lang (env->previous_active);
|
||||
|
||||
xfree (env);
|
||||
}
|
||||
|
||||
/* Called before entering the Python interpreter to install the
|
||||
current language and architecture to be used for Python values. */
|
||||
current language and architecture to be used for Python values.
|
||||
Also set the active extension language for GDB so that SIGINT's
|
||||
are directed our way, and if necessary install the right SIGINT
|
||||
handler. */
|
||||
|
||||
struct cleanup *
|
||||
ensure_python_env (struct gdbarch *gdbarch,
|
||||
|
@ -154,6 +246,8 @@ ensure_python_env (struct gdbarch *gdbarch,
|
|||
if (!gdb_python_initialized)
|
||||
error (_("Python not initialized"));
|
||||
|
||||
env->previous_active = set_active_ext_lang (&extension_language_python);
|
||||
|
||||
env->state = PyGILState_Ensure ();
|
||||
env->gdbarch = python_gdbarch;
|
||||
env->language = python_language;
|
||||
|
@ -169,8 +263,8 @@ ensure_python_env (struct gdbarch *gdbarch,
|
|||
|
||||
/* Clear the quit flag. */
|
||||
|
||||
void
|
||||
clear_quit_flag (void)
|
||||
static void
|
||||
gdbpy_clear_quit_flag (const struct extension_language_defn *extlang)
|
||||
{
|
||||
/* This clears the flag as a side effect. */
|
||||
PyOS_InterruptOccurred ();
|
||||
|
@ -178,16 +272,16 @@ clear_quit_flag (void)
|
|||
|
||||
/* Set the quit flag. */
|
||||
|
||||
void
|
||||
set_quit_flag (void)
|
||||
static void
|
||||
gdbpy_set_quit_flag (const struct extension_language_defn *extlang)
|
||||
{
|
||||
PyErr_SetInterrupt ();
|
||||
}
|
||||
|
||||
/* Return true if the quit flag has been set, false otherwise. */
|
||||
|
||||
int
|
||||
check_quit_flag (void)
|
||||
static int
|
||||
gdbpy_check_quit_flag (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return PyOS_InterruptOccurred ();
|
||||
}
|
||||
|
@ -343,8 +437,9 @@ compute_python_string (struct command_line *l)
|
|||
/* Take a command line structure representing a 'python' command, and
|
||||
evaluate its body using the Python interpreter. */
|
||||
|
||||
void
|
||||
eval_python_from_control_command (struct command_line *cmd)
|
||||
static void
|
||||
gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
|
||||
struct command_line *cmd)
|
||||
{
|
||||
int ret;
|
||||
char *script;
|
||||
|
@ -765,12 +860,14 @@ gdbpy_find_pc_line (PyObject *self, PyObject *args)
|
|||
}
|
||||
|
||||
/* Read a file as Python code.
|
||||
FILE is the file to run. FILENAME is name of the file FILE.
|
||||
This is the extension_language_script_ops.script_sourcer "method".
|
||||
FILE is the file to load. FILENAME is name of the file FILE.
|
||||
This does not throw any errors. If an exception occurs python will print
|
||||
the traceback and clear the error indicator. */
|
||||
|
||||
void
|
||||
source_python_script (FILE *file, const char *filename)
|
||||
static void
|
||||
gdbpy_source_script (const struct extension_language_defn *extlang,
|
||||
FILE *file, const char *filename)
|
||||
{
|
||||
struct cleanup *cleanup;
|
||||
|
||||
|
@ -899,14 +996,17 @@ gdbpy_initialize_events (void)
|
|||
|
||||
|
||||
|
||||
static void
|
||||
before_prompt_hook (const char *current_gdb_prompt)
|
||||
/* This is the extension_language_ops.before_prompt "method". */
|
||||
|
||||
static enum ext_lang_rc
|
||||
gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
|
||||
const char *current_gdb_prompt)
|
||||
{
|
||||
struct cleanup *cleanup;
|
||||
char *prompt = NULL;
|
||||
|
||||
if (!gdb_python_initialized)
|
||||
return;
|
||||
return EXT_LANG_RC_NOP;
|
||||
|
||||
cleanup = ensure_python_env (get_current_arch (), current_language);
|
||||
|
||||
|
@ -968,12 +1068,12 @@ before_prompt_hook (const char *current_gdb_prompt)
|
|||
set_prompt (prompt);
|
||||
|
||||
do_cleanups (cleanup);
|
||||
return;
|
||||
return prompt != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_NOP;
|
||||
|
||||
fail:
|
||||
gdbpy_print_stack ();
|
||||
do_cleanups (cleanup);
|
||||
return;
|
||||
return EXT_LANG_RC_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1158,16 +1258,19 @@ gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
|
|||
|
||||
/* The "current" objfile. This is set when gdb detects that a new
|
||||
objfile has been loaded. It is only set for the duration of a call to
|
||||
source_python_script_for_objfile; it is NULL at other times. */
|
||||
gdbpy_source_objfile_script; it is NULL at other times. */
|
||||
static struct objfile *gdbpy_current_objfile;
|
||||
|
||||
/* Set the current objfile to OBJFILE and then read FILE named FILENAME
|
||||
as Python code. This does not throw any errors. If an exception
|
||||
occurs python will print the traceback and clear the error indicator. */
|
||||
occurs python will print the traceback and clear the error indicator.
|
||||
This is the extension_language_script_ops.objfile_script_sourcer
|
||||
"method". */
|
||||
|
||||
void
|
||||
source_python_script_for_objfile (struct objfile *objfile, FILE *file,
|
||||
const char *filename)
|
||||
static void
|
||||
gdbpy_source_objfile_script (const struct extension_language_defn *extlang,
|
||||
struct objfile *objfile, FILE *file,
|
||||
const char *filename)
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
|
||||
|
@ -1225,18 +1328,20 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
|
|||
return list;
|
||||
}
|
||||
|
||||
/* Compute the list of active type printers and return it. The result
|
||||
of this function can be passed to apply_type_printers, and should
|
||||
be freed by free_type_printers. */
|
||||
/* Compute the list of active python type printers and store them in
|
||||
EXT_PRINTERS->py_type_printers. The product of this function is used by
|
||||
gdbpy_apply_type_printers, and freed by gdbpy_free_type_printers.
|
||||
This is the extension_language_ops.start_type_printers "method". */
|
||||
|
||||
void *
|
||||
start_type_printers (void)
|
||||
static void
|
||||
gdbpy_start_type_printers (const struct extension_language_defn *extlang,
|
||||
struct ext_lang_type_printers *ext_printers)
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
PyObject *type_module, *func = NULL, *result_obj = NULL;
|
||||
PyObject *type_module, *func = NULL, *printers_obj = NULL;
|
||||
|
||||
if (!gdb_python_initialized)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
cleanups = ensure_python_env (get_current_arch (), current_language);
|
||||
|
||||
|
@ -1254,39 +1359,41 @@ start_type_printers (void)
|
|||
goto done;
|
||||
}
|
||||
|
||||
result_obj = PyObject_CallFunctionObjArgs (func, (char *) NULL);
|
||||
if (result_obj == NULL)
|
||||
printers_obj = PyObject_CallFunctionObjArgs (func, (char *) NULL);
|
||||
if (printers_obj == NULL)
|
||||
gdbpy_print_stack ();
|
||||
else
|
||||
ext_printers->py_type_printers = printers_obj;
|
||||
|
||||
done:
|
||||
Py_XDECREF (type_module);
|
||||
Py_XDECREF (func);
|
||||
do_cleanups (cleanups);
|
||||
return result_obj;
|
||||
}
|
||||
|
||||
/* If TYPE is recognized by some type printer, return a newly
|
||||
allocated string holding the type's replacement name. The caller
|
||||
is responsible for freeing the string. Otherwise, return NULL.
|
||||
/* If TYPE is recognized by some type printer, store in *PRETTIED_TYPE
|
||||
a newly allocated string holding the type's replacement name, and return
|
||||
EXT_LANG_RC_OK. The caller is responsible for freeing the string.
|
||||
If there's a Python error return EXT_LANG_RC_ERROR.
|
||||
Otherwise, return EXT_LANG_RC_NOP.
|
||||
This is the extension_language_ops.apply_type_printers "method". */
|
||||
|
||||
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. */
|
||||
|
||||
char *
|
||||
apply_type_printers (void *printers, struct type *type)
|
||||
static enum ext_lang_rc
|
||||
gdbpy_apply_type_printers (const struct extension_language_defn *extlang,
|
||||
const struct ext_lang_type_printers *ext_printers,
|
||||
struct type *type, char **prettied_type)
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
PyObject *type_obj, *type_module = NULL, *func = NULL;
|
||||
PyObject *result_obj = NULL;
|
||||
PyObject *printers_obj = printers;
|
||||
PyObject *printers_obj = ext_printers->py_type_printers;
|
||||
char *result = NULL;
|
||||
|
||||
if (printers_obj == NULL)
|
||||
return NULL;
|
||||
return EXT_LANG_RC_NOP;
|
||||
|
||||
if (!gdb_python_initialized)
|
||||
return NULL;
|
||||
return EXT_LANG_RC_NOP;
|
||||
|
||||
cleanups = ensure_python_env (get_current_arch (), current_language);
|
||||
|
||||
|
@ -1332,16 +1439,20 @@ apply_type_printers (void *printers, struct type *type)
|
|||
Py_XDECREF (func);
|
||||
Py_XDECREF (result_obj);
|
||||
do_cleanups (cleanups);
|
||||
return result;
|
||||
if (result != NULL)
|
||||
*prettied_type = result;
|
||||
return result != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_ERROR;
|
||||
}
|
||||
|
||||
/* Free the result of start_type_printers. */
|
||||
/* Free the result of start_type_printers.
|
||||
This is the extension_language_ops.free_type_printers "method". */
|
||||
|
||||
void
|
||||
free_type_printers (void *arg)
|
||||
static void
|
||||
gdbpy_free_type_printers (const struct extension_language_defn *extlang,
|
||||
struct ext_lang_type_printers *ext_printers)
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
PyObject *printers = arg;
|
||||
PyObject *printers = ext_printers->py_type_printers;
|
||||
|
||||
if (printers == NULL)
|
||||
return;
|
||||
|
@ -1381,62 +1492,6 @@ python_command (char *arg, int from_tty)
|
|||
python_interactive_command (arg, from_tty);
|
||||
}
|
||||
|
||||
void
|
||||
eval_python_from_control_command (struct command_line *cmd)
|
||||
{
|
||||
error (_("Python scripting is not supported in this copy of GDB."));
|
||||
}
|
||||
|
||||
void
|
||||
source_python_script (FILE *file, const char *filename)
|
||||
{
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("source_python_script called when Python scripting is "
|
||||
"not supported."));
|
||||
}
|
||||
|
||||
int
|
||||
gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
|
||||
{
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("gdbpy_should_stop called when Python scripting is " \
|
||||
"not supported."));
|
||||
}
|
||||
|
||||
int
|
||||
gdbpy_breakpoint_has_py_cond (struct gdbpy_breakpoint_object *bp_obj)
|
||||
{
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("gdbpy_breakpoint_has_py_cond called when Python " \
|
||||
"scripting is not supported."));
|
||||
}
|
||||
|
||||
void *
|
||||
start_type_printers (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
apply_type_printers (void *ignore, struct type *type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
free_type_printers (void *arg)
|
||||
{
|
||||
}
|
||||
|
||||
enum py_bt_status
|
||||
apply_frame_filter (struct frame_info *frame, int flags,
|
||||
enum py_frame_args args_type,
|
||||
struct ui_out *out, int frame_low,
|
||||
int frame_high)
|
||||
{
|
||||
return PY_BT_NO_FILTERS;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PYTHON */
|
||||
|
||||
|
||||
|
@ -1473,16 +1528,25 @@ user_show_python (char *args, int from_tty)
|
|||
static void
|
||||
finalize_python (void *ignore)
|
||||
{
|
||||
struct active_ext_lang_state *previous_active;
|
||||
|
||||
/* We don't use ensure_python_env here because if we ever ran the
|
||||
cleanup, gdb would crash -- because the cleanup calls into the
|
||||
Python interpreter, which we are about to destroy. It seems
|
||||
clearer to make the needed calls explicitly here than to create a
|
||||
cleanup and then mysteriously discard it. */
|
||||
|
||||
/* This is only called as a final cleanup so we can assume the active
|
||||
SIGINT handler is gdb's. We still need to tell it to notify Python. */
|
||||
previous_active = set_active_ext_lang (&extension_language_python);
|
||||
|
||||
(void) PyGILState_Ensure ();
|
||||
python_gdbarch = target_gdbarch ();
|
||||
python_language = current_language;
|
||||
|
||||
Py_Finalize ();
|
||||
|
||||
restore_active_ext_lang (previous_active);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1691,8 +1755,6 @@ message == an error message without a stack will be printed."),
|
|||
|| gdbpy_initialize_arch () < 0)
|
||||
goto fail;
|
||||
|
||||
observer_attach_before_prompt (before_prompt_hook);
|
||||
|
||||
gdbpy_to_string_cst = PyString_FromString ("to_string");
|
||||
if (gdbpy_to_string_cst == NULL)
|
||||
goto fail;
|
||||
|
@ -1734,10 +1796,11 @@ message == an error message without a stack will be printed."),
|
|||
/* Perform the remaining python initializations.
|
||||
These must be done after GDB is at least mostly initialized.
|
||||
E.g., The "info pretty-printer" command needs the "info" prefix
|
||||
command installed. */
|
||||
command installed.
|
||||
This is the extension_language_ops.finish_initialization "method". */
|
||||
|
||||
void
|
||||
finish_python_initialization (void)
|
||||
static void
|
||||
gdbpy_finish_initialization (const struct extension_language_defn *extlang)
|
||||
{
|
||||
PyObject *m;
|
||||
char *gdb_pythondir;
|
||||
|
@ -1816,6 +1879,15 @@ finish_python_initialization (void)
|
|||
do_cleanups (cleanup);
|
||||
}
|
||||
|
||||
/* Return non-zero if Python has successfully initialized.
|
||||
This is the extension_languages_ops.initialized "method". */
|
||||
|
||||
static int
|
||||
gdbpy_initialized (const struct extension_language_defn *extlang)
|
||||
{
|
||||
return gdb_python_initialized;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PYTHON */
|
||||
|
||||
|
||||
|
|
|
@ -20,118 +20,9 @@
|
|||
#ifndef GDB_PYTHON_H
|
||||
#define GDB_PYTHON_H
|
||||
|
||||
#include "value.h"
|
||||
#include "mi/mi-cmds.h"
|
||||
#include "extension.h"
|
||||
|
||||
struct gdbpy_breakpoint_object;
|
||||
|
||||
/* The suffix of per-objfile scripts to auto-load.
|
||||
E.g. When the program loads libfoo.so, look for libfoo-gdb.py. */
|
||||
#define GDBPY_AUTO_FILE_NAME "-gdb.py"
|
||||
|
||||
/* Python frame-filter status return values. */
|
||||
enum py_bt_status
|
||||
{
|
||||
/* Return when an error has occurred in processing frame filters,
|
||||
or when printing the stack. */
|
||||
PY_BT_ERROR = -1,
|
||||
|
||||
/* Return from internal routines to indicate that the function
|
||||
succeeded. */
|
||||
PY_BT_OK = 1,
|
||||
|
||||
/* Return when the frame filter process is complete, and all
|
||||
operations have succeeded. */
|
||||
PY_BT_COMPLETED = 2,
|
||||
|
||||
/* Return when the frame filter process is complete, but there
|
||||
were no filter registered and enabled to process. */
|
||||
PY_BT_NO_FILTERS = 3
|
||||
};
|
||||
|
||||
/* Flags to pass to apply_frame_filter. */
|
||||
|
||||
enum frame_filter_flags
|
||||
{
|
||||
/* Set this flag if frame level is to be printed. */
|
||||
PRINT_LEVEL = 1,
|
||||
|
||||
/* Set this flag if frame information is to be printed. */
|
||||
PRINT_FRAME_INFO = 2,
|
||||
|
||||
/* Set this flag if frame arguments are to be printed. */
|
||||
PRINT_ARGS = 4,
|
||||
|
||||
/* Set this flag if frame locals are to be printed. */
|
||||
PRINT_LOCALS = 8,
|
||||
};
|
||||
|
||||
/* A choice of the different frame argument printing strategies that
|
||||
can occur in different cases of frame filter instantiation. */
|
||||
typedef enum py_frame_args
|
||||
{
|
||||
/* Print no values for arguments when invoked from the MI. */
|
||||
NO_VALUES = PRINT_NO_VALUES,
|
||||
|
||||
MI_PRINT_ALL_VALUES = PRINT_ALL_VALUES,
|
||||
|
||||
/* Print only simple values (what MI defines as "simple") for
|
||||
arguments when invoked from the MI. */
|
||||
MI_PRINT_SIMPLE_VALUES = PRINT_SIMPLE_VALUES,
|
||||
|
||||
|
||||
/* Print only scalar values for arguments when invoked from the
|
||||
CLI. */
|
||||
CLI_SCALAR_VALUES,
|
||||
|
||||
/* Print all values for arguments when invoked from the
|
||||
CLI. */
|
||||
CLI_ALL_VALUES
|
||||
} py_frame_args;
|
||||
|
||||
/* Returns true if Python support is built into GDB, false
|
||||
otherwise. */
|
||||
|
||||
static inline int
|
||||
have_python (void)
|
||||
{
|
||||
#ifdef HAVE_PYTHON
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void finish_python_initialization (void);
|
||||
|
||||
void eval_python_from_control_command (struct command_line *);
|
||||
|
||||
void source_python_script (FILE *file, const char *filename);
|
||||
|
||||
int apply_val_pretty_printer (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);
|
||||
|
||||
enum py_bt_status apply_frame_filter (struct frame_info *frame, int flags,
|
||||
enum py_frame_args args_type,
|
||||
struct ui_out *out, int frame_low,
|
||||
int frame_high);
|
||||
|
||||
void preserve_python_values (struct objfile *objfile, htab_t copied_types);
|
||||
|
||||
const struct script_language *gdbpy_script_language_defn (void);
|
||||
|
||||
int gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj);
|
||||
|
||||
int gdbpy_breakpoint_has_py_cond (struct gdbpy_breakpoint_object *bp_obj);
|
||||
|
||||
void *start_type_printers (void);
|
||||
|
||||
char *apply_type_printers (void *, struct type *type);
|
||||
|
||||
void free_type_printers (void *arg);
|
||||
/* This is all that python exports to gdb. */
|
||||
extern const struct extension_language_defn extension_language_python;
|
||||
|
||||
#endif /* GDB_PYTHON_H */
|
||||
|
|
15
gdb/stack.c
15
gdb/stack.c
|
@ -53,7 +53,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "symfile.h"
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
|
||||
void (*deprecated_selected_frame_level_changed_hook) (int);
|
||||
|
||||
|
@ -1708,7 +1708,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int no_filters,
|
|||
int i;
|
||||
struct frame_info *trailing;
|
||||
int trailing_level, py_start = 0, py_end = 0;
|
||||
enum py_bt_status result = PY_BT_ERROR;
|
||||
enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
|
||||
|
||||
if (!target_has_stack)
|
||||
error (_("No stack."));
|
||||
|
@ -1782,7 +1782,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int no_filters,
|
|||
if (! no_filters)
|
||||
{
|
||||
int flags = PRINT_LEVEL | PRINT_FRAME_INFO | PRINT_ARGS;
|
||||
enum py_frame_args arg_type;
|
||||
enum ext_lang_frame_args arg_type;
|
||||
|
||||
if (show_locals)
|
||||
flags |= PRINT_LOCALS;
|
||||
|
@ -1794,13 +1794,14 @@ backtrace_command_1 (char *count_exp, int show_locals, int no_filters,
|
|||
else
|
||||
arg_type = NO_VALUES;
|
||||
|
||||
result = apply_frame_filter (get_current_frame (), flags, arg_type,
|
||||
current_uiout, py_start, py_end);
|
||||
|
||||
result = apply_ext_lang_frame_filter (get_current_frame (), flags,
|
||||
arg_type, current_uiout,
|
||||
py_start, py_end);
|
||||
}
|
||||
|
||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||
"no-filters" has been specified from the command. */
|
||||
if (no_filters || result == PY_BT_NO_FILTERS)
|
||||
if (no_filters || result == EXT_LANG_BT_NO_FILTERS)
|
||||
{
|
||||
for (i = 0, fi = trailing; fi && count--; i++, fi = get_prev_frame (fi))
|
||||
{
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2014-02-06 Doug Evans <xdje42@gmail.com>
|
||||
|
||||
* gdb.python/py-breakpoint.exp (test_bkpt_eval_funcs): Update expected
|
||||
output.
|
||||
|
||||
* gdb.gdb/python-interrupts.exp: New file.
|
||||
|
||||
2014-02-05 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* gdb.trace/report.exp (use_collected_data): Test the output
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright 2013 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/>.
|
||||
|
||||
# Test Python SIGINT handling.
|
||||
# This is easiest if we can send SIGINT when gdb is at particular points.
|
||||
|
||||
load_lib selftest-support.exp
|
||||
load_lib gdb-python.exp
|
||||
|
||||
proc test_python_interrupts {} {
|
||||
if {[skip_python_tests]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_breakpoint set_active_ext_lang temporary
|
||||
gdb_test "call catch_command_errors(execute_command, \"python print 5\", 0, RETURN_MASK_ALL)" \
|
||||
"Temporary breakpoint.*silently stop."
|
||||
gdb_test "signal SIGINT" \
|
||||
"KeyboardInterrupt.*Error while executing Python code."
|
||||
return 0
|
||||
}
|
||||
|
||||
do_self_tests captured_command_loop test_python_interrupts
|
|
@ -372,7 +372,7 @@ proc test_bkpt_eval_funcs { } {
|
|||
"Set breakpoint" 0
|
||||
set test_cond {cond $bpnum}
|
||||
gdb_test "$test_cond \"foo==3\"" \
|
||||
"Cannot set a condition where a Python.*" \
|
||||
"Only one stop condition allowed. There is currently a Python.*" \
|
||||
"Check you cannot add a CLI condition to a Python breakpoint that has defined stop"
|
||||
gdb_py_test_silent_cmd "python eval_bp2 = basic(\"$cond_bp\")" \
|
||||
"Set breakpoint" 0
|
||||
|
@ -385,7 +385,7 @@ proc test_bkpt_eval_funcs { } {
|
|||
"end" ""
|
||||
|
||||
gdb_test "python eval_bp2.stop = stop_func" \
|
||||
"RuntimeError: Cannot set 'stop' method.*" \
|
||||
"RuntimeError: Only one stop condition allowed. There is currently a GDB.*" \
|
||||
"Assign stop function to a breakpoint that has a condition"
|
||||
|
||||
delete_breakpoints
|
||||
|
|
10
gdb/top.c
10
gdb/top.c
|
@ -45,7 +45,7 @@
|
|||
#include "main.h"
|
||||
#include "event-loop.h"
|
||||
#include "gdbthread.h"
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
#include "interps.h"
|
||||
#include "observer.h"
|
||||
#include "maint.h"
|
||||
|
@ -1850,11 +1850,9 @@ gdb_init (char *argv0)
|
|||
if (deprecated_init_ui_hook)
|
||||
deprecated_init_ui_hook (argv0);
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
/* Python initialization can require various commands to be
|
||||
/* Python initialization, for example, can require various commands to be
|
||||
installed. For example "info pretty-printer" needs the "info"
|
||||
prefix to be installed. Keep things simple and just do final
|
||||
python initialization here. */
|
||||
finish_python_initialization ();
|
||||
#endif
|
||||
script initialization here. */
|
||||
finish_ext_lang_initialization ();
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include "cli/cli-utils.h"
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
#include "completer.h"
|
||||
|
||||
extern void _initialize_typeprint (void);
|
||||
|
@ -248,7 +248,7 @@ do_free_global_table (void *arg)
|
|||
struct type_print_options *flags = arg;
|
||||
|
||||
free_typedef_hash (flags->global_typedefs);
|
||||
free_type_printers (flags->global_printers);
|
||||
free_ext_lang_type_printers (flags->global_printers);
|
||||
}
|
||||
|
||||
/* Create the global typedef hash. */
|
||||
|
@ -258,13 +258,13 @@ create_global_typedef_table (struct type_print_options *flags)
|
|||
{
|
||||
gdb_assert (flags->global_typedefs == NULL && flags->global_printers == NULL);
|
||||
flags->global_typedefs = create_typedef_hash ();
|
||||
flags->global_printers = start_type_printers ();
|
||||
flags->global_printers = start_ext_lang_type_printers ();
|
||||
return make_cleanup (do_free_global_table, flags);
|
||||
}
|
||||
|
||||
/* Look up the type T in the global typedef hash. If it is found,
|
||||
return the typedef name. If it is not found, apply the
|
||||
type-printers, if any, given by start_type_printers and return the
|
||||
type-printers, if any, given by start_script_type_printers and return the
|
||||
result. A NULL return means that the name was not found. */
|
||||
|
||||
static const char *
|
||||
|
@ -288,7 +288,7 @@ find_global_typedef (const struct type_print_options *flags,
|
|||
return new_tf->name;
|
||||
}
|
||||
|
||||
/* Put an entry into the hash table now, in case apply_type_printers
|
||||
/* Put an entry into the hash table now, in case apply_script_type_printers
|
||||
recurses. */
|
||||
new_tf = XOBNEW (&flags->global_typedefs->storage, struct typedef_field);
|
||||
new_tf->name = NULL;
|
||||
|
@ -296,7 +296,7 @@ find_global_typedef (const struct type_print_options *flags,
|
|||
|
||||
*slot = new_tf;
|
||||
|
||||
applied = apply_type_printers (flags->global_printers, t);
|
||||
applied = apply_ext_lang_type_printers (flags->global_printers, t);
|
||||
|
||||
if (applied != NULL)
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
enum language;
|
||||
struct ui_file;
|
||||
struct typedef_hash_table;
|
||||
struct ext_lang_type_printers;
|
||||
|
||||
struct type_print_options
|
||||
{
|
||||
|
@ -44,7 +45,7 @@ struct type_print_options
|
|||
|
||||
/* The list of type printers associated with the global typedef
|
||||
table. This is intentionally opaque. */
|
||||
void *global_printers;
|
||||
struct ext_lang_type_printers *global_printers;
|
||||
};
|
||||
|
||||
extern const struct type_print_options type_print_raw_options;
|
||||
|
|
41
gdb/utils.c
41
gdb/utils.c
|
@ -112,12 +112,6 @@ static int debug_timestamp = 0;
|
|||
|
||||
int job_control;
|
||||
|
||||
#ifndef HAVE_PYTHON
|
||||
/* Nonzero means a quit has been requested. */
|
||||
|
||||
int quit_flag;
|
||||
#endif /* HAVE_PYTHON */
|
||||
|
||||
/* Nonzero means quit immediately if Control-C is typed now, rather
|
||||
than waiting until QUIT is executed. Be careful in setting this;
|
||||
code which executes with immediate_quit set has to be very careful
|
||||
|
@ -131,41 +125,6 @@ int quit_flag;
|
|||
|
||||
int immediate_quit;
|
||||
|
||||
#ifndef HAVE_PYTHON
|
||||
|
||||
/* Clear the quit flag. */
|
||||
|
||||
void
|
||||
clear_quit_flag (void)
|
||||
{
|
||||
quit_flag = 0;
|
||||
}
|
||||
|
||||
/* Set the quit flag. */
|
||||
|
||||
void
|
||||
set_quit_flag (void)
|
||||
{
|
||||
quit_flag = 1;
|
||||
}
|
||||
|
||||
/* Return true if the quit flag has been set, false otherwise. */
|
||||
|
||||
int
|
||||
check_quit_flag (void)
|
||||
{
|
||||
/* This is written in a particular way to avoid races. */
|
||||
if (quit_flag)
|
||||
{
|
||||
quit_flag = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PYTHON */
|
||||
|
||||
/* Nonzero means that strings with character values >0x7F should be printed
|
||||
as octal escapes. Zero means just print the value (e.g. it's an
|
||||
international character, and the terminal or window can cope.) */
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "doublest.h"
|
||||
#include "exceptions.h"
|
||||
#include "dfp.h"
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
#include "ada-lang.h"
|
||||
#include "gdb_obstack.h"
|
||||
#include "charset.h"
|
||||
|
@ -770,9 +770,9 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
|||
|
||||
if (!options->raw)
|
||||
{
|
||||
ret = apply_val_pretty_printer (type, valaddr, embedded_offset,
|
||||
address, stream, recurse,
|
||||
val, options, language);
|
||||
ret = apply_ext_lang_val_pretty_printer (type, valaddr, embedded_offset,
|
||||
address, stream, recurse,
|
||||
val, options, language);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
|
@ -876,12 +876,13 @@ value_print (struct value *val, struct ui_file *stream,
|
|||
|
||||
if (!options->raw)
|
||||
{
|
||||
int r = apply_val_pretty_printer (value_type (val),
|
||||
value_contents_for_printing (val),
|
||||
value_embedded_offset (val),
|
||||
value_address (val),
|
||||
stream, 0,
|
||||
val, options, current_language);
|
||||
int r
|
||||
= apply_ext_lang_val_pretty_printer (value_type (val),
|
||||
value_contents_for_printing (val),
|
||||
value_embedded_offset (val),
|
||||
value_address (val),
|
||||
stream, 0,
|
||||
val, options, current_language);
|
||||
|
||||
if (r)
|
||||
return;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "valprint.h"
|
||||
#include "cli/cli-decode.h"
|
||||
#include "exceptions.h"
|
||||
#include "python/python.h"
|
||||
#include "extension.h"
|
||||
#include <ctype.h>
|
||||
#include "tracepoint.h"
|
||||
#include "cp-abi.h"
|
||||
|
@ -2405,7 +2405,7 @@ preserve_values (struct objfile *objfile)
|
|||
for (var = internalvars; var; var = var->next)
|
||||
preserve_one_internalvar (var, objfile, copied_types);
|
||||
|
||||
preserve_python_values (objfile, copied_types);
|
||||
preserve_ext_lang_values (objfile, copied_types);
|
||||
|
||||
htab_delete (copied_types);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue