summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2015-12-10 12:00:33 -0800
committerDoug Evans <dje@google.com>2015-12-10 12:00:33 -0800
commit6dc3050775f42a9e9877d967aa81cf9af161da85 (patch)
tree6715acdd02e26a4431ff5bb1432dc290db8fde35
parent5ca623bde7d8fd87f93aa869295ed033f083c5a8 (diff)
downloadbinutils-gdb-6dc3050775f42a9e9877d967aa81cf9af161da85.tar.gz
patch ../102438532.patch
-rw-r--r--README.google25
-rw-r--r--gdb/doc/python.texi43
-rw-r--r--gdb/extension-priv.h4
-rw-r--r--gdb/extension.c16
-rw-r--r--gdb/extension.h2
-rw-r--r--gdb/guile/guile.c1
-rw-r--r--gdb/main.c7
-rw-r--r--gdb/python/lib/gdb/__init__.py3
-rw-r--r--gdb/python/python.c51
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 */