]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
patch ../102438532.patch
authorDoug Evans <dje@google.com>
Thu, 10 Dec 2015 20:00:33 +0000 (12:00 -0800)
committerDoug Evans <dje@google.com>
Thu, 10 Dec 2015 20:00:33 +0000 (12:00 -0800)
README.google
gdb/doc/python.texi
gdb/extension-priv.h
gdb/extension.c
gdb/extension.h
gdb/guile/guile.c
gdb/main.c
gdb/python/lib/gdb/__init__.py
gdb/python/python.c

index a1ab047ad3ac7b59275486bf2920b32ba9619ccd..6bd979ae4e6b1425ce3b0581bba2296c708fb844 100644 (file)
@@ -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.
index 45de2bf8a307adbb18bc112d8aff2c4f070ee895..9fd667e8732f09c234377779984d88f5251387db 100644 (file)
@@ -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
index d0242e28f296df24a667e89e85abcbee35ccad35..b78543248a9e05457930af1ee16460839e42b0f5 100644 (file)
@@ -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
index 0f426ccada3b74d94aa831cd02d33dc694e3e6c5..9b3546c6cb75b5611258a1c5a4038be0362ddb8e 100644 (file)
@@ -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.
 
index ea30035c5f3c6a56efec029636edaf69940fa566..7f9ac7ae787f185a5b4c1b4b721e0f0ff69f37a3 100644 (file)
@@ -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 *);
index 4abf5c5bb14537d20767a2e8caef01e30ae34d78..dbb2836e7d27f370044852ff22b2c288dd495646 100644 (file)
@@ -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,
 
index 68c4b85df4edd80fee9f13d6e984cede52ba8f9d..a87a09b8819a786ae5b927f383d495d22b133c3b 100644 (file)
@@ -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).  */
index 81789e5f6a42b3d3e951dae1f6f5009494de4ffa..e4028c9ccef5fed30c20d2290f454ae8e5e81c0a 100644 (file)
@@ -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 = []
 
index 60a60a3b173e37734ccdb3f01dda3741d5119aa4..59b16ff0bd2fd36ef651c199a404e0889dca921d 100644 (file)
@@ -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 */
 
 \f