Extension Language API
* configure.ac (libpython checking): Remove all but python.o from CONFIG_OBS. Remove all but python.c from CONFIG_SRCS. * configure: Regenerate. * Makefile.in (SFILES): Add extension.c. (HFILES_NO_SRCDIR): Add extension.h, extension-priv.h (COMMON_OBS): Add extension.o. * extension.h: New file. * extension-priv.h: New file. * extension.c: New file. * python/python-internal.h: #include "extension.h". (gdbpy_auto_load_enabled): Declare. (gdbpy_apply_val_pretty_printer): Declare. (gdbpy_apply_frame_filter): Declare. (gdbpy_preserve_values): Declare. (gdbpy_breakpoint_cond_says_stop): Declare. (gdbpy_breakpoint_has_cond): Declare. (void source_python_script_for_objfile): Delete. * python/python.c: #include "extension-priv.h". Delete inclusion of "observer.h". (extension_language_python): Moved here and renamed from script_language_python in py-auto-load.c. Redefined to be of type extension_language_defn. (python_extension_script_ops): New global. (python_extension_ops): New global. (struct python_env): New member previous_active. (restore_python_env): Call restore_active_ext_lang. (ensure_python_env): Call set_active_ext_lang. (gdbpy_clear_quit_flag): Renamed from clear_quit_flag, made static. New arg extlang. (gdbpy_set_quit_flag): Renamed from set_quit_flag, made static. New arg extlang. (gdbpy_check_quit_flag): Renamed from check_quit_flag, made static. New arg extlang. (gdbpy_eval_from_control_command): Renamed from eval_python_from_control_command, made static. New arg extlang. (gdbpy_source_script) Renamed from source_python_script, made static. New arg extlang. (gdbpy_before_prompt_hook): Renamed from before_prompt_hook. Change result to int. New arg extlang. (gdbpy_source_objfile_script): Renamed from source_python_script_for_objfile, made static. New arg extlang. (gdbpy_start_type_printers): Renamed from start_type_printers, made static. New args extlang, extlang_printers. Change result type to "void". (gdbpy_apply_type_printers): Renamed from apply_type_printers, made static. New arg extlang. Rename arg printers to extlang_printers and change type to ext_lang_type_printers *. (gdbpy_free_type_printers): Renamed from free_type_printers, made static. Replace argument arg with extlang, extlang_printers. (!HAVE_PYTHON, eval_python_from_control_command): Delete. (!HAVE_PYTHON, source_python_script): Delete. (!HAVE_PYTHON, gdbpy_should_stop): Delete. (!HAVE_PYTHON, gdbpy_breakpoint_has_py_cond): Delete. (!HAVE_PYTHON, start_type_printers): Delete. (!HAVE_PYTHON, apply_type_printers): Delete. (!HAVE_PYTHON, free_type_printers): Delete. (_initialize_python): Delete call to observer_attach_before_prompt. (finalize_python): Set/restore active extension language. (gdbpy_finish_initialization) Renamed from finish_python_initialization, made static. New arg extlang. (gdbpy_initialized): New function. * python/python.h: #include "extension.h". Delete #include "value.h", "mi/mi-cmds.h". (extension_language_python): Declare. (GDBPY_AUTO_FILE_NAME): Delete. (enum py_bt_status): Moved to extension.h and renamed to ext_lang_bt_status. (enum frame_filter_flags): Moved to extension.h. (enum py_frame_args): Moved to extension.h and renamed to ext_lang_frame_args. (finish_python_initialization): Delete. (eval_python_from_control_command): Delete. (source_python_script): Delete. (apply_val_pretty_printer): Delete. (apply_frame_filter): Delete. (preserve_python_values): Delete. (gdbpy_script_language_defn): Delete. (gdbpy_should_stop, gdbpy_breakpoint_has_py_cond): Delete. (start_type_printers, apply_type_printers, free_type_printers): Delete. * auto-load.c: #include "extension.h". (GDB_AUTO_FILE_NAME): Delete. (auto_load_gdb_scripts_enabled): Make public. New arg extlang. (script_language_gdb): Delete, moved to extension.c and renamed to extension_language_gdb. (source_gdb_script_for_objfile): Delete. (auto_load_pspace_info): New member unsupported_script_warning_printed. (loaded_script): Change type of language member to struct extension_language_defn *. (init_loaded_scripts_info): Initialize unsupported_script_warning_printed. (maybe_add_script): Make static. Change type of language arg to struct extension_language_defn *. (clear_section_scripts): Reset unsupported_script_warning_printed. (auto_load_objfile_script_1): Rewrite to use extension language API. (auto_load_objfile_script): Make public. Remove support-compiled-in and auto-load-enabled checks, moved to auto_load_scripts_for_objfile. (source_section_scripts): Rewrite to use extension language API. (load_auto_scripts_for_objfile): Rewrite to use auto_load_scripts_for_objfile. (collect_matching_scripts_data): Change type of language member to struct extension_language_defn *. (auto_load_info_scripts): Change type of language arg to struct extension_language_defn *. (unsupported_script_warning_print): New function. (script_not_found_warning_print): Make static. (_initialize_auto_load): Rewrite construction of scripts-directory help. * auto-load.h (struct objfile): Add forward decl. (struct script_language): Delete. (struct auto_load_pspace_info): Add forward decl. (struct extension_language_defn): Add forward decl. (maybe_add_script): Delete. (auto_load_objfile_script): Declare. (script_not_found_warning_print): Delete. (auto_load_info_scripts): Update prototype. (auto_load_gdb_scripts_enabled): Declare. * python/py-auto-load.c (gdbpy_auto_load_enabled): Renamed from auto_load_python_scripts_enabled and made public. (script_language_python): Delete, moved to python.c. (gdbpy_script_language_defn): Delete. (info_auto_load_python_scripts): Update to use extension_language_python. * breakpoint.c (condition_command): Replace call to gdbpy_breakpoint_has_py_cond with call to get_breakpoint_cond_ext_lang. (bpstat_check_breakpoint_conditions): Replace call to gdbpy_should_stop with call to breakpoint_ext_lang_cond_says_stop. * python/py-breakpoint.c (gdbpy_breakpoint_cond_says_stop): Renamed from gdbpy_should_stop. Change result type to enum scr_bp_stop. New arg slang. Return SCR_BP_STOP_UNSET if py_bp_object is NULL. (gdbpy_breakpoint_has_cond): Renamed from gdbpy_breakpoint_has_py_cond. New arg slang. (local_setattro): Print name of extension language with existing stop condition. * valprint.c (val_print, value_print): Update to call apply_ext_lang_val_pretty_printer. * cp-valprint.c (cp_print_value): Update call to apply_ext_lang_val_pretty_printer. * python/py-prettyprint.c: Remove #ifdef HAVE_PYTHON. (gdbpy_apply_val_pretty_printer): Renamed from apply_val_pretty_printer. New arg extlang. (!HAVE_PYTHON, apply_val_pretty_printer): Delete. * cli/cli-cmds.c (source_script_from_stream): Rewrite to use extension language API. * cli/cli-script.c (execute_control_command): Update to call eval_ext_lang_from_control_command. * mi/mi-cmd-stack.c (mi_cmd_stack_list_frames): Update to use enum ext_lang_bt_status values. Update call to apply_ext_lang_frame_filter. (mi_cmd_stack_list_locals): Ditto. (mi_cmd_stack_list_args): Ditto. (mi_cmd_stack_list_variables): Ditto. * mi/mi-main.c: Delete #include "python/python-internal.h". Add #include "extension.h". (mi_cmd_list_features): Replace reference to python internal variable gdb_python_initialized with call to ext_lang_initialized_p. * stack.c (backtrace_command_1): Update to use enum ext_lang_bt_status. Update to use enum ext_lang_frame_args. Update to call apply_ext_lang_frame_filter. * python/py-framefilter.c (extract_sym): Update to use enum ext_lang_bt_status. (extract_value, py_print_type, py_print_value): Ditto. (py_print_single_arg, enumerate_args, enumerate_locals): Ditto. (py_mi_print_variables, py_print_locals, py_print_args): Ditto. (py_print_frame): Ditto. (gdbpy_apply_frame_filter): Renamed from apply_frame_filter. New arg extlang. Update to use enum ext_lang_bt_status. * top.c (gdb_init): Delete #ifdef HAVE_PYTHON call to finish_python_initialization. Replace with call to finish_ext_lang_initialization. * typeprint.c (do_free_global_table): Update to call free_ext_lang_type_printers. (create_global_typedef_table): Update to call start_ext_lang_type_printers. (find_global_typedef): Update to call apply_ext_lang_type_printers. * typeprint.h (struct ext_lang_type_printers): Add forward decl. (type_print_options): Change type of global_printers from "void *" to "struct ext_lang_type_printers *". * value.c (preserve_values): Update to call preserve_ext_lang_values. * python/py-value.c: Remove #ifdef HAVE_PYTHON. (gdbpy_preserve_values): Renamed from preserve_python_values. New arg extlang. (!HAVE_PYTHON, preserve_python_values): Delete. * utils.c (quit_flag): Delete, moved to extension.c. (clear_quit_flag, set_quit_flag, check_quit_flag): Delete, moved to extension.c. * eval.c: Delete #include "python/python.h". * main.c: Delete #include "python/python.h". * defs.h: Update comment. testsuite/ * gdb.python/py-breakpoint.exp (test_bkpt_eval_funcs): Update expected output. * gdb.gdb/python-interrupts.exp: New file.
This commit is contained in:
parent
6af7998535
commit
6dddc817c1
36 changed files with 2285 additions and 718 deletions
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>
|
2014-02-06 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
GDB 7.7 released.
|
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 \
|
dwarf2expr.c dwarf2loc.c dwarf2read.c dwarf2-frame.c \
|
||||||
dwarf2-frame-tailcall.c \
|
dwarf2-frame-tailcall.c \
|
||||||
elfread.c environ.c eval.c event-loop.c event-top.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 \
|
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 \
|
findcmd.c findvar.c frame.c frame-base.c frame-unwind.c \
|
||||||
gdbarch.c arch-utils.c gdb_bfd.c gdb_obstack.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-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 \
|
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 \
|
expression.h score-tdep.h gdb_select.h ser-tcp.h \
|
||||||
|
extension.h extension-priv.h \
|
||||||
build-id.h buildsym.h valprint.h \
|
build-id.h buildsym.h valprint.h \
|
||||||
typeprint.h mi/mi-getopt.h mi/mi-parse.h mi/mi-console.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 \
|
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 \
|
infcmd.o infrun.o \
|
||||||
expprint.o environ.o stack.o thread.o \
|
expprint.o environ.o stack.o thread.o \
|
||||||
exceptions.o \
|
exceptions.o \
|
||||||
|
extension.o \
|
||||||
filesystem.o \
|
filesystem.o \
|
||||||
filestuff.o \
|
filestuff.o \
|
||||||
inf-child.o \
|
inf-child.o \
|
||||||
|
|
210
gdb/auto-load.c
210
gdb/auto-load.c
|
@ -20,7 +20,6 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "auto-load.h"
|
#include "auto-load.h"
|
||||||
#include "progspace.h"
|
#include "progspace.h"
|
||||||
#include "python/python.h"
|
|
||||||
#include "gdb_regex.h"
|
#include "gdb_regex.h"
|
||||||
#include "ui-out.h"
|
#include "ui-out.h"
|
||||||
#include "filenames.h"
|
#include "filenames.h"
|
||||||
|
@ -39,6 +38,8 @@
|
||||||
#include "fnmatch.h"
|
#include "fnmatch.h"
|
||||||
#include "top.h"
|
#include "top.h"
|
||||||
#include "filestuff.h"
|
#include "filestuff.h"
|
||||||
|
#include "extension.h"
|
||||||
|
#include "python/python.h"
|
||||||
|
|
||||||
/* The section to look in for auto-loaded scripts (in file formats that
|
/* The section to look in for auto-loaded scripts (in file formats that
|
||||||
support sections).
|
support sections).
|
||||||
|
@ -48,12 +49,14 @@
|
||||||
followed by the path of a python script to load. */
|
followed by the path of a python script to load. */
|
||||||
#define AUTO_SECTION_NAME ".debug_gdb_scripts"
|
#define AUTO_SECTION_NAME ".debug_gdb_scripts"
|
||||||
|
|
||||||
/* The suffix of per-objfile scripts to auto-load as non-Python command files.
|
static int maybe_add_script (struct auto_load_pspace_info *pspace_info,
|
||||||
E.g. When the program loads libfoo.so, look for libfoo-gdb.gdb. */
|
int loaded, const char *name,
|
||||||
#define GDB_AUTO_FILE_NAME "-gdb.gdb"
|
const char *full_path,
|
||||||
|
const struct extension_language_defn *language);
|
||||||
|
|
||||||
static void source_gdb_script_for_objfile (struct objfile *objfile, FILE *file,
|
static int unsupported_script_warning_print (struct auto_load_pspace_info *);
|
||||||
const char *filename);
|
|
||||||
|
static int script_not_found_warning_print (struct auto_load_pspace_info *);
|
||||||
|
|
||||||
/* Value of the 'set debug auto-load' configuration variable. */
|
/* Value of the 'set debug auto-load' configuration variable. */
|
||||||
static int debug_auto_load = 0;
|
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. */
|
/* Return non-zero if auto-loading gdb scripts is enabled. */
|
||||||
|
|
||||||
static int
|
int
|
||||||
auto_load_gdb_scripts_enabled (void)
|
auto_load_gdb_scripts_enabled (const struct extension_language_defn *extlang)
|
||||||
{
|
{
|
||||||
return auto_load_gdb_scripts;
|
return auto_load_gdb_scripts;
|
||||||
}
|
}
|
||||||
|
@ -516,29 +519,6 @@ For more information about this security protection see the\n\
|
||||||
return 0;
|
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
|
/* For scripts specified in .debug_gdb_scripts, multiple objfiles may load
|
||||||
the same script. There's no point in loading the script multiple times,
|
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
|
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. */
|
/* For each program space we keep track of loaded scripts. */
|
||||||
struct htab *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
|
/* Non-zero if we've issued the warning about an auto-load script not being
|
||||||
found. We only want to issue this warning once. */
|
found. We only want to issue this warning once. */
|
||||||
int script_not_found_warning_printed;
|
int script_not_found_warning_printed;
|
||||||
|
@ -568,7 +552,7 @@ struct loaded_script
|
||||||
/* Non-zero if this script has been loaded. */
|
/* Non-zero if this script has been loaded. */
|
||||||
int loaded;
|
int loaded;
|
||||||
|
|
||||||
const struct script_language *language;
|
const struct extension_language_defn *language;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Per-program-space data key. */
|
/* Per-program-space data key. */
|
||||||
|
@ -638,6 +622,7 @@ init_loaded_scripts_info (struct auto_load_pspace_info *pspace_info)
|
||||||
eq_loaded_script_entry,
|
eq_loaded_script_entry,
|
||||||
xfree);
|
xfree);
|
||||||
|
|
||||||
|
pspace_info->unsupported_script_warning_printed = FALSE;
|
||||||
pspace_info->script_not_found_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
|
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. */
|
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,
|
maybe_add_script (struct auto_load_pspace_info *pspace_info, int loaded,
|
||||||
const char *name, const char *full_path,
|
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 htab *htab = pspace_info->loaded_scripts;
|
||||||
struct loaded_script **slot, entry;
|
struct loaded_script **slot, entry;
|
||||||
|
@ -716,6 +701,7 @@ clear_section_scripts (void)
|
||||||
{
|
{
|
||||||
htab_delete (info->loaded_scripts);
|
htab_delete (info->loaded_scripts);
|
||||||
info->loaded_scripts = NULL;
|
info->loaded_scripts = NULL;
|
||||||
|
info->unsupported_script_warning_printed = FALSE;
|
||||||
info->script_not_found_warning_printed = FALSE;
|
info->script_not_found_warning_printed = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,17 +712,18 @@ clear_section_scripts (void)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
|
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;
|
char *filename, *debugfile;
|
||||||
int len, retval;
|
int len, retval;
|
||||||
FILE *input;
|
FILE *input;
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups;
|
||||||
|
const char *suffix = ext_lang_auto_load_suffix (language);
|
||||||
|
|
||||||
len = strlen (realname);
|
len = strlen (realname);
|
||||||
filename = xmalloc (len + strlen (language->suffix) + 1);
|
filename = xmalloc (len + strlen (suffix) + 1);
|
||||||
memcpy (filename, realname, len);
|
memcpy (filename, realname, len);
|
||||||
strcpy (filename + len, language->suffix);
|
strcpy (filename + len, suffix);
|
||||||
|
|
||||||
cleanups = make_cleanup (xfree, filename);
|
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,
|
= file_is_auto_load_safe (filename,
|
||||||
_("auto-load: Loading %s script \"%s\""
|
_("auto-load: Loading %s script \"%s\""
|
||||||
" by extension for objfile \"%s\".\n"),
|
" by extension for objfile \"%s\".\n"),
|
||||||
language->name, filename,
|
ext_lang_name (language),
|
||||||
objfile_name (objfile));
|
filename, objfile_name (objfile));
|
||||||
|
|
||||||
/* Add this script to the hash table too so
|
/* Add this script to the hash table too so
|
||||||
"info auto-load ${lang}-scripts" can print it. */
|
"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
|
and these scripts are required to be idempotent under multiple
|
||||||
loads anyway. */
|
loads anyway. */
|
||||||
if (is_safe)
|
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;
|
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
|
/* Look for the auto-load script in LANGUAGE associated with OBJFILE and load
|
||||||
it. */
|
it. */
|
||||||
|
|
||||||
static void
|
void
|
||||||
auto_load_objfile_script (struct objfile *objfile,
|
auto_load_objfile_script (struct objfile *objfile,
|
||||||
const struct script_language *language)
|
const struct extension_language_defn *language)
|
||||||
{
|
{
|
||||||
char *realname;
|
char *realname = gdb_realpath (objfile_name (objfile));
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups = make_cleanup (xfree, realname);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
if (!auto_load_objfile_script_1 (objfile, realname, language))
|
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;
|
struct cleanup *back_to;
|
||||||
/* At the moment we only support python scripts in .debug_gdb_scripts,
|
/* At the moment we only support python scripts in .debug_gdb_scripts,
|
||||||
but that can change. */
|
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)
|
if (*p != 1)
|
||||||
{
|
{
|
||||||
|
@ -922,10 +911,34 @@ source_section_scripts (struct objfile *objfile, const char *section_name,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip this script if support has not been compiled in or
|
/* Until we support more types of records in .debug_gdb_scripts we do
|
||||||
auto-loading it has been disabled. */
|
all the processing here. The expectation is to add a new
|
||||||
if (language == NULL
|
extension_language_script_ops "method" that handles all the records
|
||||||
|| !language->auto_load_enabled ())
|
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. */
|
/* No message is printed, just skip it. */
|
||||||
continue;
|
continue;
|
||||||
|
@ -944,8 +957,8 @@ source_section_scripts (struct objfile *objfile, const char *section_name,
|
||||||
_("auto-load: Loading %s script "
|
_("auto-load: Loading %s script "
|
||||||
"\"%s\" from section \"%s\" of "
|
"\"%s\" from section \"%s\" of "
|
||||||
"objfile \"%s\".\n"),
|
"objfile \"%s\".\n"),
|
||||||
language->name, full_path, section_name,
|
ext_lang_name (language), full_path,
|
||||||
objfile_name (objfile)))
|
section_name, objfile_name (objfile)))
|
||||||
opened = 0;
|
opened = 0;
|
||||||
}
|
}
|
||||||
else
|
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\
|
warning (_("Missing auto-load scripts referenced in section %s\n\
|
||||||
of file %s\n\
|
of file %s\n\
|
||||||
Use `info auto-load %s-scripts [REGEXP]' to list them."),
|
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,
|
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 this file is not currently loaded, load it. */
|
||||||
if (opened && !in_hash_table)
|
if (opened && !in_hash_table)
|
||||||
{
|
sourcer (language, objfile, stream, full_path);
|
||||||
gdb_assert (language->source_script_for_objfile != NULL);
|
|
||||||
language->source_script_for_objfile (objfile, stream, full_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
do_cleanups (back_to);
|
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)
|
if (!global_auto_load || (objfile->flags & OBJF_NOT_FILENAME) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Load any scripts for this objfile. e.g. foo-gdb.gdb, foo-gdb.py. */
|
/* Load any extension language scripts for this objfile.
|
||||||
auto_load_objfile_script (objfile, &script_language_gdb);
|
E.g., foo-gdb.gdb, foo-gdb.py. */
|
||||||
auto_load_objfile_script (objfile, gdbpy_script_language_defn ());
|
auto_load_ext_lang_scripts_for_objfile (objfile);
|
||||||
|
|
||||||
/* Load any scripts mentioned in AUTO_SECTION_NAME (.debug_gdb_scripts). */
|
/* Load any scripts mentioned in AUTO_SECTION_NAME (.debug_gdb_scripts). */
|
||||||
auto_load_section_scripts (objfile, AUTO_SECTION_NAME);
|
auto_load_section_scripts (objfile, AUTO_SECTION_NAME);
|
||||||
|
@ -1056,7 +1067,7 @@ struct collect_matching_scripts_data
|
||||||
{
|
{
|
||||||
VEC (loaded_script_ptr) **scripts_p;
|
VEC (loaded_script_ptr) **scripts_p;
|
||||||
|
|
||||||
const struct script_language *language;
|
const struct extension_language_defn *language;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Traversal function for htab_traverse.
|
/* Traversal function for htab_traverse.
|
||||||
|
@ -1122,7 +1133,7 @@ char auto_load_info_scripts_pattern_nl[] = "";
|
||||||
|
|
||||||
void
|
void
|
||||||
auto_load_info_scripts (char *pattern, int from_tty,
|
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 ui_out *uiout = current_uiout;
|
||||||
struct auto_load_pspace_info *pspace_info;
|
struct auto_load_pspace_info *pspace_info;
|
||||||
|
@ -1205,7 +1216,7 @@ auto_load_info_scripts (char *pattern, int from_tty,
|
||||||
static void
|
static void
|
||||||
info_auto_load_gdb_scripts (char *pattern, int from_tty)
|
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'. */
|
/* 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);
|
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
|
/* 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
|
before calling this function. Always set SCRIPT_NOT_FOUND_WARNING_PRINTED
|
||||||
of PSPACE_INFO. */
|
of PSPACE_INFO. */
|
||||||
|
|
||||||
int
|
static int
|
||||||
script_not_found_warning_print (struct auto_load_pspace_info *pspace_info)
|
script_not_found_warning_print (struct auto_load_pspace_info *pspace_info)
|
||||||
{
|
{
|
||||||
int retval = !pspace_info->script_not_found_warning_printed;
|
int retval = !pspace_info->script_not_found_warning_printed;
|
||||||
|
@ -1369,7 +1394,7 @@ void
|
||||||
_initialize_auto_load (void)
|
_initialize_auto_load (void)
|
||||||
{
|
{
|
||||||
struct cmd_list_element *cmd;
|
struct cmd_list_element *cmd;
|
||||||
char *scripts_directory_help;
|
char *scripts_directory_help, *gdb_name_help, *python_name_help;
|
||||||
|
|
||||||
auto_load_pspace_data
|
auto_load_pspace_data
|
||||||
= register_program_space_data_with_cleanup (NULL,
|
= register_program_space_data_with_cleanup (NULL,
|
||||||
|
@ -1413,27 +1438,34 @@ Usage: info auto-load local-gdbinit"),
|
||||||
auto_load_info_cmdlist_get ());
|
auto_load_info_cmdlist_get ());
|
||||||
|
|
||||||
auto_load_dir = xstrdup (AUTO_LOAD_DIR);
|
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
|
#ifdef HAVE_PYTHON
|
||||||
_("\
|
python_name_help
|
||||||
Automatically loaded Python scripts (named OBJFILE%s) and GDB scripts\n\
|
= xstrprintf (_("\
|
||||||
(named OBJFILE%s) are located in one of the directories listed by this\n\
|
Python scripts: OBJFILE%s\n"),
|
||||||
option.\n\
|
ext_lang_auto_load_suffix (&extension_language_python));
|
||||||
%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"),
|
|
||||||
#endif
|
#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 \
|
This option is ignored for the kinds of scripts \
|
||||||
having 'set auto-load ... off'.\n\
|
having 'set auto-load ... off'.\n\
|
||||||
Directories listed here need to be present also \
|
Directories listed here need to be present also \
|
||||||
in the 'set auto-load safe-path'\n\
|
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,
|
add_setshow_optional_filename_cmd ("scripts-directory", class_support,
|
||||||
&auto_load_dir, _("\
|
&auto_load_dir, _("\
|
||||||
Set the list of directories from which to load auto-loaded scripts."), _("\
|
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_set_cmdlist_get (),
|
||||||
auto_load_show_cmdlist_get ());
|
auto_load_show_cmdlist_get ());
|
||||||
xfree (scripts_directory_help);
|
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 = xstrdup (AUTO_LOAD_SAFE_PATH);
|
||||||
auto_load_safe_path_vec_update ();
|
auto_load_safe_path_vec_update ();
|
||||||
|
|
|
@ -20,25 +20,10 @@
|
||||||
#ifndef AUTO_LOAD_H
|
#ifndef AUTO_LOAD_H
|
||||||
#define AUTO_LOAD_H 1
|
#define AUTO_LOAD_H 1
|
||||||
|
|
||||||
|
struct objfile;
|
||||||
struct program_space;
|
struct program_space;
|
||||||
|
struct auto_load_pspace_info;
|
||||||
struct script_language
|
struct extension_language_defn;
|
||||||
{
|
|
||||||
/* 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);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern int global_auto_load;
|
extern int global_auto_load;
|
||||||
|
|
||||||
|
@ -48,16 +33,12 @@ extern int auto_load_local_gdbinit_loaded;
|
||||||
|
|
||||||
extern struct auto_load_pspace_info *
|
extern struct auto_load_pspace_info *
|
||||||
get_auto_load_pspace_data_for_loading (struct program_space *pspace);
|
get_auto_load_pspace_data_for_loading (struct program_space *pspace);
|
||||||
extern int maybe_add_script (struct auto_load_pspace_info *pspace_info,
|
extern void auto_load_objfile_script (struct objfile *objfile,
|
||||||
int loaded, const char *name,
|
const struct extension_language_defn *);
|
||||||
const char *full_path,
|
|
||||||
const struct script_language *language);
|
|
||||||
extern void load_auto_scripts_for_objfile (struct objfile *objfile);
|
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 char auto_load_info_scripts_pattern_nl[];
|
||||||
extern void auto_load_info_scripts (char *pattern, int from_tty,
|
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_set_cmdlist_get (void);
|
||||||
extern struct cmd_list_element **auto_load_show_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,
|
extern int file_is_auto_load_safe (const char *filename,
|
||||||
const char *debug_fmt, ...);
|
const char *debug_fmt, ...);
|
||||||
|
|
||||||
|
extern int auto_load_gdb_scripts_enabled
|
||||||
|
(const struct extension_language_defn *extlang);
|
||||||
|
|
||||||
#endif /* AUTO_LOAD_H */
|
#endif /* AUTO_LOAD_H */
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
#undef savestring
|
#undef savestring
|
||||||
|
|
||||||
#include "mi/mi-common.h"
|
#include "mi/mi-common.h"
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
|
|
||||||
/* Enums for exception-handling support. */
|
/* Enums for exception-handling support. */
|
||||||
enum exception_event_kind
|
enum exception_event_kind
|
||||||
|
@ -1047,14 +1047,18 @@ condition_command (char *arg, int from_tty)
|
||||||
ALL_BREAKPOINTS (b)
|
ALL_BREAKPOINTS (b)
|
||||||
if (b->number == bnum)
|
if (b->number == bnum)
|
||||||
{
|
{
|
||||||
/* Check if this breakpoint has a Python object assigned to
|
/* Check if this breakpoint has a "stop" method implemented in an
|
||||||
it, and if it has a definition of the "stop"
|
extension language. This method and conditions entered into GDB
|
||||||
method. This method and conditions entered into GDB from
|
from the CLI are mutually exclusive. */
|
||||||
the CLI are mutually exclusive. */
|
const struct extension_language_defn *extlang
|
||||||
if (b->py_bp_object
|
= get_breakpoint_cond_ext_lang (b, EXT_LANG_NONE);
|
||||||
&& gdbpy_breakpoint_has_py_cond (b->py_bp_object))
|
|
||||||
error (_("Cannot set a condition where a Python 'stop' "
|
if (extlang != NULL)
|
||||||
"method has been defined in the breakpoint."));
|
{
|
||||||
|
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);
|
set_breakpoint_condition (b, p, from_tty);
|
||||||
|
|
||||||
if (is_breakpoint (b))
|
if (is_breakpoint (b))
|
||||||
|
@ -5188,9 +5192,9 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Evaluate Python breakpoints that have a "stop" method implemented. */
|
/* Evaluate extension language breakpoints that have a "stop" method
|
||||||
if (b->py_bp_object)
|
implemented. */
|
||||||
bs->stop = gdbpy_should_stop (b->py_bp_object);
|
bs->stop = breakpoint_ext_lang_cond_says_stop (b);
|
||||||
|
|
||||||
if (is_watchpoint (b))
|
if (is_watchpoint (b))
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#include "cli/cli-cmds.h"
|
#include "cli/cli-cmds.h"
|
||||||
#include "cli/cli-utils.h"
|
#include "cli/cli-utils.h"
|
||||||
|
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
|
|
||||||
#ifdef TUI
|
#ifdef TUI
|
||||||
#include "tui/tui.h" /* For tui_active et.al. */
|
#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
|
static void
|
||||||
source_script_from_stream (FILE *stream, const char *file)
|
source_script_from_stream (FILE *stream, const char *file)
|
||||||
{
|
{
|
||||||
if (script_ext_mode != script_ext_off
|
if (script_ext_mode != script_ext_off)
|
||||||
&& strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py"))
|
|
||||||
{
|
{
|
||||||
if (have_python ())
|
const struct extension_language_defn *extlang
|
||||||
source_python_script (stream, file);
|
= get_ext_lang_of_file (file);
|
||||||
else if (script_ext_mode == script_ext_soft)
|
|
||||||
|
if (extlang != NULL)
|
||||||
{
|
{
|
||||||
/* Fallback to GDB script mode. */
|
if (ext_lang_present_p (extlang))
|
||||||
script_from_file (stream, file);
|
{
|
||||||
|
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.
|
/* Worker to perform the "source" command.
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "cli/cli-script.h"
|
#include "cli/cli-script.h"
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
|
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
#include "interps.h"
|
#include "interps.h"
|
||||||
|
|
||||||
/* Prototypes for local functions. */
|
/* Prototypes for local functions. */
|
||||||
|
@ -590,7 +590,7 @@ execute_control_command (struct command_line *cmd)
|
||||||
|
|
||||||
case python_control:
|
case python_control:
|
||||||
{
|
{
|
||||||
eval_python_from_control_command (cmd);
|
eval_ext_lang_from_control_command (cmd);
|
||||||
ret = simple_control;
|
ret = simple_control;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
9
gdb/configure
vendored
9
gdb/configure
vendored
|
@ -8672,11 +8672,10 @@ rm -f conftest.err conftest.$ac_ext
|
||||||
$as_echo "${python_has_threads}" >&6; }
|
$as_echo "${python_has_threads}" >&6; }
|
||||||
CPPFLAGS="${saved_CPPFLAGS}"
|
CPPFLAGS="${saved_CPPFLAGS}"
|
||||||
else
|
else
|
||||||
# Even if Python support is not compiled in, we need to have these files
|
# Even if Python support is not compiled in, we need to have this file
|
||||||
# included.
|
# included so that the "python" command, et.al., still exists.
|
||||||
CONFIG_OBS="$CONFIG_OBS python.o py-value.o py-prettyprint.o py-auto-load.o"
|
CONFIG_OBS="$CONFIG_OBS python.o"
|
||||||
CONFIG_SRCS="$CONFIG_SRCS python/python.c python/py-value.c \
|
CONFIG_SRCS="$CONFIG_SRCS python/python.c"
|
||||||
python/py-prettyprint.c python/py-auto-load.c"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1045,11 +1045,10 @@ if test "${have_libpython}" != no; then
|
||||||
AC_MSG_RESULT(${python_has_threads})
|
AC_MSG_RESULT(${python_has_threads})
|
||||||
CPPFLAGS="${saved_CPPFLAGS}"
|
CPPFLAGS="${saved_CPPFLAGS}"
|
||||||
else
|
else
|
||||||
# Even if Python support is not compiled in, we need to have these files
|
# Even if Python support is not compiled in, we need to have this file
|
||||||
# included.
|
# included so that the "python" command, et.al., still exists.
|
||||||
CONFIG_OBS="$CONFIG_OBS python.o py-value.o py-prettyprint.o py-auto-load.o"
|
CONFIG_OBS="$CONFIG_OBS python.o"
|
||||||
CONFIG_SRCS="$CONFIG_SRCS python/python.c python/py-value.c \
|
CONFIG_SRCS="$CONFIG_SRCS python/python.c"
|
||||||
python/py-prettyprint.c python/py-auto-load.c"
|
|
||||||
fi
|
fi
|
||||||
AC_SUBST(PYTHON_CFLAGS)
|
AC_SUBST(PYTHON_CFLAGS)
|
||||||
AC_SUBST(PYTHON_CPPFLAGS)
|
AC_SUBST(PYTHON_CPPFLAGS)
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "valprint.h"
|
#include "valprint.h"
|
||||||
#include "cp-support.h"
|
#include "cp-support.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "typeprint.h"
|
#include "typeprint.h"
|
||||||
|
|
||||||
|
@ -584,17 +584,17 @@ cp_print_value (struct type *type, struct type *real_type,
|
||||||
{
|
{
|
||||||
int result = 0;
|
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. */
|
baseclass if possible. */
|
||||||
if (!options->raw)
|
if (!options->raw)
|
||||||
result = apply_val_pretty_printer (baseclass, base_valaddr,
|
result
|
||||||
thisoffset + boffset,
|
= apply_ext_lang_val_pretty_printer (baseclass, base_valaddr,
|
||||||
value_address (base_val),
|
thisoffset + boffset,
|
||||||
stream, recurse, base_val,
|
value_address (base_val),
|
||||||
options, current_language);
|
stream, recurse,
|
||||||
|
base_val, options,
|
||||||
|
current_language);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
cp_print_value_fields (baseclass, thistype, base_valaddr,
|
cp_print_value_fields (baseclass, thistype, base_valaddr,
|
||||||
thisoffset + boffset,
|
thisoffset + boffset,
|
||||||
|
|
|
@ -159,13 +159,9 @@ extern char *debug_file_directory;
|
||||||
handler. Otherwise, SIGINT simply sets a flag; code that might
|
handler. Otherwise, SIGINT simply sets a flag; code that might
|
||||||
take a long time, and which ought to be interruptible, checks this
|
take a long time, and which ought to be interruptible, checks this
|
||||||
flag using the QUIT macro.
|
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
|
These functions use the extension_language_ops API to allow extension
|
||||||
variables. */
|
language(s) and GDB SIGINT handling to coexist seamlessly. */
|
||||||
|
|
||||||
/* Clear the quit flag. */
|
/* Clear the quit flag. */
|
||||||
extern void clear_quit_flag (void);
|
extern void clear_quit_flag (void);
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include "valprint.h"
|
#include "valprint.h"
|
||||||
#include "gdb_obstack.h"
|
#include "gdb_obstack.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "python/python.h"
|
|
||||||
|
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
|
|
||||||
|
|
285
gdb/extension-priv.h
Normal file
285
gdb/extension-priv.h
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
/* Private implementation details of interface between gdb and its
|
||||||
|
extension languages.
|
||||||
|
|
||||||
|
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef EXTENSION_PRIV_H
|
||||||
|
#define EXTENSION_PRIV_H
|
||||||
|
|
||||||
|
#include "extension.h"
|
||||||
|
|
||||||
|
/* The return code for some API calls. */
|
||||||
|
|
||||||
|
enum ext_lang_rc
|
||||||
|
{
|
||||||
|
/* The operation completed successfully. */
|
||||||
|
EXT_LANG_RC_OK,
|
||||||
|
|
||||||
|
/* The operation was not performed (e.g., no pretty-printer). */
|
||||||
|
EXT_LANG_RC_NOP,
|
||||||
|
|
||||||
|
/* There was an error (e.g., Python error while printing a value).
|
||||||
|
When an error occurs no further extension languages are tried.
|
||||||
|
This is to preserve existing behaviour, and because it's convenient
|
||||||
|
for Python developers.
|
||||||
|
Note: This is different than encountering a memory error trying to read
|
||||||
|
a value for pretty-printing. Here we're referring to, e.g., programming
|
||||||
|
errors that trigger an exception in the extension language. */
|
||||||
|
EXT_LANG_RC_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
/* High level description of an extension/scripting language.
|
||||||
|
An entry for each is compiled into GDB regardless of whether the support
|
||||||
|
is present. This is done so that we can issue meaningful errors if the
|
||||||
|
support is not compiled in. */
|
||||||
|
|
||||||
|
struct extension_language_defn
|
||||||
|
{
|
||||||
|
/* Enum of the extension language. */
|
||||||
|
enum extension_language language;
|
||||||
|
|
||||||
|
/* The name of the extension language, lowercase. E.g., python. */
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
/* The capitalized name of the extension language.
|
||||||
|
For python this is "Python". For gdb this is "GDB". */
|
||||||
|
const char *capitalized_name;
|
||||||
|
|
||||||
|
/* The file suffix of this extension language. E.g., ".py". */
|
||||||
|
const char *suffix;
|
||||||
|
|
||||||
|
/* The suffix of per-objfile scripts to auto-load.
|
||||||
|
E.g., When the program loads libfoo.so, look for libfoo.so-gdb.py. */
|
||||||
|
const char *auto_load_suffix;
|
||||||
|
|
||||||
|
/* We support embedding external extension language code in GDB's own
|
||||||
|
scripting language. We do this by having a special command that begins
|
||||||
|
the extension language snippet, and terminate it with "end".
|
||||||
|
This specifies the control type used to implement this. */
|
||||||
|
enum command_control_type cli_control_type;
|
||||||
|
|
||||||
|
/* A pointer to the "methods" to load scripts in this language,
|
||||||
|
or NULL if the support is not compiled into GDB. */
|
||||||
|
const struct extension_language_script_ops *script_ops;
|
||||||
|
|
||||||
|
/* Either a pointer to the "methods" of the extension language interface
|
||||||
|
or NULL if the support is not compiled into GDB.
|
||||||
|
This is also NULL for GDB's own scripting language which is relatively
|
||||||
|
primitive, and doesn't provide these features. */
|
||||||
|
const struct extension_language_ops *ops;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The interface for loading scripts from external extension languages,
|
||||||
|
as well as GDB's own scripting language.
|
||||||
|
All of these methods are required to be implemented. */
|
||||||
|
|
||||||
|
struct extension_language_script_ops
|
||||||
|
{
|
||||||
|
/* Load a script. This is called, e.g., via the "source" command.
|
||||||
|
If there's an error while processing the script this function may,
|
||||||
|
but is not required to, throw an error. */
|
||||||
|
script_sourcer_func *script_sourcer;
|
||||||
|
|
||||||
|
/* Load a script attached to an objfile.
|
||||||
|
If there's an error while processing the script this function may,
|
||||||
|
but is not required to, throw an error. */
|
||||||
|
objfile_script_sourcer_func *objfile_script_sourcer;
|
||||||
|
|
||||||
|
/* Return non-zero if auto-loading scripts in this extension language
|
||||||
|
is enabled. */
|
||||||
|
int (*auto_load_enabled) (const struct extension_language_defn *);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The interface for making calls from GDB to an external extension
|
||||||
|
language. This is for non-script-loading related functionality, like
|
||||||
|
pretty-printing, etc. The reason these are separated out is GDB's own
|
||||||
|
scripting language makes use of extension_language_script_opts, but it
|
||||||
|
makes no use of these. There is no (current) intention to split
|
||||||
|
extension_language_ops up any further.
|
||||||
|
All of these methods are optional and may be NULL, except where
|
||||||
|
otherwise indicated. */
|
||||||
|
|
||||||
|
struct extension_language_ops
|
||||||
|
{
|
||||||
|
/* Called at the end of gdb initialization to give the extension language
|
||||||
|
an opportunity to finish up. This is useful for things like adding
|
||||||
|
new commands where one has to wait until gdb itself is initialized. */
|
||||||
|
void (*finish_initialization) (const struct extension_language_defn *);
|
||||||
|
|
||||||
|
/* Return non-zero if the extension language successfully initialized.
|
||||||
|
This method is required. */
|
||||||
|
int (*initialized) (const struct extension_language_defn *);
|
||||||
|
|
||||||
|
/* Process a sequence of commands embedded in GDB's own scripting language.
|
||||||
|
E.g.,
|
||||||
|
python
|
||||||
|
print 42
|
||||||
|
end */
|
||||||
|
void (*eval_from_control_command) (const struct extension_language_defn *,
|
||||||
|
struct command_line *);
|
||||||
|
|
||||||
|
/* Type-printing support:
|
||||||
|
start_type_printers, apply_type_printers, free_type_printers.
|
||||||
|
These methods are optional and may be NULL, but if one of them is
|
||||||
|
implemented then they all must be. */
|
||||||
|
|
||||||
|
/* Called before printing a type. */
|
||||||
|
void (*start_type_printers) (const struct extension_language_defn *,
|
||||||
|
struct ext_lang_type_printers *);
|
||||||
|
|
||||||
|
/* Try to pretty-print TYPE. If successful the pretty-printed type is
|
||||||
|
stored in *PRETTIED_TYPE, and the caller must free it.
|
||||||
|
Returns EXT_LANG_RC_OK upon success, EXT_LANG_RC_NOP if the type
|
||||||
|
is not recognized, and EXT_LANG_RC_ERROR if an error was encountered.
|
||||||
|
This function has a bit of a funny name, since it actually applies
|
||||||
|
recognizers, but this seemed clearer given the start_type_printers
|
||||||
|
and free_type_printers functions. */
|
||||||
|
enum ext_lang_rc (*apply_type_printers)
|
||||||
|
(const struct extension_language_defn *,
|
||||||
|
const struct ext_lang_type_printers *,
|
||||||
|
struct type *, char **prettied_type);
|
||||||
|
|
||||||
|
/* Called after a type has been printed to give the type pretty-printer
|
||||||
|
mechanism an opportunity to clean up. */
|
||||||
|
void (*free_type_printers) (const struct extension_language_defn *,
|
||||||
|
struct ext_lang_type_printers *);
|
||||||
|
|
||||||
|
/* Try to pretty-print a value of type TYPE located at VALADDR
|
||||||
|
+ EMBEDDED_OFFSET, which came from the inferior at address ADDRESS
|
||||||
|
+ EMBEDDED_OFFSET, onto stdio stream STREAM according to OPTIONS.
|
||||||
|
VAL is the whole object that came from ADDRESS. VALADDR must point to
|
||||||
|
the head of VAL's contents buffer.
|
||||||
|
Returns EXT_LANG_RC_OK upon success, EXT_LANG_RC_NOP if the value
|
||||||
|
is not recognized, and EXT_LANG_RC_ERROR if an error was encountered. */
|
||||||
|
enum ext_lang_rc (*apply_val_pretty_printer)
|
||||||
|
(const struct extension_language_defn *,
|
||||||
|
struct type *type, const gdb_byte *valaddr,
|
||||||
|
int embedded_offset, CORE_ADDR address,
|
||||||
|
struct ui_file *stream, int recurse,
|
||||||
|
const struct value *val, const struct value_print_options *options,
|
||||||
|
const struct language_defn *language);
|
||||||
|
|
||||||
|
/* GDB access to the "frame filter" feature.
|
||||||
|
FRAME is the source frame to start frame-filter invocation. FLAGS is an
|
||||||
|
integer holding the flags for printing. The following elements of
|
||||||
|
the FRAME_FILTER_FLAGS enum denotes the make-up of FLAGS:
|
||||||
|
PRINT_LEVEL is a flag indicating whether to print the frame's
|
||||||
|
relative level in the output. PRINT_FRAME_INFO is a flag that
|
||||||
|
indicates whether this function should print the frame
|
||||||
|
information, PRINT_ARGS is a flag that indicates whether to print
|
||||||
|
frame arguments, and PRINT_LOCALS, likewise, with frame local
|
||||||
|
variables. ARGS_TYPE is an enumerator describing the argument
|
||||||
|
format, OUT is the output stream to print. FRAME_LOW is the
|
||||||
|
beginning of the slice of frames to print, and FRAME_HIGH is the
|
||||||
|
upper limit of the frames to count. Returns SCR_BT_ERROR on error,
|
||||||
|
or SCR_BT_COMPLETED on success. */
|
||||||
|
enum ext_lang_bt_status (*apply_frame_filter)
|
||||||
|
(const struct extension_language_defn *,
|
||||||
|
struct frame_info *frame, int flags, enum ext_lang_frame_args args_type,
|
||||||
|
struct ui_out *out, int frame_low, int frame_high);
|
||||||
|
|
||||||
|
/* Update values held by the extension language when OBJFILE is discarded.
|
||||||
|
New global types must be created for every such value, which must then be
|
||||||
|
updated to use the new types.
|
||||||
|
This function typically just iterates over all appropriate values and
|
||||||
|
calls preserve_one_value for each one.
|
||||||
|
COPIED_TYPES is used to prevent cycles / duplicates and is passed to
|
||||||
|
preserve_one_value. */
|
||||||
|
void (*preserve_values) (const struct extension_language_defn *,
|
||||||
|
struct objfile *objfile, htab_t copied_types);
|
||||||
|
|
||||||
|
/* Return non-zero if there is a stop condition for the breakpoint.
|
||||||
|
This is used to implement the restriction that a breakpoint may have
|
||||||
|
at most one condition. */
|
||||||
|
int (*breakpoint_has_cond) (const struct extension_language_defn *,
|
||||||
|
struct breakpoint *);
|
||||||
|
|
||||||
|
/* Return a value of enum ext_lang_bp_stop indicating if there is a stop
|
||||||
|
condition for the breakpoint, and if so whether the program should
|
||||||
|
stop. This is called when the program has stopped at the specified
|
||||||
|
breakpoint.
|
||||||
|
While breakpoints can have at most one condition, this is called for
|
||||||
|
every extension language, even if another extension language has a
|
||||||
|
"stop" method: other kinds of breakpoints may be implemented using
|
||||||
|
this method, e.g., "finish breakpoints" in Python. */
|
||||||
|
enum ext_lang_bp_stop (*breakpoint_cond_says_stop)
|
||||||
|
(const struct extension_language_defn *, struct breakpoint *);
|
||||||
|
|
||||||
|
/* The next three are used to connect GDB's SIGINT handling with the
|
||||||
|
extension language's.
|
||||||
|
|
||||||
|
Terminology: If an extension language can use GDB's SIGINT handling then
|
||||||
|
we say the extension language has "cooperative SIGINT handling".
|
||||||
|
Python is an example of this.
|
||||||
|
|
||||||
|
These need not be implemented, but if one of them is implemented
|
||||||
|
then they all must be. */
|
||||||
|
|
||||||
|
/* Clear the SIGINT indicator. */
|
||||||
|
void (*clear_quit_flag) (const struct extension_language_defn *);
|
||||||
|
|
||||||
|
/* Set the SIGINT indicator.
|
||||||
|
This is called by GDB's SIGINT handler and must be async-safe. */
|
||||||
|
void (*set_quit_flag) (const struct extension_language_defn *);
|
||||||
|
|
||||||
|
/* Return non-zero if a SIGINT has occurred.
|
||||||
|
This is expected to also clear the indicator. */
|
||||||
|
int (*check_quit_flag) (const struct extension_language_defn *);
|
||||||
|
|
||||||
|
/* Called before gdb prints its prompt, giving extension languages an
|
||||||
|
opportunity to change it with set_prompt.
|
||||||
|
Returns EXT_LANG_RC_OK if the prompt was changed, EXT_LANG_RC_NOP if
|
||||||
|
the prompt was not changed, and EXT_LANG_RC_ERROR if an error was
|
||||||
|
encountered.
|
||||||
|
Extension languages are called in order, and once the prompt is
|
||||||
|
changed or an error occurs no further languages are called. */
|
||||||
|
enum ext_lang_rc (*before_prompt) (const struct extension_language_defn *,
|
||||||
|
const char *current_gdb_prompt);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* State necessary to restore a signal handler to its previous value. */
|
||||||
|
|
||||||
|
struct signal_handler
|
||||||
|
{
|
||||||
|
/* Non-zero if "handler" has been set. */
|
||||||
|
int handler_saved;
|
||||||
|
|
||||||
|
/* The signal handler. */
|
||||||
|
RETSIGTYPE (*handler) ();
|
||||||
|
};
|
||||||
|
|
||||||
|
/* State necessary to restore the currently active extension language
|
||||||
|
to is previous value. */
|
||||||
|
|
||||||
|
struct active_ext_lang_state
|
||||||
|
{
|
||||||
|
/* The previously active extension language. */
|
||||||
|
const struct extension_language_defn *ext_lang;
|
||||||
|
|
||||||
|
/* Its SIGINT handler. */
|
||||||
|
struct signal_handler sigint_handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct extension_language_defn *get_active_ext_lang (void);
|
||||||
|
|
||||||
|
extern struct active_ext_lang_state *set_active_ext_lang
|
||||||
|
(const struct extension_language_defn *);
|
||||||
|
|
||||||
|
extern void restore_active_ext_lang (struct active_ext_lang_state *previous);
|
||||||
|
|
||||||
|
#endif /* EXTENSION_PRIV_H */
|
871
gdb/extension.c
Normal file
871
gdb/extension.c
Normal file
|
@ -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);
|
||||||
|
}
|
214
gdb/extension.h
Normal file
214
gdb/extension.h
Normal file
|
@ -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 "main.h"
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "cli/cli-cmds.h"
|
#include "cli/cli-cmds.h"
|
||||||
#include "python/python.h"
|
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "auto-load.h"
|
#include "auto-load.h"
|
||||||
#include "maint.h"
|
#include "maint.h"
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "mi-getopt.h"
|
#include "mi-getopt.h"
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "mi-parse.h"
|
#include "mi-parse.h"
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
|
||||||
int i;
|
int i;
|
||||||
struct cleanup *cleanup_stack;
|
struct cleanup *cleanup_stack;
|
||||||
struct frame_info *fi;
|
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 raw_arg = 0;
|
||||||
int oind = 0;
|
int oind = 0;
|
||||||
enum opt
|
enum opt
|
||||||
|
@ -141,14 +141,14 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
|
||||||
if (py_frame_low == -1)
|
if (py_frame_low == -1)
|
||||||
py_frame_low++;
|
py_frame_low++;
|
||||||
|
|
||||||
result = apply_frame_filter (get_current_frame (), flags,
|
result = apply_ext_lang_frame_filter (get_current_frame (), flags,
|
||||||
NO_VALUES, current_uiout,
|
NO_VALUES, current_uiout,
|
||||||
py_frame_low, frame_high);
|
py_frame_low, frame_high);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||||
if "--no-frame-filters" has been specified from the command. */
|
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
|
/* Now let's print the frames up to frame_high, or until there are
|
||||||
frames in the stack. */
|
frames in the stack. */
|
||||||
|
@ -200,7 +200,7 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc)
|
||||||
{
|
{
|
||||||
struct frame_info *frame;
|
struct frame_info *frame;
|
||||||
int raw_arg = 0;
|
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 print_value;
|
||||||
int oind = 0;
|
int oind = 0;
|
||||||
int skip_unavailable = 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;
|
int flags = PRINT_LEVEL | PRINT_LOCALS;
|
||||||
|
|
||||||
result = apply_frame_filter (frame, flags, print_value,
|
result = apply_ext_lang_frame_filter (frame, flags, print_value,
|
||||||
current_uiout, 0, 0);
|
current_uiout, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||||
if "--no-frame-filters" has been specified from the command. */
|
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,
|
list_args_or_locals (locals, print_value, frame,
|
||||||
skip_unavailable);
|
skip_unavailable);
|
||||||
|
@ -284,7 +284,7 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
|
||||||
int raw_arg = 0;
|
int raw_arg = 0;
|
||||||
int oind = 0;
|
int oind = 0;
|
||||||
int skip_unavailable = 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
|
enum opt
|
||||||
{
|
{
|
||||||
NO_FRAME_FILTERS,
|
NO_FRAME_FILTERS,
|
||||||
|
@ -360,14 +360,14 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
|
||||||
if (py_frame_low == -1)
|
if (py_frame_low == -1)
|
||||||
py_frame_low++;
|
py_frame_low++;
|
||||||
|
|
||||||
result = apply_frame_filter (get_current_frame (), flags,
|
result = apply_ext_lang_frame_filter (get_current_frame (), flags,
|
||||||
print_values, current_uiout,
|
print_values, current_uiout,
|
||||||
py_frame_low, frame_high);
|
py_frame_low, frame_high);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||||
if "--no-frame-filters" has been specified from the command. */
|
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
|
/* Now let's print the frames up to frame_high, or until there are
|
||||||
frames in the stack. */
|
frames in the stack. */
|
||||||
|
@ -397,7 +397,7 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc)
|
||||||
{
|
{
|
||||||
struct frame_info *frame;
|
struct frame_info *frame;
|
||||||
int raw_arg = 0;
|
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 print_value;
|
||||||
int oind = 0;
|
int oind = 0;
|
||||||
int skip_unavailable = 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;
|
int flags = PRINT_LEVEL | PRINT_ARGS | PRINT_LOCALS;
|
||||||
|
|
||||||
result = apply_frame_filter (frame, flags, print_value,
|
result = apply_ext_lang_frame_filter (frame, flags, print_value,
|
||||||
current_uiout, 0, 0);
|
current_uiout, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||||
if "--no-frame-filters" has been specified from the command. */
|
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,
|
list_args_or_locals (all, print_value, frame,
|
||||||
skip_unavailable);
|
skip_unavailable);
|
||||||
|
|
|
@ -52,9 +52,7 @@
|
||||||
#include "ctf.h"
|
#include "ctf.h"
|
||||||
#include "ada-lang.h"
|
#include "ada-lang.h"
|
||||||
#include "linespec.h"
|
#include "linespec.h"
|
||||||
#ifdef HAVE_PYTHON
|
#include "extension.h"
|
||||||
#include "python/python-internal.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/time.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, "undefined-command-error-code");
|
||||||
ui_out_field_string (uiout, NULL, "exec-run-start-option");
|
ui_out_field_string (uiout, NULL, "exec-run-start-option");
|
||||||
|
|
||||||
#if HAVE_PYTHON
|
if (ext_lang_initialized_p (get_ext_lang_defn (EXT_LANG_PYTHON)))
|
||||||
if (gdb_python_initialized)
|
|
||||||
ui_out_field_string (uiout, NULL, "python");
|
ui_out_field_string (uiout, NULL, "python");
|
||||||
#endif
|
|
||||||
|
|
||||||
do_cleanups (cleanup);
|
do_cleanups (cleanup);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "python.h"
|
#include "python.h"
|
||||||
#include "auto-load.h"
|
#include "auto-load.h"
|
||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
|
||||||
|
|
||||||
#include "python-internal.h"
|
#include "python-internal.h"
|
||||||
|
|
||||||
/* User-settable option to enable/disable auto-loading of Python scripts:
|
/* 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);
|
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
|
int
|
||||||
auto_load_python_scripts_enabled (void)
|
gdbpy_auto_load_enabled (const struct extension_language_defn *extlang)
|
||||||
{
|
{
|
||||||
return auto_load_python_scripts;
|
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". */
|
/* Wrapper for "info auto-load python-scripts". */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
info_auto_load_python_scripts (char *pattern, int from_tty)
|
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
|
int
|
||||||
|
@ -125,16 +105,3 @@ Print the list of automatically loaded Python scripts, deprecated."));
|
||||||
|
|
||||||
return 0;
|
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
|
stopped at the breakpoint. Otherwise the inferior will be
|
||||||
allowed to continue. */
|
allowed to continue. */
|
||||||
|
|
||||||
int
|
enum ext_lang_bp_stop
|
||||||
gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
|
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;
|
PyObject *py_bp = (PyObject *) bp_obj;
|
||||||
struct breakpoint *b = bp_obj->bp;
|
struct gdbarch *garch;
|
||||||
struct gdbarch *garch = b->gdbarch ? b->gdbarch : get_current_arch ();
|
struct cleanup *cleanup;
|
||||||
struct cleanup *cleanup = ensure_python_env (garch, current_language);
|
|
||||||
|
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)
|
if (bp_obj->is_finish_bp)
|
||||||
bpfinishpy_pre_stop_hook (bp_obj);
|
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);
|
PyObject *result = PyObject_CallMethod (py_bp, stop_func, NULL);
|
||||||
|
|
||||||
|
stop = 1;
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
int evaluate = PyObject_IsTrue (result);
|
int evaluate = PyObject_IsTrue (result);
|
||||||
|
@ -790,7 +798,9 @@ gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
|
||||||
|
|
||||||
do_cleanups (cleanup);
|
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.
|
/* Checks if the "stop" method exists in this breakpoint.
|
||||||
|
@ -798,17 +808,21 @@ gdbpy_should_stop (struct gdbpy_breakpoint_object *bp_obj)
|
||||||
conditions. */
|
conditions. */
|
||||||
|
|
||||||
int
|
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;
|
int has_func;
|
||||||
PyObject *py_bp = (PyObject *) bp_obj;
|
PyObject *py_bp;
|
||||||
struct gdbarch *garch = bp_obj->bp->gdbarch ? bp_obj->bp->gdbarch :
|
struct gdbarch *garch;
|
||||||
get_current_arch ();
|
struct cleanup *cleanup;
|
||||||
struct cleanup *cleanup = ensure_python_env (garch, current_language);
|
|
||||||
|
|
||||||
if (py_bp != NULL)
|
if (b->py_bp_object == NULL)
|
||||||
has_func = PyObject_HasAttrString (py_bp, stop_func);
|
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);
|
do_cleanups (cleanup);
|
||||||
|
|
||||||
return has_func;
|
return has_func;
|
||||||
|
@ -947,16 +961,30 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* If the attribute trying to be set is the "stop" method,
|
/* If the attribute trying to be set is the "stop" method,
|
||||||
but we already have a condition set in the CLI, disallow this
|
but we already have a condition set in the CLI or other extension
|
||||||
operation. */
|
language, disallow this operation. */
|
||||||
if (strcmp (attr, stop_func) == 0 && obj->bp->cond_string)
|
if (strcmp (attr, stop_func) == 0)
|
||||||
{
|
{
|
||||||
xfree (attr);
|
const struct extension_language_defn *extlang = NULL;
|
||||||
PyErr_SetString (PyExc_RuntimeError,
|
|
||||||
_("Cannot set 'stop' method. There is an " \
|
if (obj->bp->cond_string != NULL)
|
||||||
"existing GDB condition attached to the " \
|
extlang = get_ext_lang_defn (EXT_LANG_GDB);
|
||||||
"breakpoint."));
|
if (extlang == NULL)
|
||||||
return -1;
|
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);
|
xfree (attr);
|
||||||
|
|
|
@ -48,17 +48,17 @@ enum mi_print_types
|
||||||
this will be set to NULL. LANGUAGE is also a pass-through argument
|
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
|
denoting the language attributed to the Symbol. In the case of SYM
|
||||||
being NULL, this will be set to the current language. Returns
|
being NULL, this will be set to the current language. Returns
|
||||||
PY_BT_ERROR on error with the appropriate Python exception set, and
|
EXT_LANG_BT_ERROR on error with the appropriate Python exception set, and
|
||||||
PY_BT_OK on success. */
|
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,
|
extract_sym (PyObject *obj, char **name, struct symbol **sym,
|
||||||
const struct language_defn **language)
|
const struct language_defn **language)
|
||||||
{
|
{
|
||||||
PyObject *result = PyObject_CallMethod (obj, "symbol", NULL);
|
PyObject *result = PyObject_CallMethod (obj, "symbol", NULL);
|
||||||
|
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
|
|
||||||
/* For 'symbol' callback, the function can return a symbol or a
|
/* For 'symbol' callback, the function can return a symbol or a
|
||||||
string. */
|
string. */
|
||||||
|
@ -68,7 +68,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
|
||||||
Py_DECREF (result);
|
Py_DECREF (result);
|
||||||
|
|
||||||
if (*name == NULL)
|
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
|
/* If the API returns a string (and not a symbol), then there is
|
||||||
no symbol derived language available and the frame filter has
|
no symbol derived language available and the frame filter has
|
||||||
either overridden the symbol with a string, or supplied a
|
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,
|
PyErr_SetString (PyExc_RuntimeError,
|
||||||
_("Unexpected value. Expecting a "
|
_("Unexpected value. Expecting a "
|
||||||
"gdb.Symbol or a Python string."));
|
"gdb.Symbol or a Python string."));
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicate the symbol name, so the caller has consistency
|
/* 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;
|
*language = current_language;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function to extract a value from an object that conforms to
|
/* 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
|
the value from. VALUE is a pass-through argument where the value
|
||||||
will be written. If the object does not have the value attribute,
|
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
|
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
|
and this function will return as successful. Returns EXT_LANG_BT_ERROR
|
||||||
on error with the appropriate Python exception set, and PY_BT_OK on
|
on error with the appropriate Python exception set, and EXT_LANG_BT_OK on
|
||||||
success. */
|
success. */
|
||||||
|
|
||||||
static enum py_bt_status
|
static enum ext_lang_bt_status
|
||||||
extract_value (PyObject *obj, struct value **value)
|
extract_value (PyObject *obj, struct value **value)
|
||||||
{
|
{
|
||||||
if (PyObject_HasAttrString (obj, "value"))
|
if (PyObject_HasAttrString (obj, "value"))
|
||||||
|
@ -126,7 +126,7 @@ extract_value (PyObject *obj, struct value **value)
|
||||||
PyObject *vresult = PyObject_CallMethod (obj, "value", NULL);
|
PyObject *vresult = PyObject_CallMethod (obj, "value", NULL);
|
||||||
|
|
||||||
if (vresult == 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
|
/* The Python code has returned 'None' for a value, so we set
|
||||||
value to NULL. This flags that GDB should read the
|
value to NULL. This flags that GDB should read the
|
||||||
|
@ -135,7 +135,7 @@ extract_value (PyObject *obj, struct value **value)
|
||||||
{
|
{
|
||||||
Py_DECREF (vresult);
|
Py_DECREF (vresult);
|
||||||
*value = NULL;
|
*value = NULL;
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -143,15 +143,15 @@ extract_value (PyObject *obj, struct value **value)
|
||||||
Py_DECREF (vresult);
|
Py_DECREF (vresult);
|
||||||
|
|
||||||
if (*value == NULL)
|
if (*value == NULL)
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
|
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*value = NULL;
|
*value = NULL;
|
||||||
|
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MI prints only certain values according to the type of symbol and
|
/* 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
|
/* 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
|
"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
|
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
|
type will be extracted from. Returns EXT_LANG_BT_ERROR on error, with
|
||||||
any GDB exceptions converted to a Python exception, or PY_BT_OK on
|
any GDB exceptions converted to a Python exception, or EXT_LANG_BT_OK on
|
||||||
success. */
|
success. */
|
||||||
|
|
||||||
static enum py_bt_status
|
static enum ext_lang_bt_status
|
||||||
py_print_type (struct ui_out *out, struct value *val)
|
py_print_type (struct ui_out *out, struct value *val)
|
||||||
{
|
{
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
|
@ -220,10 +220,10 @@ py_print_type (struct ui_out *out, struct value *val)
|
||||||
if (except.reason < 0)
|
if (except.reason < 0)
|
||||||
{
|
{
|
||||||
gdbpy_convert_exception (except);
|
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
|
/* 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
|
VAL is the value that will be printed, OPTS contains the value
|
||||||
printing options, ARGS_TYPE is an enumerator describing the
|
printing options, ARGS_TYPE is an enumerator describing the
|
||||||
argument format, and LANGUAGE is the language_defn that the value
|
argument format, and LANGUAGE is the language_defn that the value
|
||||||
will be printed with. Returns PY_BT_ERROR on error, with any GDB
|
will be printed with. Returns EXT_LANG_BT_ERROR on error, with any GDB
|
||||||
exceptions converted to a Python exception, or PY_BT_OK on
|
exceptions converted to a Python exception, or EXT_LANG_BT_OK on
|
||||||
success. */
|
success. */
|
||||||
|
|
||||||
static enum py_bt_status
|
static enum ext_lang_bt_status
|
||||||
py_print_value (struct ui_out *out, struct value *val,
|
py_print_value (struct ui_out *out, struct value *val,
|
||||||
const struct value_print_options *opts,
|
const struct value_print_options *opts,
|
||||||
int indent,
|
int indent,
|
||||||
enum py_frame_args args_type,
|
enum ext_lang_frame_args args_type,
|
||||||
const struct language_defn *language)
|
const struct language_defn *language)
|
||||||
{
|
{
|
||||||
int should_print = 0;
|
int should_print = 0;
|
||||||
|
@ -265,7 +265,7 @@ py_print_value (struct ui_out *out, struct value *val,
|
||||||
if (except.reason < 0)
|
if (except.reason < 0)
|
||||||
{
|
{
|
||||||
gdbpy_convert_exception (except);
|
gdbpy_convert_exception (except);
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args_type == MI_PRINT_ALL_VALUES)
|
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)
|
if (except.reason < 0)
|
||||||
{
|
{
|
||||||
gdbpy_convert_exception (except);
|
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
|
/* 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,
|
ARGS_TYPE is an enumerator describing the argument format,
|
||||||
PRINT_ARGS_FIELD is a flag which indicates if we output "ARGS=1"
|
PRINT_ARGS_FIELD is a flag which indicates if we output "ARGS=1"
|
||||||
in MI output in commands where both arguments and locals are
|
in MI output in commands where both arguments and locals are
|
||||||
printed. Returns PY_BT_ERROR on error, with any GDB exceptions
|
printed. Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions
|
||||||
converted to a Python exception, or PY_BT_OK on success. */
|
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,
|
py_print_single_arg (struct ui_out *out,
|
||||||
const char *sym_name,
|
const char *sym_name,
|
||||||
struct frame_arg *fa,
|
struct frame_arg *fa,
|
||||||
struct value *fv,
|
struct value *fv,
|
||||||
const struct value_print_options *opts,
|
const struct value_print_options *opts,
|
||||||
enum py_frame_args args_type,
|
enum ext_lang_frame_args args_type,
|
||||||
int print_args_field,
|
int print_args_field,
|
||||||
const struct language_defn *language)
|
const struct language_defn *language)
|
||||||
{
|
{
|
||||||
|
@ -435,7 +435,7 @@ py_print_single_arg (struct ui_out *out,
|
||||||
types. */
|
types. */
|
||||||
if (args_type == MI_PRINT_SIMPLE_VALUES)
|
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);
|
do_cleanups (cleanups);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -455,7 +455,7 @@ py_print_single_arg (struct ui_out *out,
|
||||||
if (args_type != NO_VALUES)
|
if (args_type != NO_VALUES)
|
||||||
{
|
{
|
||||||
if (py_print_value (out, val, opts, 0, args_type, language)
|
if (py_print_value (out, val, opts, 0, args_type, language)
|
||||||
== PY_BT_ERROR)
|
== EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
do_cleanups (cleanups);
|
do_cleanups (cleanups);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -471,10 +471,10 @@ py_print_single_arg (struct ui_out *out,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function to loop over frame arguments provided by the
|
/* 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
|
enumerator describing the argument format, PRINT_ARGS_FIELD is a
|
||||||
flag which indicates if we output "ARGS=1" in MI output in commands
|
flag which indicates if we output "ARGS=1" in MI output in commands
|
||||||
where both arguments and locals are printed, and FRAME is the
|
where both arguments and locals are printed, and FRAME is the
|
||||||
backing frame. Returns PY_BT_ERROR on error, with any GDB
|
backing frame. Returns EXT_LANG_BT_ERROR on error, with any GDB
|
||||||
exceptions converted to a Python exception, or PY_BT_OK on
|
exceptions converted to a Python exception, or EXT_LANG_BT_OK on
|
||||||
success. */
|
success. */
|
||||||
|
|
||||||
static enum py_bt_status
|
static enum ext_lang_bt_status
|
||||||
enumerate_args (PyObject *iter,
|
enumerate_args (PyObject *iter,
|
||||||
struct ui_out *out,
|
struct ui_out *out,
|
||||||
enum py_frame_args args_type,
|
enum ext_lang_frame_args args_type,
|
||||||
int print_args_field,
|
int print_args_field,
|
||||||
struct frame_info *frame)
|
struct frame_info *frame)
|
||||||
{
|
{
|
||||||
|
@ -533,17 +533,17 @@ enumerate_args (PyObject *iter,
|
||||||
char *sym_name;
|
char *sym_name;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct value *val;
|
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);
|
success = extract_sym (item, &sym_name, &sym, &language);
|
||||||
if (success == PY_BT_ERROR)
|
if (success == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
Py_DECREF (item);
|
Py_DECREF (item);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = extract_value (item, &val);
|
success = extract_value (item, &val);
|
||||||
if (success == PY_BT_ERROR)
|
if (success == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
xfree (sym_name);
|
xfree (sym_name);
|
||||||
Py_DECREF (item);
|
Py_DECREF (item);
|
||||||
|
@ -597,7 +597,7 @@ enumerate_args (PyObject *iter,
|
||||||
NULL, &opts,
|
NULL, &opts,
|
||||||
args_type,
|
args_type,
|
||||||
print_args_field,
|
print_args_field,
|
||||||
NULL) == PY_BT_ERROR)
|
NULL) == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
xfree (arg.error);
|
xfree (arg.error);
|
||||||
xfree (entryarg.error);
|
xfree (entryarg.error);
|
||||||
|
@ -625,9 +625,9 @@ enumerate_args (PyObject *iter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (py_print_single_arg (out, NULL, &entryarg, NULL,
|
if (py_print_single_arg (out, NULL, &entryarg, NULL, &opts,
|
||||||
&opts, args_type,
|
args_type, print_args_field, NULL)
|
||||||
print_args_field, NULL) == PY_BT_ERROR)
|
== EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
xfree (arg.error);
|
xfree (arg.error);
|
||||||
xfree (entryarg.error);
|
xfree (entryarg.error);
|
||||||
|
@ -646,7 +646,7 @@ enumerate_args (PyObject *iter,
|
||||||
{
|
{
|
||||||
if (py_print_single_arg (out, sym_name, NULL, val, &opts,
|
if (py_print_single_arg (out, sym_name, NULL, val, &opts,
|
||||||
args_type, print_args_field,
|
args_type, print_args_field,
|
||||||
language) == PY_BT_ERROR)
|
language) == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
xfree (sym_name);
|
xfree (sym_name);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -688,10 +688,10 @@ enumerate_args (PyObject *iter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
|
|
||||||
error:
|
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
|
the argument format, PRINT_ARGS_FIELD is flag which indicates
|
||||||
whether to output the ARGS field in the case of
|
whether to output the ARGS field in the case of
|
||||||
-stack-list-variables and FRAME is the backing frame. Returns
|
-stack-list-variables and FRAME is the backing frame. Returns
|
||||||
PY_BT_ERROR on error, with any GDB exceptions converted to a Python
|
EXT_LANG_BT_ERROR on error, with any GDB exceptions converted to a Python
|
||||||
exception, or PY_BT_OK on success. */
|
exception, or EXT_LANG_BT_OK on success. */
|
||||||
|
|
||||||
static enum py_bt_status
|
static enum ext_lang_bt_status
|
||||||
enumerate_locals (PyObject *iter,
|
enumerate_locals (PyObject *iter,
|
||||||
struct ui_out *out,
|
struct ui_out *out,
|
||||||
int indent,
|
int indent,
|
||||||
enum py_frame_args args_type,
|
enum ext_lang_frame_args args_type,
|
||||||
int print_args_field,
|
int print_args_field,
|
||||||
struct frame_info *frame)
|
struct frame_info *frame)
|
||||||
{
|
{
|
||||||
|
@ -725,7 +725,7 @@ enumerate_locals (PyObject *iter,
|
||||||
const struct language_defn *language;
|
const struct language_defn *language;
|
||||||
char *sym_name;
|
char *sym_name;
|
||||||
struct value *val;
|
struct value *val;
|
||||||
enum py_bt_status success = PY_BT_ERROR;
|
enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
int local_indent = 8 + (8 * indent);
|
int local_indent = 8 + (8 * indent);
|
||||||
|
@ -734,7 +734,7 @@ enumerate_locals (PyObject *iter,
|
||||||
locals_cleanups = make_cleanup_py_decref (item);
|
locals_cleanups = make_cleanup_py_decref (item);
|
||||||
|
|
||||||
success = extract_sym (item, &sym_name, &sym, &language);
|
success = extract_sym (item, &sym_name, &sym, &language);
|
||||||
if (success == PY_BT_ERROR)
|
if (success == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
do_cleanups (locals_cleanups);
|
do_cleanups (locals_cleanups);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -743,7 +743,7 @@ enumerate_locals (PyObject *iter,
|
||||||
make_cleanup (xfree, sym_name);
|
make_cleanup (xfree, sym_name);
|
||||||
|
|
||||||
success = extract_value (item, &val);
|
success = extract_value (item, &val);
|
||||||
if (success == PY_BT_ERROR)
|
if (success == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
do_cleanups (locals_cleanups);
|
do_cleanups (locals_cleanups);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -801,7 +801,7 @@ enumerate_locals (PyObject *iter,
|
||||||
|
|
||||||
if (args_type == MI_PRINT_SIMPLE_VALUES)
|
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);
|
do_cleanups (locals_cleanups);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -815,7 +815,7 @@ enumerate_locals (PyObject *iter,
|
||||||
int val_indent = (indent + 1) * 4;
|
int val_indent = (indent + 1) * 4;
|
||||||
|
|
||||||
if (py_print_value (out, val, &opts, val_indent, args_type,
|
if (py_print_value (out, val, &opts, val_indent, args_type,
|
||||||
language) == PY_BT_ERROR)
|
language) == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
do_cleanups (locals_cleanups);
|
do_cleanups (locals_cleanups);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -826,7 +826,7 @@ enumerate_locals (PyObject *iter,
|
||||||
if (args_type != NO_VALUES)
|
if (args_type != NO_VALUES)
|
||||||
{
|
{
|
||||||
if (py_print_value (out, val, &opts, 0, args_type,
|
if (py_print_value (out, val, &opts, 0, args_type,
|
||||||
language) == PY_BT_ERROR)
|
language) == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
do_cleanups (locals_cleanups);
|
do_cleanups (locals_cleanups);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -850,19 +850,19 @@ enumerate_locals (PyObject *iter,
|
||||||
if (item == NULL && PyErr_Occurred ())
|
if (item == NULL && PyErr_Occurred ())
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function for -stack-list-variables. Returns PY_BT_ERROR on
|
/* Helper function for -stack-list-variables. Returns EXT_LANG_BT_ERROR on
|
||||||
error, or PY_BT_OK on success. */
|
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,
|
py_mi_print_variables (PyObject *filter, struct ui_out *out,
|
||||||
struct value_print_options *opts,
|
struct value_print_options *opts,
|
||||||
enum py_frame_args args_type,
|
enum ext_lang_frame_args args_type,
|
||||||
struct frame_info *frame)
|
struct frame_info *frame)
|
||||||
{
|
{
|
||||||
struct cleanup *old_chain;
|
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");
|
make_cleanup_ui_out_list_begin_end (out, "variables");
|
||||||
|
|
||||||
if (args_iter != Py_None)
|
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;
|
goto error;
|
||||||
|
|
||||||
if (locals_iter != Py_None)
|
if (locals_iter != Py_None)
|
||||||
if (enumerate_locals (locals_iter, out, 1, args_type, 1, frame)
|
if (enumerate_locals (locals_iter, out, 1, args_type, 1, frame)
|
||||||
== PY_BT_ERROR)
|
== EXT_LANG_BT_ERROR)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function for printing locals. This function largely just
|
/* Helper function for printing locals. This function largely just
|
||||||
creates the wrapping tuple, and calls enumerate_locals. Returns
|
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,
|
py_print_locals (PyObject *filter,
|
||||||
struct ui_out *out,
|
struct ui_out *out,
|
||||||
enum py_frame_args args_type,
|
enum ext_lang_frame_args args_type,
|
||||||
int indent,
|
int indent,
|
||||||
struct frame_info *frame)
|
struct frame_info *frame)
|
||||||
{
|
{
|
||||||
|
@ -920,26 +921,26 @@ py_print_locals (PyObject *filter,
|
||||||
|
|
||||||
if (locals_iter != Py_None)
|
if (locals_iter != Py_None)
|
||||||
if (enumerate_locals (locals_iter, out, indent, args_type,
|
if (enumerate_locals (locals_iter, out, indent, args_type,
|
||||||
0, frame) == PY_BT_ERROR)
|
0, frame) == EXT_LANG_BT_ERROR)
|
||||||
goto locals_error;
|
goto locals_error;
|
||||||
|
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
return PY_BT_OK;;
|
return EXT_LANG_BT_OK;
|
||||||
|
|
||||||
locals_error:
|
locals_error:
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function for printing frame arguments. This function
|
/* Helper function for printing frame arguments. This function
|
||||||
largely just creates the wrapping tuple, and calls enumerate_args.
|
largely just creates the wrapping tuple, and calls enumerate_args.
|
||||||
Returns PY_BT_ERROR on error, with any GDB exceptions converted to
|
Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions converted to
|
||||||
a Python exception, or PY_BT_OK on success. */
|
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,
|
py_print_args (PyObject *filter,
|
||||||
struct ui_out *out,
|
struct ui_out *out,
|
||||||
enum py_frame_args args_type,
|
enum ext_lang_frame_args args_type,
|
||||||
struct frame_info *frame)
|
struct frame_info *frame)
|
||||||
{
|
{
|
||||||
PyObject *args_iter = get_py_iter_from_func (filter, "frame_args");
|
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 (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;
|
goto args_error;
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
@ -979,11 +981,11 @@ py_print_args (PyObject *filter,
|
||||||
}
|
}
|
||||||
|
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
return PY_BT_OK;
|
return EXT_LANG_BT_OK;
|
||||||
|
|
||||||
args_error:
|
args_error:
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print a single frame to the designated output stream, detecting
|
/* 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
|
(in the case of elided frames), and LEVELS_PRINTED is a hash-table
|
||||||
containing all the frames level that have already been printed.
|
containing all the frames level that have already been printed.
|
||||||
If a frame level has been printed, do not print it again (in the
|
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
|
case of elided frames). Returns EXT_LANG_BT_ERROR on error, with any
|
||||||
GDB exceptions converted to a Python exception, or PY_BT_COMPLETED
|
GDB exceptions converted to a Python exception, or EXT_LANG_BT_COMPLETED
|
||||||
on success. */
|
on success. */
|
||||||
|
|
||||||
static enum py_bt_status
|
static enum ext_lang_bt_status
|
||||||
py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
py_print_frame (PyObject *filter, int flags,
|
||||||
|
enum ext_lang_frame_args args_type,
|
||||||
struct ui_out *out, int indent, htab_t levels_printed)
|
struct ui_out *out, int indent, htab_t levels_printed)
|
||||||
{
|
{
|
||||||
int has_addr = 0;
|
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 (print_locals && print_args && ! print_frame_info)
|
||||||
{
|
{
|
||||||
if (py_mi_print_variables (filter, out, &opts,
|
if (py_mi_print_variables (filter, out, &opts,
|
||||||
args_type, frame) == PY_BT_ERROR)
|
args_type, frame) == EXT_LANG_BT_ERROR)
|
||||||
goto error;
|
goto error;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
do_cleanups (cleanup_stack);
|
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. */
|
wrong. */
|
||||||
if (print_args)
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1334,7 +1337,7 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
||||||
if (print_locals)
|
if (print_locals)
|
||||||
{
|
{
|
||||||
if (py_print_locals (filter, out, args_type, indent,
|
if (py_print_locals (filter, out, args_type, indent,
|
||||||
frame) == PY_BT_ERROR)
|
frame) == EXT_LANG_BT_ERROR)
|
||||||
goto 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)))
|
while ((item = PyIter_Next (elided)))
|
||||||
{
|
{
|
||||||
enum py_bt_status success = py_print_frame (item, flags,
|
enum ext_lang_bt_status success = py_print_frame (item, flags,
|
||||||
args_type, out,
|
args_type, out,
|
||||||
indent,
|
indent,
|
||||||
levels_printed);
|
levels_printed);
|
||||||
|
|
||||||
if (success == PY_BT_ERROR)
|
if (success == EXT_LANG_BT_ERROR)
|
||||||
{
|
{
|
||||||
Py_DECREF (item);
|
Py_DECREF (item);
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -1374,11 +1377,11 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
|
||||||
|
|
||||||
|
|
||||||
do_cleanups (cleanup_stack);
|
do_cleanups (cleanup_stack);
|
||||||
return PY_BT_COMPLETED;
|
return EXT_LANG_BT_COMPLETED;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
do_cleanups (cleanup_stack);
|
do_cleanups (cleanup_stack);
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function to initiate frame filter invocation at starting
|
/* 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
|
variables. ARGS_TYPE is an enumerator describing the argument
|
||||||
format, OUT is the output stream to print. FRAME_LOW is the
|
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
|
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,
|
upper limit of the frames to count. Returns EXT_LANG_BT_ERROR on error,
|
||||||
or PY_BT_COMPLETED on success.*/
|
or EXT_LANG_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)
|
|
||||||
|
|
||||||
|
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 gdbarch *gdbarch = NULL;
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups;
|
||||||
enum py_bt_status success = PY_BT_ERROR;
|
enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
|
||||||
PyObject *iterable;
|
PyObject *iterable;
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
htab_t levels_printed;
|
htab_t levels_printed;
|
||||||
|
|
||||||
if (!gdb_python_initialized)
|
if (!gdb_python_initialized)
|
||||||
return PY_BT_NO_FILTERS;
|
return EXT_LANG_BT_NO_FILTERS;
|
||||||
|
|
||||||
TRY_CATCH (except, RETURN_MASK_ALL)
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
|
@ -1484,7 +1486,7 @@ apply_frame_filter (struct frame_info *frame, int flags,
|
||||||
if (except.reason < 0)
|
if (except.reason < 0)
|
||||||
{
|
{
|
||||||
/* Let gdb try to print the stack trace. */
|
/* 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);
|
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
|
where GDB cannot initialize the frame filters (most likely
|
||||||
due to incorrect auto-load paths), GDB has printed nothing.
|
due to incorrect auto-load paths), GDB has printed nothing.
|
||||||
In this case it is OK to print the default backtrace after
|
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
|
here to signify there are no filters after printing the
|
||||||
initialization error. This return code will trigger a
|
initialization error. This return code will trigger a
|
||||||
default backtrace. */
|
default backtrace. */
|
||||||
|
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
do_cleanups (cleanups);
|
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.
|
/* 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);
|
make_cleanup_py_decref (iterable);
|
||||||
if (iterable == Py_None)
|
if (iterable == Py_None)
|
||||||
{
|
{
|
||||||
success = PY_BT_NO_FILTERS;
|
success = EXT_LANG_BT_NO_FILTERS;
|
||||||
goto done;
|
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
|
/* Do not exit on error printing a single frame. Print the
|
||||||
error and continue with other frames. */
|
error and continue with other frames. */
|
||||||
if (success == PY_BT_ERROR)
|
if (success == EXT_LANG_BT_ERROR)
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
|
|
||||||
Py_DECREF (item);
|
Py_DECREF (item);
|
||||||
|
@ -1552,5 +1554,5 @@ apply_frame_filter (struct frame_info *frame, int flags,
|
||||||
error:
|
error:
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
do_cleanups (cleanups);
|
do_cleanups (cleanups);
|
||||||
return PY_BT_ERROR;
|
return EXT_LANG_BT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,8 @@
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
#include "valprint.h"
|
#include "valprint.h"
|
||||||
|
#include "extension-priv.h"
|
||||||
#include "python.h"
|
#include "python.h"
|
||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
|
||||||
#include "python-internal.h"
|
#include "python-internal.h"
|
||||||
|
|
||||||
/* Return type of print_string_repr. */
|
/* Return type of print_string_repr. */
|
||||||
|
@ -300,7 +298,7 @@ print_stack_unless_memory_error (struct ui_file *stream)
|
||||||
gdbpy_print_stack ();
|
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. */
|
formats the result. */
|
||||||
|
|
||||||
static enum string_repr_result
|
static enum string_repr_result
|
||||||
|
@ -467,7 +465,7 @@ push_dummy_python_frame (void)
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
printer, if any exist. If is_py_none is true, then nothing has
|
||||||
been printed by to_string, and format output accordingly. */
|
been printed by to_string, and format output accordingly. */
|
||||||
static void
|
static void
|
||||||
|
@ -686,13 +684,14 @@ print_children (PyObject *printer, const char *hint,
|
||||||
do_cleanups (cleanups);
|
do_cleanups (cleanups);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
enum ext_lang_rc
|
||||||
apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
|
gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
|
||||||
int embedded_offset, CORE_ADDR address,
|
struct type *type, const gdb_byte *valaddr,
|
||||||
struct ui_file *stream, int recurse,
|
int embedded_offset, CORE_ADDR address,
|
||||||
const struct value *val,
|
struct ui_file *stream, int recurse,
|
||||||
const struct value_print_options *options,
|
const struct value *val,
|
||||||
const struct language_defn *language)
|
const struct value_print_options *options,
|
||||||
|
const struct language_defn *language)
|
||||||
{
|
{
|
||||||
struct gdbarch *gdbarch = get_type_arch (type);
|
struct gdbarch *gdbarch = get_type_arch (type);
|
||||||
PyObject *printer = NULL;
|
PyObject *printer = NULL;
|
||||||
|
@ -700,15 +699,15 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
|
||||||
struct value *value;
|
struct value *value;
|
||||||
char *hint = NULL;
|
char *hint = NULL;
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups;
|
||||||
int result = 0;
|
enum ext_lang_rc result = EXT_LANG_RC_NOP;
|
||||||
enum string_repr_result print_result;
|
enum string_repr_result print_result;
|
||||||
|
|
||||||
/* No pretty-printer support for unavailable values. */
|
/* No pretty-printer support for unavailable values. */
|
||||||
if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
|
if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
|
||||||
return 0;
|
return EXT_LANG_RC_NOP;
|
||||||
|
|
||||||
if (!gdb_python_initialized)
|
if (!gdb_python_initialized)
|
||||||
return 0;
|
return EXT_LANG_RC_NOP;
|
||||||
|
|
||||||
cleanups = ensure_python_env (gdbarch, language);
|
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);
|
val_obj = value_to_value_object (value);
|
||||||
if (! val_obj)
|
if (! val_obj)
|
||||||
goto done;
|
{
|
||||||
|
result = EXT_LANG_RC_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the constructor. */
|
/* Find the constructor. */
|
||||||
printer = find_pretty_printer (val_obj);
|
printer = find_pretty_printer (val_obj);
|
||||||
Py_DECREF (val_obj);
|
Py_DECREF (val_obj);
|
||||||
|
|
||||||
if (printer == NULL)
|
if (printer == NULL)
|
||||||
goto done;
|
{
|
||||||
|
result = EXT_LANG_RC_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
make_cleanup_py_decref (printer);
|
make_cleanup_py_decref (printer);
|
||||||
if (printer == Py_None)
|
if (printer == Py_None)
|
||||||
goto done;
|
{
|
||||||
|
result = EXT_LANG_RC_NOP;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we are printing a map, we want some special formatting. */
|
/* If we are printing a map, we want some special formatting. */
|
||||||
hint = gdbpy_get_display_hint (printer);
|
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_children (printer, hint, stream, recurse, options, language,
|
||||||
print_result == string_repr_none);
|
print_result == string_repr_none);
|
||||||
|
|
||||||
result = 1;
|
result = EXT_LANG_RC_OK;
|
||||||
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (PyErr_Occurred ())
|
if (PyErr_Occurred ())
|
||||||
|
@ -838,18 +845,3 @@ gdbpy_default_visualizer (PyObject *self, PyObject *args)
|
||||||
cons = find_pretty_printer (val_obj);
|
cons = find_pretty_printer (val_obj);
|
||||||
return cons;
|
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 "cp-abi.h"
|
||||||
#include "python.h"
|
#include "python.h"
|
||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
|
||||||
|
|
||||||
#include "python-internal.h"
|
#include "python-internal.h"
|
||||||
|
|
||||||
/* Even though Python scalar types directly map to host types, we use
|
/* 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
|
/* Iterate over all the Value objects, calling preserve_one_value on
|
||||||
each. */
|
each. */
|
||||||
void
|
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;
|
value_object *iter;
|
||||||
|
|
||||||
|
@ -1702,13 +1701,3 @@ PyTypeObject value_object_type = {
|
||||||
0, /* tp_alloc */
|
0, /* tp_alloc */
|
||||||
valpy_new /* tp_new */
|
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
|
#ifndef GDB_PYTHON_INTERNAL_H
|
||||||
#define GDB_PYTHON_INTERNAL_H
|
#define GDB_PYTHON_INTERNAL_H
|
||||||
|
|
||||||
|
#include "extension.h"
|
||||||
|
|
||||||
/* These WITH_* macros are defined by the CPython API checker that
|
/* These WITH_* macros are defined by the CPython API checker that
|
||||||
comes with the Python plugin for GCC. See:
|
comes with the Python plugin for GCC. See:
|
||||||
https://gcc-python-plugin.readthedocs.org/en/latest/cpychecker.html
|
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 *set_python_list;
|
||||||
extern struct cmd_list_element *show_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_history (PyObject *self, PyObject *args);
|
||||||
PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
|
PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
|
||||||
PyObject *gdbpy_frame_stop_reason_string (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 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);
|
PyObject *python_string_to_unicode (PyObject *obj);
|
||||||
char *unicode_to_target_string (PyObject *unicode_str);
|
char *unicode_to_target_string (PyObject *unicode_str);
|
||||||
char *python_string_to_target_string (PyObject *obj);
|
char *python_string_to_target_string (PyObject *obj);
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "readline/tilde.h"
|
#include "readline/tilde.h"
|
||||||
#include "python.h"
|
#include "python.h"
|
||||||
|
#include "extension-priv.h"
|
||||||
#include "cli/cli-utils.h"
|
#include "cli/cli-utils.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
/* Declared constants and enum for python stack printing. */
|
/* Declared constants and enum for python stack printing. */
|
||||||
|
@ -56,6 +56,34 @@ static const char *const python_excp_enums[] =
|
||||||
the default. */
|
the default. */
|
||||||
static const char *gdbpy_should_print_stack = python_excp_message;
|
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
|
#ifdef HAVE_PYTHON
|
||||||
|
|
||||||
#include "libiberty.h"
|
#include "libiberty.h"
|
||||||
|
@ -69,7 +97,6 @@ static const char *gdbpy_should_print_stack = python_excp_message;
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "gdbthread.h"
|
#include "gdbthread.h"
|
||||||
#include "observer.h"
|
|
||||||
#include "interps.h"
|
#include "interps.h"
|
||||||
#include "event-top.h"
|
#include "event-top.h"
|
||||||
|
|
||||||
|
@ -104,6 +131,64 @@ PyObject *gdbpy_gdb_error;
|
||||||
/* The `gdb.MemoryError' exception. */
|
/* The `gdb.MemoryError' exception. */
|
||||||
PyObject *gdbpy_gdb_memory_error;
|
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
|
/* Architecture and language to be used in callbacks from
|
||||||
the Python interpreter. */
|
the Python interpreter. */
|
||||||
struct gdbarch *python_gdbarch;
|
struct gdbarch *python_gdbarch;
|
||||||
|
@ -114,6 +199,7 @@ const struct language_defn *python_language;
|
||||||
|
|
||||||
struct python_env
|
struct python_env
|
||||||
{
|
{
|
||||||
|
struct active_ext_lang_state *previous_active;
|
||||||
PyGILState_STATE state;
|
PyGILState_STATE state;
|
||||||
struct gdbarch *gdbarch;
|
struct gdbarch *gdbarch;
|
||||||
const struct language_defn *language;
|
const struct language_defn *language;
|
||||||
|
@ -138,11 +224,17 @@ restore_python_env (void *p)
|
||||||
PyGILState_Release (env->state);
|
PyGILState_Release (env->state);
|
||||||
python_gdbarch = env->gdbarch;
|
python_gdbarch = env->gdbarch;
|
||||||
python_language = env->language;
|
python_language = env->language;
|
||||||
|
|
||||||
|
restore_active_ext_lang (env->previous_active);
|
||||||
|
|
||||||
xfree (env);
|
xfree (env);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called before entering the Python interpreter to install the
|
/* 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 *
|
struct cleanup *
|
||||||
ensure_python_env (struct gdbarch *gdbarch,
|
ensure_python_env (struct gdbarch *gdbarch,
|
||||||
|
@ -154,6 +246,8 @@ ensure_python_env (struct gdbarch *gdbarch,
|
||||||
if (!gdb_python_initialized)
|
if (!gdb_python_initialized)
|
||||||
error (_("Python not initialized"));
|
error (_("Python not initialized"));
|
||||||
|
|
||||||
|
env->previous_active = set_active_ext_lang (&extension_language_python);
|
||||||
|
|
||||||
env->state = PyGILState_Ensure ();
|
env->state = PyGILState_Ensure ();
|
||||||
env->gdbarch = python_gdbarch;
|
env->gdbarch = python_gdbarch;
|
||||||
env->language = python_language;
|
env->language = python_language;
|
||||||
|
@ -169,8 +263,8 @@ ensure_python_env (struct gdbarch *gdbarch,
|
||||||
|
|
||||||
/* Clear the quit flag. */
|
/* Clear the quit flag. */
|
||||||
|
|
||||||
void
|
static void
|
||||||
clear_quit_flag (void)
|
gdbpy_clear_quit_flag (const struct extension_language_defn *extlang)
|
||||||
{
|
{
|
||||||
/* This clears the flag as a side effect. */
|
/* This clears the flag as a side effect. */
|
||||||
PyOS_InterruptOccurred ();
|
PyOS_InterruptOccurred ();
|
||||||
|
@ -178,16 +272,16 @@ clear_quit_flag (void)
|
||||||
|
|
||||||
/* Set the quit flag. */
|
/* Set the quit flag. */
|
||||||
|
|
||||||
void
|
static void
|
||||||
set_quit_flag (void)
|
gdbpy_set_quit_flag (const struct extension_language_defn *extlang)
|
||||||
{
|
{
|
||||||
PyErr_SetInterrupt ();
|
PyErr_SetInterrupt ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if the quit flag has been set, false otherwise. */
|
/* Return true if the quit flag has been set, false otherwise. */
|
||||||
|
|
||||||
int
|
static int
|
||||||
check_quit_flag (void)
|
gdbpy_check_quit_flag (const struct extension_language_defn *extlang)
|
||||||
{
|
{
|
||||||
return PyOS_InterruptOccurred ();
|
return PyOS_InterruptOccurred ();
|
||||||
}
|
}
|
||||||
|
@ -343,8 +437,9 @@ compute_python_string (struct command_line *l)
|
||||||
/* Take a command line structure representing a 'python' command, and
|
/* Take a command line structure representing a 'python' command, and
|
||||||
evaluate its body using the Python interpreter. */
|
evaluate its body using the Python interpreter. */
|
||||||
|
|
||||||
void
|
static void
|
||||||
eval_python_from_control_command (struct command_line *cmd)
|
gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
|
||||||
|
struct command_line *cmd)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *script;
|
char *script;
|
||||||
|
@ -765,12 +860,14 @@ gdbpy_find_pc_line (PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a file as Python code.
|
/* 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
|
This does not throw any errors. If an exception occurs python will print
|
||||||
the traceback and clear the error indicator. */
|
the traceback and clear the error indicator. */
|
||||||
|
|
||||||
void
|
static void
|
||||||
source_python_script (FILE *file, const char *filename)
|
gdbpy_source_script (const struct extension_language_defn *extlang,
|
||||||
|
FILE *file, const char *filename)
|
||||||
{
|
{
|
||||||
struct cleanup *cleanup;
|
struct cleanup *cleanup;
|
||||||
|
|
||||||
|
@ -899,14 +996,17 @@ gdbpy_initialize_events (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
/* This is the extension_language_ops.before_prompt "method". */
|
||||||
before_prompt_hook (const char *current_gdb_prompt)
|
|
||||||
|
static enum ext_lang_rc
|
||||||
|
gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
|
||||||
|
const char *current_gdb_prompt)
|
||||||
{
|
{
|
||||||
struct cleanup *cleanup;
|
struct cleanup *cleanup;
|
||||||
char *prompt = NULL;
|
char *prompt = NULL;
|
||||||
|
|
||||||
if (!gdb_python_initialized)
|
if (!gdb_python_initialized)
|
||||||
return;
|
return EXT_LANG_RC_NOP;
|
||||||
|
|
||||||
cleanup = ensure_python_env (get_current_arch (), current_language);
|
cleanup = ensure_python_env (get_current_arch (), current_language);
|
||||||
|
|
||||||
|
@ -968,12 +1068,12 @@ before_prompt_hook (const char *current_gdb_prompt)
|
||||||
set_prompt (prompt);
|
set_prompt (prompt);
|
||||||
|
|
||||||
do_cleanups (cleanup);
|
do_cleanups (cleanup);
|
||||||
return;
|
return prompt != NULL ? EXT_LANG_RC_OK : EXT_LANG_RC_NOP;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
do_cleanups (cleanup);
|
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
|
/* 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
|
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;
|
static struct objfile *gdbpy_current_objfile;
|
||||||
|
|
||||||
/* Set the current objfile to OBJFILE and then read FILE named FILENAME
|
/* Set the current objfile to OBJFILE and then read FILE named FILENAME
|
||||||
as Python code. This does not throw any errors. If an exception
|
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
|
static void
|
||||||
source_python_script_for_objfile (struct objfile *objfile, FILE *file,
|
gdbpy_source_objfile_script (const struct extension_language_defn *extlang,
|
||||||
const char *filename)
|
struct objfile *objfile, FILE *file,
|
||||||
|
const char *filename)
|
||||||
{
|
{
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups;
|
||||||
|
|
||||||
|
@ -1225,18 +1328,20 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the list of active type printers and return it. The result
|
/* Compute the list of active python type printers and store them in
|
||||||
of this function can be passed to apply_type_printers, and should
|
EXT_PRINTERS->py_type_printers. The product of this function is used by
|
||||||
be freed by free_type_printers. */
|
gdbpy_apply_type_printers, and freed by gdbpy_free_type_printers.
|
||||||
|
This is the extension_language_ops.start_type_printers "method". */
|
||||||
|
|
||||||
void *
|
static void
|
||||||
start_type_printers (void)
|
gdbpy_start_type_printers (const struct extension_language_defn *extlang,
|
||||||
|
struct ext_lang_type_printers *ext_printers)
|
||||||
{
|
{
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups;
|
||||||
PyObject *type_module, *func = NULL, *result_obj = NULL;
|
PyObject *type_module, *func = NULL, *printers_obj = NULL;
|
||||||
|
|
||||||
if (!gdb_python_initialized)
|
if (!gdb_python_initialized)
|
||||||
return NULL;
|
return;
|
||||||
|
|
||||||
cleanups = ensure_python_env (get_current_arch (), current_language);
|
cleanups = ensure_python_env (get_current_arch (), current_language);
|
||||||
|
|
||||||
|
@ -1254,39 +1359,41 @@ start_type_printers (void)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_obj = PyObject_CallFunctionObjArgs (func, (char *) NULL);
|
printers_obj = PyObject_CallFunctionObjArgs (func, (char *) NULL);
|
||||||
if (result_obj == NULL)
|
if (printers_obj == NULL)
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
|
else
|
||||||
|
ext_printers->py_type_printers = printers_obj;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
Py_XDECREF (type_module);
|
Py_XDECREF (type_module);
|
||||||
Py_XDECREF (func);
|
Py_XDECREF (func);
|
||||||
do_cleanups (cleanups);
|
do_cleanups (cleanups);
|
||||||
return result_obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If TYPE is recognized by some type printer, return a newly
|
/* If TYPE is recognized by some type printer, store in *PRETTIED_TYPE
|
||||||
allocated string holding the type's replacement name. The caller
|
a newly allocated string holding the type's replacement name, and return
|
||||||
is responsible for freeing the string. Otherwise, return NULL.
|
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
|
static enum ext_lang_rc
|
||||||
recognizers, but this seemed clearer given the start_type_printers
|
gdbpy_apply_type_printers (const struct extension_language_defn *extlang,
|
||||||
and free_type_printers functions. */
|
const struct ext_lang_type_printers *ext_printers,
|
||||||
|
struct type *type, char **prettied_type)
|
||||||
char *
|
|
||||||
apply_type_printers (void *printers, struct type *type)
|
|
||||||
{
|
{
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups;
|
||||||
PyObject *type_obj, *type_module = NULL, *func = NULL;
|
PyObject *type_obj, *type_module = NULL, *func = NULL;
|
||||||
PyObject *result_obj = NULL;
|
PyObject *result_obj = NULL;
|
||||||
PyObject *printers_obj = printers;
|
PyObject *printers_obj = ext_printers->py_type_printers;
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
|
|
||||||
if (printers_obj == NULL)
|
if (printers_obj == NULL)
|
||||||
return NULL;
|
return EXT_LANG_RC_NOP;
|
||||||
|
|
||||||
if (!gdb_python_initialized)
|
if (!gdb_python_initialized)
|
||||||
return NULL;
|
return EXT_LANG_RC_NOP;
|
||||||
|
|
||||||
cleanups = ensure_python_env (get_current_arch (), current_language);
|
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 (func);
|
||||||
Py_XDECREF (result_obj);
|
Py_XDECREF (result_obj);
|
||||||
do_cleanups (cleanups);
|
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
|
static void
|
||||||
free_type_printers (void *arg)
|
gdbpy_free_type_printers (const struct extension_language_defn *extlang,
|
||||||
|
struct ext_lang_type_printers *ext_printers)
|
||||||
{
|
{
|
||||||
struct cleanup *cleanups;
|
struct cleanup *cleanups;
|
||||||
PyObject *printers = arg;
|
PyObject *printers = ext_printers->py_type_printers;
|
||||||
|
|
||||||
if (printers == NULL)
|
if (printers == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -1381,62 +1492,6 @@ python_command (char *arg, int from_tty)
|
||||||
python_interactive_command (arg, 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 */
|
#endif /* HAVE_PYTHON */
|
||||||
|
|
||||||
|
|
||||||
|
@ -1473,16 +1528,25 @@ user_show_python (char *args, int from_tty)
|
||||||
static void
|
static void
|
||||||
finalize_python (void *ignore)
|
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
|
/* We don't use ensure_python_env here because if we ever ran the
|
||||||
cleanup, gdb would crash -- because the cleanup calls into the
|
cleanup, gdb would crash -- because the cleanup calls into the
|
||||||
Python interpreter, which we are about to destroy. It seems
|
Python interpreter, which we are about to destroy. It seems
|
||||||
clearer to make the needed calls explicitly here than to create a
|
clearer to make the needed calls explicitly here than to create a
|
||||||
cleanup and then mysteriously discard it. */
|
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 ();
|
(void) PyGILState_Ensure ();
|
||||||
python_gdbarch = target_gdbarch ();
|
python_gdbarch = target_gdbarch ();
|
||||||
python_language = current_language;
|
python_language = current_language;
|
||||||
|
|
||||||
Py_Finalize ();
|
Py_Finalize ();
|
||||||
|
|
||||||
|
restore_active_ext_lang (previous_active);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1691,8 +1755,6 @@ message == an error message without a stack will be printed."),
|
||||||
|| gdbpy_initialize_arch () < 0)
|
|| gdbpy_initialize_arch () < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
observer_attach_before_prompt (before_prompt_hook);
|
|
||||||
|
|
||||||
gdbpy_to_string_cst = PyString_FromString ("to_string");
|
gdbpy_to_string_cst = PyString_FromString ("to_string");
|
||||||
if (gdbpy_to_string_cst == NULL)
|
if (gdbpy_to_string_cst == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1734,10 +1796,11 @@ message == an error message without a stack will be printed."),
|
||||||
/* Perform the remaining python initializations.
|
/* Perform the remaining python initializations.
|
||||||
These must be done after GDB is at least mostly initialized.
|
These must be done after GDB is at least mostly initialized.
|
||||||
E.g., The "info pretty-printer" command needs the "info" prefix
|
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
|
static void
|
||||||
finish_python_initialization (void)
|
gdbpy_finish_initialization (const struct extension_language_defn *extlang)
|
||||||
{
|
{
|
||||||
PyObject *m;
|
PyObject *m;
|
||||||
char *gdb_pythondir;
|
char *gdb_pythondir;
|
||||||
|
@ -1816,6 +1879,15 @@ finish_python_initialization (void)
|
||||||
do_cleanups (cleanup);
|
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 */
|
#endif /* HAVE_PYTHON */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,118 +20,9 @@
|
||||||
#ifndef GDB_PYTHON_H
|
#ifndef GDB_PYTHON_H
|
||||||
#define GDB_PYTHON_H
|
#define GDB_PYTHON_H
|
||||||
|
|
||||||
#include "value.h"
|
#include "extension.h"
|
||||||
#include "mi/mi-cmds.h"
|
|
||||||
|
|
||||||
struct gdbpy_breakpoint_object;
|
/* This is all that python exports to gdb. */
|
||||||
|
extern const struct extension_language_defn extension_language_python;
|
||||||
/* 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);
|
|
||||||
|
|
||||||
#endif /* GDB_PYTHON_H */
|
#endif /* GDB_PYTHON_H */
|
||||||
|
|
15
gdb/stack.c
15
gdb/stack.c
|
@ -53,7 +53,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
|
|
||||||
void (*deprecated_selected_frame_level_changed_hook) (int);
|
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;
|
int i;
|
||||||
struct frame_info *trailing;
|
struct frame_info *trailing;
|
||||||
int trailing_level, py_start = 0, py_end = 0;
|
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)
|
if (!target_has_stack)
|
||||||
error (_("No stack."));
|
error (_("No stack."));
|
||||||
|
@ -1782,7 +1782,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int no_filters,
|
||||||
if (! no_filters)
|
if (! no_filters)
|
||||||
{
|
{
|
||||||
int flags = PRINT_LEVEL | PRINT_FRAME_INFO | PRINT_ARGS;
|
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)
|
if (show_locals)
|
||||||
flags |= PRINT_LOCALS;
|
flags |= PRINT_LOCALS;
|
||||||
|
@ -1794,13 +1794,14 @@ backtrace_command_1 (char *count_exp, int show_locals, int no_filters,
|
||||||
else
|
else
|
||||||
arg_type = NO_VALUES;
|
arg_type = NO_VALUES;
|
||||||
|
|
||||||
result = apply_frame_filter (get_current_frame (), flags, arg_type,
|
result = apply_ext_lang_frame_filter (get_current_frame (), flags,
|
||||||
current_uiout, py_start, py_end);
|
arg_type, current_uiout,
|
||||||
|
py_start, py_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the inbuilt backtrace if there are no filters registered, or
|
/* Run the inbuilt backtrace if there are no filters registered, or
|
||||||
"no-filters" has been specified from the command. */
|
"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))
|
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>
|
2014-02-05 Yao Qi <yao@codesourcery.com>
|
||||||
|
|
||||||
* gdb.trace/report.exp (use_collected_data): Test the output
|
* gdb.trace/report.exp (use_collected_data): Test the output
|
||||||
|
|
35
gdb/testsuite/gdb.gdb/python-interrupts.exp
Normal file
35
gdb/testsuite/gdb.gdb/python-interrupts.exp
Normal file
|
@ -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 breakpoint" 0
|
||||||
set test_cond {cond $bpnum}
|
set test_cond {cond $bpnum}
|
||||||
gdb_test "$test_cond \"foo==3\"" \
|
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"
|
"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\")" \
|
gdb_py_test_silent_cmd "python eval_bp2 = basic(\"$cond_bp\")" \
|
||||||
"Set breakpoint" 0
|
"Set breakpoint" 0
|
||||||
|
@ -385,7 +385,7 @@ proc test_bkpt_eval_funcs { } {
|
||||||
"end" ""
|
"end" ""
|
||||||
|
|
||||||
gdb_test "python eval_bp2.stop = stop_func" \
|
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"
|
"Assign stop function to a breakpoint that has a condition"
|
||||||
|
|
||||||
delete_breakpoints
|
delete_breakpoints
|
||||||
|
|
10
gdb/top.c
10
gdb/top.c
|
@ -45,7 +45,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "event-loop.h"
|
#include "event-loop.h"
|
||||||
#include "gdbthread.h"
|
#include "gdbthread.h"
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
#include "interps.h"
|
#include "interps.h"
|
||||||
#include "observer.h"
|
#include "observer.h"
|
||||||
#include "maint.h"
|
#include "maint.h"
|
||||||
|
@ -1850,11 +1850,9 @@ gdb_init (char *argv0)
|
||||||
if (deprecated_init_ui_hook)
|
if (deprecated_init_ui_hook)
|
||||||
deprecated_init_ui_hook (argv0);
|
deprecated_init_ui_hook (argv0);
|
||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
/* Python initialization, for example, can require various commands to be
|
||||||
/* Python initialization can require various commands to be
|
|
||||||
installed. For example "info pretty-printer" needs the "info"
|
installed. For example "info pretty-printer" needs the "info"
|
||||||
prefix to be installed. Keep things simple and just do final
|
prefix to be installed. Keep things simple and just do final
|
||||||
python initialization here. */
|
script initialization here. */
|
||||||
finish_python_initialization ();
|
finish_ext_lang_initialization ();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "cli/cli-utils.h"
|
#include "cli/cli-utils.h"
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
#include "completer.h"
|
#include "completer.h"
|
||||||
|
|
||||||
extern void _initialize_typeprint (void);
|
extern void _initialize_typeprint (void);
|
||||||
|
@ -248,7 +248,7 @@ do_free_global_table (void *arg)
|
||||||
struct type_print_options *flags = arg;
|
struct type_print_options *flags = arg;
|
||||||
|
|
||||||
free_typedef_hash (flags->global_typedefs);
|
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. */
|
/* 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);
|
gdb_assert (flags->global_typedefs == NULL && flags->global_printers == NULL);
|
||||||
flags->global_typedefs = create_typedef_hash ();
|
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);
|
return make_cleanup (do_free_global_table, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look up the type T in the global typedef hash. If it is found,
|
/* 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
|
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. */
|
result. A NULL return means that the name was not found. */
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
@ -288,7 +288,7 @@ find_global_typedef (const struct type_print_options *flags,
|
||||||
return new_tf->name;
|
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. */
|
recurses. */
|
||||||
new_tf = XOBNEW (&flags->global_typedefs->storage, struct typedef_field);
|
new_tf = XOBNEW (&flags->global_typedefs->storage, struct typedef_field);
|
||||||
new_tf->name = NULL;
|
new_tf->name = NULL;
|
||||||
|
@ -296,7 +296,7 @@ find_global_typedef (const struct type_print_options *flags,
|
||||||
|
|
||||||
*slot = new_tf;
|
*slot = new_tf;
|
||||||
|
|
||||||
applied = apply_type_printers (flags->global_printers, t);
|
applied = apply_ext_lang_type_printers (flags->global_printers, t);
|
||||||
|
|
||||||
if (applied != NULL)
|
if (applied != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
enum language;
|
enum language;
|
||||||
struct ui_file;
|
struct ui_file;
|
||||||
struct typedef_hash_table;
|
struct typedef_hash_table;
|
||||||
|
struct ext_lang_type_printers;
|
||||||
|
|
||||||
struct type_print_options
|
struct type_print_options
|
||||||
{
|
{
|
||||||
|
@ -44,7 +45,7 @@ struct type_print_options
|
||||||
|
|
||||||
/* The list of type printers associated with the global typedef
|
/* The list of type printers associated with the global typedef
|
||||||
table. This is intentionally opaque. */
|
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;
|
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;
|
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
|
/* Nonzero means quit immediately if Control-C is typed now, rather
|
||||||
than waiting until QUIT is executed. Be careful in setting this;
|
than waiting until QUIT is executed. Be careful in setting this;
|
||||||
code which executes with immediate_quit set has to be very careful
|
code which executes with immediate_quit set has to be very careful
|
||||||
|
@ -131,41 +125,6 @@ int quit_flag;
|
||||||
|
|
||||||
int immediate_quit;
|
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
|
/* 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
|
as octal escapes. Zero means just print the value (e.g. it's an
|
||||||
international character, and the terminal or window can cope.) */
|
international character, and the terminal or window can cope.) */
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "doublest.h"
|
#include "doublest.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "dfp.h"
|
#include "dfp.h"
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
#include "ada-lang.h"
|
#include "ada-lang.h"
|
||||||
#include "gdb_obstack.h"
|
#include "gdb_obstack.h"
|
||||||
#include "charset.h"
|
#include "charset.h"
|
||||||
|
@ -770,9 +770,9 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||||
|
|
||||||
if (!options->raw)
|
if (!options->raw)
|
||||||
{
|
{
|
||||||
ret = apply_val_pretty_printer (type, valaddr, embedded_offset,
|
ret = apply_ext_lang_val_pretty_printer (type, valaddr, embedded_offset,
|
||||||
address, stream, recurse,
|
address, stream, recurse,
|
||||||
val, options, language);
|
val, options, language);
|
||||||
if (ret)
|
if (ret)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -876,12 +876,13 @@ value_print (struct value *val, struct ui_file *stream,
|
||||||
|
|
||||||
if (!options->raw)
|
if (!options->raw)
|
||||||
{
|
{
|
||||||
int r = apply_val_pretty_printer (value_type (val),
|
int r
|
||||||
value_contents_for_printing (val),
|
= apply_ext_lang_val_pretty_printer (value_type (val),
|
||||||
value_embedded_offset (val),
|
value_contents_for_printing (val),
|
||||||
value_address (val),
|
value_embedded_offset (val),
|
||||||
stream, 0,
|
value_address (val),
|
||||||
val, options, current_language);
|
stream, 0,
|
||||||
|
val, options, current_language);
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "valprint.h"
|
#include "valprint.h"
|
||||||
#include "cli/cli-decode.h"
|
#include "cli/cli-decode.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "python/python.h"
|
#include "extension.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "tracepoint.h"
|
#include "tracepoint.h"
|
||||||
#include "cp-abi.h"
|
#include "cp-abi.h"
|
||||||
|
@ -2405,7 +2405,7 @@ preserve_values (struct objfile *objfile)
|
||||||
for (var = internalvars; var; var = var->next)
|
for (var = internalvars; var; var = var->next)
|
||||||
preserve_one_internalvar (var, objfile, copied_types);
|
preserve_one_internalvar (var, objfile, copied_types);
|
||||||
|
|
||||||
preserve_python_values (objfile, copied_types);
|
preserve_ext_lang_values (objfile, copied_types);
|
||||||
|
|
||||||
htab_delete (copied_types);
|
htab_delete (copied_types);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue