diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h index b709494927d..cb00cb6ff7b 100644 --- a/gdb/extension-priv.h +++ b/gdb/extension-priv.h @@ -119,6 +119,10 @@ struct extension_language_ops This method is required. */ int (*initialized) (const struct extension_language_defn *); + /* Called just before GDB exits. This shuts down the extension + language. This can be NULL. */ + void (*shutdown) (const struct extension_language_defn *); + /* Process a sequence of commands embedded in GDB's own scripting language. E.g., python diff --git a/gdb/extension.c b/gdb/extension.c index 42e05199d2c..9f403500497 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -341,6 +341,18 @@ ext_lang_initialization (void) } } +/* See extension.h. */ + +void +ext_lang_shutdown () +{ + for (const struct extension_language_defn *extlang : extension_languages) + { + if (extlang->ops != nullptr && extlang->ops->shutdown != nullptr) + extlang->ops->shutdown (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. diff --git a/gdb/extension.h b/gdb/extension.h index 0514d7930a2..5260bcbde00 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -282,6 +282,9 @@ extern bool ext_lang_auto_load_enabled (const struct extension_language_defn *); extern void ext_lang_initialization (void); +/* Shut down all extension languages. */ +extern void ext_lang_shutdown (); + extern void eval_ext_lang_from_control_command (struct command_line *cmd); extern void auto_load_ext_lang_scripts_for_objfile (struct objfile *); diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c index 30d1c72fceb..f0db709e4fe 100644 --- a/gdb/guile/guile.c +++ b/gdb/guile/guile.c @@ -115,6 +115,7 @@ static const struct extension_language_ops guile_extension_ops = { gdbscm_initialize, gdbscm_initialized, + nullptr, gdbscm_eval_from_control_command, diff --git a/gdb/python/python.c b/gdb/python/python.c index 8f8ee7c0680..57f6bd571d5 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -110,6 +110,7 @@ static objfile_script_sourcer_func gdbpy_source_objfile_script; static objfile_script_executor_func gdbpy_execute_objfile_script; static void gdbpy_initialize (const struct extension_language_defn *); static int gdbpy_initialized (const struct extension_language_defn *); +static void finalize_python (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 *, @@ -147,6 +148,7 @@ static const struct extension_language_ops python_extension_ops = { gdbpy_initialize, gdbpy_initialized, + finalize_python, gdbpy_eval_from_control_command, @@ -2057,7 +2059,7 @@ static struct cmd_list_element *user_show_python_list; interpreter. This lets Python's 'atexit' work. */ static void -finalize_python () +finalize_python (const struct extension_language_defn *ignore) { struct active_ext_lang_state *previous_active; @@ -2297,8 +2299,6 @@ init_done: /* Release the GIL while gdb runs. */ PyEval_SaveThread (); - add_final_cleanup (finalize_python); - /* Only set this when initialization has succeeded. */ gdb_python_initialized = 1; return true; diff --git a/gdb/top.c b/gdb/top.c index 5114713baa4..67d6670cd9c 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1819,6 +1819,8 @@ quit_force (int *exit_arg, int from_tty) exception_print (gdb_stderr, ex); } + ext_lang_shutdown (); + exit (exit_code); }