diff options
author | Doug Evans <dje@google.com> | 2015-12-10 12:00:33 -0800 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2015-12-10 12:00:33 -0800 |
commit | 6dc3050775f42a9e9877d967aa81cf9af161da85 (patch) | |
tree | 6715acdd02e26a4431ff5bb1432dc290db8fde35 | |
parent | 5ca623bde7d8fd87f93aa869295ed033f083c5a8 (diff) | |
download | binutils-gdb-6dc3050775f42a9e9877d967aa81cf9af161da85.tar.gz |
patch ../102438532.patch
-rw-r--r-- | README.google | 25 | ||||
-rw-r--r-- | gdb/doc/python.texi | 43 | ||||
-rw-r--r-- | gdb/extension-priv.h | 4 | ||||
-rw-r--r-- | gdb/extension.c | 16 | ||||
-rw-r--r-- | gdb/extension.h | 2 | ||||
-rw-r--r-- | gdb/guile/guile.c | 1 | ||||
-rw-r--r-- | gdb/main.c | 7 | ||||
-rw-r--r-- | gdb/python/lib/gdb/__init__.py | 3 | ||||
-rw-r--r-- | gdb/python/python.c | 51 |
9 files changed, 152 insertions, 0 deletions
diff --git a/README.google b/README.google index a1ab047ad3a..6bd979ae4e6 100644 --- a/README.google +++ b/README.google @@ -384,3 +384,28 @@ they are an ongoing maintenance burden. + (basic_lookup_transparent_type): Ditto. + * windows-tdep.c (windows_iterate_over_objfiles_in_search_order): + Ditto. +--- README.google 2015-09-06 00:39:08.000000000 -0700 ++++ README.google 2015-09-06 00:43:48.000000000 -0700 ++ ++2015-09-05 Doug Evans <dje@google.com> ++ ++ * NEWS: Document new post-initializer support for Python. ++ * extension-priv.h (extension_language_ops) <post_initialization>: ++ New member. ++ * extension.c (post_ext_lang_initialization): New function. ++ * extension.h (post_ext_lang_initialization): Declare. ++ * main.c: #include "extension.h". ++ (captured_main): Call post_ext_lang_initialization. ++ * python/lib/gdb/__init__.py (post_initializers): Define. ++ * python/python.c (python_extension_ops): Update. ++ (gdbpy_post_initialization): New function. ++ * guile/guile.c (guile_extension_ops): Update. ++ ++ doc/ ++ * python.texi (Python API): Add entry for Startup Post-Initialization. ++ (Startup Post-Initialization): New node. ++ ++ testsuite/ ++ * gdb.python/py-post-init.c: New file. ++ * gdb.python/py-post-init.exp: New file. ++ * gdb.python/py-post-init.py: New file. diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 45de2bf8a30..9fd667e8732 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -135,6 +135,7 @@ optional arguments while skipping others. Example: @menu * Basic Python:: Basic Python Functions. * Exception Handling:: How Python exceptions are translated. +* Startup Post-Initialization:: Running python at the end of GDB startup. * Values From Inferior:: Python representation of values. * Types In Python:: Python representation of types. * Pretty Printing API:: Pretty-printing values. @@ -512,6 +513,48 @@ to handle this case. Example: hello-world takes no arguments @end smallexample +@node Startup Post-Initialization +@subsubsection Startup Post-Initialization +@cindex running python at the end of GDB startup + +@value{GDBN} provides a way to run Python code at the end of startup, +after @code{-iex}, @code{-ix}, and @code{-cd} option processing, +and before it loads any specified program. +Such initialization may depend on various startup options, so +@value{GDBN} invokes them after all such options are processed. + +The Python list @code{gdb.post_initializers} contains an array of +functions or callable objects that have been registered. +Registration is done via appending to the list. + +As an example, suppose the @file{system.gdbinit} file provides a set of +features that are loaded, if present, from the current directory. +The features must be loaded before the program is loaded, +and must take into account the @code{-cd} option. +Thus loading must be delayed until after processing the @code{-cd} +option but before the inferior program is loaded. +This is achieved with a ``post-initializer'' function. +The function is registered by @file{system.gdbinit} and is called +at the correct time by @value{GDBN}. + +Here is a small example: + +@smallexample +$ cd $HOME +$ cat post-init.py +def post_init(): + print "Hi, this is post_init." + gdb.execute("pwd") +import gdb +gdb.post_initializers.append(post_init) +$ gdb -quiet -cd /tmp -iex pwd -ix post-init.py $HOME/myprogram +Working directory /home/user. +Hi, this is post_init. +Working directory /tmp. +Reading symbols from /home/user/myprogram...done. +(gdb) +@end smallexample + @node Values From Inferior @subsubsection Values From Inferior @cindex values from inferior, with Python diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h index d0242e28f29..b78543248a9 100644 --- a/gdb/extension-priv.h +++ b/gdb/extension-priv.h @@ -136,6 +136,10 @@ struct extension_language_ops This method is required. */ int (*initialized) (const struct extension_language_defn *); + /* Called after -iex, -ix, -cd and -d options are processed to perform + any final user-specified initialization prior to loading the binary. */ + void (*post_initialization) (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 0f426ccada3..9b3546c6cb7 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -337,6 +337,22 @@ finish_ext_lang_initialization (void) } } +/* Wrapper to call the extension_language_ops.post_initialization "method" + for each compiled-in extension language. */ + +void +post_ext_lang_initialization (void) +{ + int i; + const struct extension_language_defn *extlang; + + ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang) + { + if (extlang->ops->post_initialization != NULL) + extlang->ops->post_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. diff --git a/gdb/extension.h b/gdb/extension.h index ea30035c5f3..7f9ac7ae787 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -213,6 +213,8 @@ extern int ext_lang_auto_load_enabled (const struct extension_language_defn *); extern void finish_ext_lang_initialization (void); +extern void post_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 *); diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c index 4abf5c5bb14..dbb2836e7d2 100644 --- a/gdb/guile/guile.c +++ b/gdb/guile/guile.c @@ -138,6 +138,7 @@ const struct extension_language_ops guile_extension_ops = { gdbscm_finish_initialization, gdbscm_initialized, + NULL, /* gdbscm_post_initialization */ gdbscm_eval_from_control_command, diff --git a/gdb/main.c b/gdb/main.c index 68c4b85df4e..a87a09b8819 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -44,6 +44,7 @@ #include <signal.h> #include "event-top.h" #include "infrun.h" +#include "extension.h" /* The selected interpreter. This will be used as a set command variable, so it should always be malloc'ed - since @@ -1040,6 +1041,12 @@ captured_main (void *data) catch_command_errors (directory_switch, dirarg[i], 0); xfree (dirarg); + /* We're about to load the program (if specified). + Given extension languages a chance to do any final preprocessing, + after -ix, -iex, -cd, and -d parameters are processed, and prior to + the program being loaded. */ + post_ext_lang_initialization (); + /* Skip auto-loading section-specified scripts until we've sourced local_gdbinit (which is often used to augment the source search path). */ diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py index 81789e5f6a4..e4028c9ccef 100644 --- a/gdb/python/lib/gdb/__init__.py +++ b/gdb/python/lib/gdb/__init__.py @@ -62,6 +62,9 @@ prompt_hook = None # We do not use PySys_SetArgvEx because it did not appear until 2.6.6. sys.argv = [''] +# Initial post-initializers. +post_initializers = [] + # Initial pretty printers. pretty_printers = [] diff --git a/gdb/python/python.c b/gdb/python/python.c index 60a60a3b173..59b16ff0bd2 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -135,6 +135,8 @@ static objfile_script_executor_func gdbpy_execute_objfile_script; static void gdbpy_finish_initialization (const struct extension_language_defn *); static int gdbpy_initialized (const struct extension_language_defn *); +static void gdbpy_post_initialization + (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 *, @@ -166,6 +168,7 @@ const struct extension_language_ops python_extension_ops = { gdbpy_finish_initialization, gdbpy_initialized, + gdbpy_post_initialization, gdbpy_eval_from_control_command, @@ -1981,6 +1984,54 @@ gdbpy_initialized (const struct extension_language_defn *extlang) return gdb_python_initialized; } +/* Called after -iex, -ix, -cd and -d options are processed to perform + any final user-specified initialization prior to loading the binary. */ + +static void +gdbpy_post_initialization (const struct extension_language_defn *extlang) +{ + PyObject *pi_list, *function, *result; + Py_ssize_t pi_list_size, list_index; + struct cleanup *cleanup; + + cleanup = ensure_python_env (get_current_arch (), current_language); + + /* Fetch the global post-initializer list. */ + if (gdb_python_module == NULL + || ! PyObject_HasAttrString (gdb_python_module, "post_initializers")) + { + do_cleanups (cleanup); + return; + } + pi_list = PyObject_GetAttrString (gdb_python_module, "post_initializers"); + if (pi_list == NULL || ! PyList_Check (pi_list)) + { + Py_XDECREF (pi_list); + do_cleanups (cleanup); + return; + } + + pi_list_size = PyList_Size (pi_list); + for (list_index = 0; list_index < pi_list_size; list_index++) + { + function = PyList_GetItem (pi_list, list_index); + result = NULL; + if (function != NULL) + result = PyObject_CallFunctionObjArgs (function, NULL); + if (result == NULL) + { + /* Print the trace here, but keep going -- we want to + call all of the callbacks even if one is broken. */ + gdbpy_print_stack (); + } + Py_XDECREF (function); + Py_XDECREF (result); + } + + Py_DECREF (pi_list); + do_cleanups (cleanup); +} + #endif /* HAVE_PYTHON */ |