public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
@ 2010-04-16  7:06 Doug Evans
  2010-04-16  9:38 ` Eli Zaretskii
  2010-04-20 19:13 ` Tom Tromey
  0 siblings, 2 replies; 12+ messages in thread
From: Doug Evans @ 2010-04-16  7:06 UTC (permalink / raw)
  To: gdb-patches

Hi.

This patch adds support for auto-loading scripts mentioned in
section .debug_gdb_scripts.
It is useful in some places where the auto-loading of ${objfile}-gdb.py isn't.

E.g.,
- static linking: collecting together scripts from various input libraries
    can be problematic
- classes that are fully inlined: there may not be an associated objfile
    to attach the -gdb.py script to
- scripts needn't be copied out of the source tree:
    apps can be built out of large collections of internal
    libraries, and the build infrastructure necessary to install the
    -gdb.py scripts in a place where GDB can find them is
    cumbersome.  It may be easier to specify the scripts in the
    .debug_gdb_scripts section as relative paths, and add a path to the
    top of the source tree to the source search path.

The intended usage is to have a macro like DEFINE_GDB_SCRIPT and then
reference the macro in a header or source file.

#define DEFINE_GDB_SCRIPT(script_name) \
  asm("\
.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
.byte 1\n\
.asciz \"" script_name "\"\n\
.popsection \n\
");

And then in, say, mylib.h,

DEFINE_GDB_SCRIPT ("mylib.py")

File names are recorded in the section instead of python code
so that the user doesn't have to relink when the script changes.
Plus there can be a plethora of different scripts for unrelated
classes and it's easier to manage/identify them this way.

NOTES:
- It may be useful to be able to add another search directory
  for scripts outside of the source search path,
  but it can be added if/when needed.
- It'd be useful to reload scripts when its timestamp changes,
  but auto-loading won't retrigger until the objfile is reloaded anyway.
  -gdb.py scripts suffer from this too.
- A useful extension is to be able to specify a $cdir-like directory to
  entries in .debug_gdb_scripts.
  - needs a gcc extension
All of these can be done later.

I moved the Auto-loading section of the docs out of the Python API section
because I like it better that way, and because it solves a technical
problem: there's no @subsubsubsection. :-)
This could be done differently of course.

Comments?

2010-04-15  Doug Evans  <dje@google.com>

	Add support for auto-loading scripts from .debug_gdb_scripts section.
	* NEWS: Add entry for .debug_gdb_scripts.
	* Makefile.in SUBDIR_PYTHON_OBS): Add py-auto-load.o.
	(SUBDIR_PYTHON_SRCS): Add py-auto-load.c.
	(py-auto-load.o): New rule.
	* cli/cli-cmds.c (find_and_open_script): Make externally visible.
	* cli/cli-cmds.h (find_and_open_script): Update prototype.
	* python/py-auto-load.c: New file.
	* python/python-internal.h: #include <stdio.h>.
	(set_python_list, show_python_list): Declare.
	(gdbpy_initialize_auto_load): Declare.
	(source_python_script_for_objfile): Declare.
	* python/python.c: Remove #include of observer.h.
	(gdbpy_auto_load): Moved to py-auto-load.c.
	(GDBPY_AUTO_FILENAME): Ditto.
	(gdbpy_new_objfile): Delete.
	(source_python_script_for_objfile): New function.
	(set_python_list, show_python_list): Make externally visible.
	(_initialize_python): Move "auto-load" command to py-auto-load.c
	and observer_attach_new_objfile to py-auto-load.c.

	doc/
	* gdb.texinfo (Python): Move Auto-loading section here ...
	(Python API): from here.
	(Auto-loading): Add docs for .debug_gdb_scripts auto-loaded scripts.
	(Maintenance Commands): Add docs for "maint print section-scripts".

	testsuite/
	* gdb.python/py-section-script.c: New file.
	* gdb.python/py-section-script.exp: New file.
	* gdb.python/py-section-script.py: New file.

Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.371
diff -u -p -r1.371 NEWS
--- NEWS	15 Apr 2010 19:54:12 -0000	1.371
+++ NEWS	16 Apr 2010 05:58:03 -0000
@@ -42,6 +42,8 @@
 
 ** Pretty-printers are now also looked up in the current program space.
 
+** GDB now looks for scripts to auto-load in the .debug_gdb_scripts section.
+
 * Tracepoint actions were unified with breakpoint commands. In particular,
 there are no longer differences in "info break" output for breakpoints and
 tracepoints and the "commands" command can be used for both tracepoints and
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1118
diff -u -p -r1.1118 Makefile.in
--- Makefile.in	15 Apr 2010 19:54:12 -0000	1.1118
+++ Makefile.in	16 Apr 2010 05:54:34 -0000
@@ -267,6 +267,7 @@ SUBDIR_TUI_CFLAGS= \
 #
 SUBDIR_PYTHON_OBS = \
 	python.o \
+	py-auto-load.o \
 	py-block.o \
 	py-breakpoint.o \
 	py-cmd.o \
@@ -283,6 +284,7 @@ SUBDIR_PYTHON_OBS = \
 	py-value.o
 SUBDIR_PYTHON_SRCS = \
 	python/python.c \
+	python/py-auto-load.c \
 	python/py-block.c \
 	python/py-breakpoint.c \
 	python/py-cmd.c \
@@ -1986,6 +1988,10 @@ python.o: $(srcdir)/python/python.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
 	$(POSTCOMPILE)
 
+py-auto-load.o: $(srcdir)/python/py-auto-load.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-auto-load.c
+	$(POSTCOMPILE)
+
 py-block.o: $(srcdir)/python/py-block.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-block.c
 	$(POSTCOMPILE)
Index: cli/cli-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-cmds.c,v
retrieving revision 1.101
diff -u -p -r1.101 cli-cmds.c
--- cli/cli-cmds.c	15 Apr 2010 17:45:52 -0000	1.101
+++ cli/cli-cmds.c	16 Apr 2010 05:54:35 -0000
@@ -483,7 +483,7 @@ Script filename extension recognition is
    NOTE: This calls openp which uses xfullpath to compute the full path
    instead of gdb_realpath.  Symbolic links are not resolved.  */
 
-static int
+int
 find_and_open_script (const char *script_file, int search_path,
 		      FILE **streamp, char **full_pathp)
 {
Index: cli/cli-cmds.h
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-cmds.h,v
retrieving revision 1.14
diff -u -p -r1.14 cli-cmds.h
--- cli/cli-cmds.h	1 Jan 2010 07:31:46 -0000	1.14
+++ cli/cli-cmds.h	16 Apr 2010 05:54:35 -0000
@@ -123,6 +123,11 @@ extern void quit_command (char *, int);
 
 extern void source_script (char *, int);
 
+/* Exported to objfiles.c.  */
+
+extern int find_and_open_script (const char *file, int search_path,
+				 FILE **streamp, char **full_path);
+
 /* Used everywhere whenever at least one parameter is required and
   none is specified. */
 
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.706
diff -u -p -r1.706 gdb.texinfo
--- doc/gdb.texinfo	15 Apr 2010 19:54:13 -0000	1.706
+++ doc/gdb.texinfo	16 Apr 2010 05:54:35 -0000
@@ -19639,6 +19639,7 @@ Python programming language}.  This feat
 @menu
 * Python Commands::             Accessing Python from @value{GDBN}.
 * Python API::                  Accessing @value{GDBN} from Python.
+* Auto-loading::                Automatically loading Python code.
 @end menu
 
 @node Python Commands
@@ -19716,7 +19717,6 @@ situation, a Python @code{KeyboardInterr
 @menu
 * Basic Python::                Basic Python Functions.
 * Exception Handling::
-* Auto-loading::                Automatically loading Python code.
 * Values From Inferior::
 * Types In Python::		Python representation of types.
 * Pretty Printing::		Pretty-printing values.
@@ -19862,53 +19862,6 @@ message as its value, and the Python cal
 Python statement closest to where the @value{GDBN} error occured as the
 traceback.
 
-@node Auto-loading
-@subsubsection Auto-loading
-@cindex auto-loading, Python
-
-When a new object file is read (for example, due to the @code{file}
-command, or because the inferior has loaded a shared library),
-@value{GDBN} will look for a file named @file{@var{objfile}-gdb.py},
-where @var{objfile} is the object file's real name, formed by ensuring
-that the file name is absolute, following all symlinks, and resolving
-@code{.} and @code{..}  components.  If this file exists and is
-readable, @value{GDBN} will evaluate it as a Python script.
-
-If this file does not exist, and if the parameter
-@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
-then @value{GDBN} will use for its each separated directory component
-@code{component} the file named @file{@code{component}/@var{real-name}}, where
-@var{real-name} is the object file's real name, as described above.
-
-Finally, if this file does not exist, then @value{GDBN} will look for
-a file named @file{@var{data-directory}/python/auto-load/@var{real-name}}, where
-@var{data-directory} is @value{GDBN}'s data directory (available via
-@code{show data-directory}, @pxref{Data Files}), and @var{real-name}
-is the object file's real name, as described above.
-
-When reading an auto-loaded file, @value{GDBN} sets the ``current
-objfile''.  This is available via the @code{gdb.current_objfile}
-function (@pxref{Objfiles In Python}).  This can be useful for
-registering objfile-specific pretty-printers.
-
-The auto-loading feature is useful for supplying application-specific
-debugging commands and scripts.  You can enable or disable this
-feature, and view its current state.
-
-@table @code
-@kindex maint set python auto-load
-@item maint set python auto-load [yes|no]
-Enable or disable the Python auto-loading feature.
-
-@kindex maint show python auto-load
-@item maint show python auto-load
-Show whether Python auto-loading is enabled or disabled.
-@end table
-
-@value{GDBN} does not track which files it has already auto-loaded.
-So, your @samp{-gdb.py} file should take care to ensure that it may be
-evaluated multiple times without error.
-
 @node Values From Inferior
 @subsubsection Values From Inferior
 @cindex values from inferior, with Python
@@ -21565,6 +21518,172 @@ resolve this to the lazy string's charac
 writable.
 @end defivar
 
+@node Auto-loading
+@subsection Auto-loading
+@cindex auto-loading, Python
+
+When a new object file is read (for example, due to the @code{file}
+command, or because the inferior has loaded a shared library),
+@value{GDBN} will look for support scripts in up to two ways:
+@file{@var{objfile}-gdb.py} and @file{.debug_gdb_scripts} section.
+
+@menu
+* @file{@var{objfile}-gdb.py} file::
+* @file{.debug_gdb_scripts} section::
+* Which flavor to choose?::
+@end menu
+
+The auto-loading feature is useful for supplying application-specific
+debugging commands and scripts.
+
+When reading an auto-loaded file, @value{GDBN} sets the ``current
+objfile''.  This is available via the @code{gdb.current_objfile}
+function (@pxref{Objfiles In Python}).  This can be useful for
+registering objfile-specific pretty-printers.
+
+Auto-loading can be enabled or disabled.
+
+@table @code
+@kindex maint set python auto-load
+@item maint set python auto-load [yes|no]
+Enable or disable the Python auto-loading feature.
+
+@kindex maint show python auto-load
+@item maint show python auto-load
+Show whether Python auto-loading is enabled or disabled.
+@end table
+
+@node @file{@var{objfile}-gdb.py} file
+@subsubsection @file{@var{objfile}-gdb.py} file
+@cindex @file{@var{objfile}-gdb.py}
+
+When a new object file is read, @value{GDBN} looks for
+a file named @file{@var{objfile}-gdb.py},
+where @var{objfile} is the object file's real name, formed by ensuring
+that the file name is absolute, following all symlinks, and resolving
+@code{.} and @code{..} components.  If this file exists and is
+readable, @value{GDBN} will evaluate it as a Python script.
+
+If this file does not exist, and if the parameter
+@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
+then @value{GDBN} will use for its each separated directory component
+@code{component} the file named @file{@code{component}/@var{real-name}}, where
+@var{real-name} is the object file's real name, as described above.
+
+Finally, if this file does not exist, then @value{GDBN} will look for
+a file named @file{@var{data-directory}/python/auto-load/@var{real-name}}, where
+@var{data-directory} is @value{GDBN}'s data directory (available via
+@code{show data-directory}, @pxref{Data Files}), and @var{real-name}
+is the object file's real name, as described above.
+
+@value{GDBN} does not track which files it has already auto-loaded this way.
+@value{GDBN} will load the associated script every time the corresponding
+@var{objfile} is opened.
+So, your @samp{-gdb.py} file should take care to ensure that it may be
+evaluated multiple times without error.
+
+@node @file{.debug_gdb_scripts} section
+@subsubsection @file{.debug_gdb_scripts} section
+@cindex .debug_gdb_scripts section
+
+For systems using the ELF file format, and other formats supporting
+multiple sections, when @value{GDBN} loads an @var{objfile}
+it will look for scripts in the @file{.debug_gdb_scripts} section
+when an objfile is loaded.
+This section contains a list of names of scripts to load.
+File names are recorded instead of the file's contents so that
+the user doesn't have to relink if a script changes,
+and so that the plethora of random scripts are better managed,
+
+The scripts are searched for first in the current directory, and then
+in the source search path
+(@pxref{Source Path, ,Specifying Source Directories}),
+with the exception that @file{$cdir} is not searched, the compilation
+directory is not relevant to scripts.
+
+Entries can be placed in section @file{.debug_gdb_scripts} with,
+for example, this GCC macro:
+
+@example
+#define DEFINE_GDB_SCRIPT(script_name) \
+  asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@@progbits,1\n\
+.byte 1\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+@end example
+
+Then one can reference the macro in a header or source file like this:
+
+@example
+DEFINE_GDB_SCRIPT ("my-app-scripts.py")
+@end example
+
+If the macro is put in a header, any application or library
+using this header will get a reference to the specified script.
+The above macro uses the @code{"MS"} GAS section flags to
+remove duplicate entries.
+
+Unlike loading of @file{@var{objfile}-gdb.py} scripts,
+@value{GDBN} keeps track of scripts loaded this way.
+If the reference to the script is coming from a header file,
+the script can be referenced by multiple shared libraries.
+As an optimization to prevent loading the script 100's or even 1000's
+of times, @value{GDBN} will only auto-load a script once in each
+program space.
+However, you should still write your scripts to ensure
+that it may be evaluated multiple times without error.
+
+@node Which flavor to choose?
+@subsubsection Which flavor to choose?
+
+Given the two ways of auto-loading scripts, it might not always be clear
+which one to choose.  This section provides some guidance.
+
+Benefits of the @file{-gdb.py} way:
+
+@itemize @bullet
+@item
+Can be used with file formats that don't support multiple sections.
+
+@item
+Ease of finding scripts for public libraries.
+
+Scripts specified in the @file{.debug_gdb_scripts} section are searched for
+in the source search path.
+For publicly installed libraries, e.g. libstdc++, there typically isn't a
+source directory in which to find the script.
+@end itemize
+
+Benefits of the @file{.debug_gdb_scripts} way:
+
+@itemize @bullet
+@item
+Works with static linking.
+
+Scripts for libraries done the @file{-gdb.py} way require an objfile to
+trigger their loading.  When an application is statically linked the only
+objfile available is the executable, and it is cumbersome to attach all the
+scripts from all the input libraries to the executable's @file{-gdb.py} script.
+
+@item
+Works with classes that are entirely inlined.
+
+Some classes can be entirely inlined, and thus there may not be an associated
+shared library to attach a @file{-gdb.py} script to.
+
+@item
+Scripts needn't be copied out of the source tree.
+
+In some circumstances, apps can be built out of large collections of internal
+libraries, and the build infrastructure necessary to install the
+@file{-gdb.py} scripts in a place where @value{GDBN} can find them is
+cumbersome.  It may be easier to specify the scripts in the
+@file{.debug_gdb_scripts} section as relative paths, and add a path to the
+top of the source tree to the source search path.
+@end itemize
+
 @node Interpreters
 @chapter Command Interpreters
 @cindex command interpreters
@@ -29367,6 +29486,15 @@ Print a dump of all known object files. 
 command prints its name, address in memory, and all of its psymtabs
 and symtabs.
 
+@kindex maint print section-scripts
+@cindex info for known .debug_gdb_scripts-loaded scripts
+@item maint print section-scripts [@var{regexp}]
+Print a dump of scripts specified in the @file{.debug_gdb_section} section.
+If @var{regexp} is specified, only print scripts loaded by object files
+matching @var{regexp}.
+For each script, this command prints its name as specified in the objfile,
+and the full path if known.
+
 @kindex maint print statistics
 @cindex bcache statistics
 @item maint print statistics
Index: python/py-auto-load.c
===================================================================
RCS file: python/py-auto-load.c
diff -N python/py-auto-load.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ python/py-auto-load.c	16 Apr 2010 05:54:35 -0000
@@ -0,0 +1,459 @@
+/* GDB routines for supporting auto-loaded scripts.
+
+   Copyright (C) 2010 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/>.  */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "gdb_regex.h"
+#include "top.h"
+#include "exceptions.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "observer.h"
+#include "progspace.h"
+#include "objfiles.h"
+#include "python.h"
+#include "python-internal.h"
+#include "cli/cli-cmds.h"
+
+/* NOTE: It's trivial to also support auto-loading normal gdb scripts.
+   There has yet to be a need so it's not implemented.  */
+
+/* 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"
+
+/* The section to look for scripts (in file formats that support sections).
+   Each entry in this section is a byte of value 1, and then the nul-terminated
+   name of the script.  The script name may include a directory.
+   The leading byte is to allow upward compatible extensions.  */
+#define GDBPY_AUTO_SECTION_NAME ".debug_gdb_scripts"
+
+/* For scripts specified in .debug_gdb_scripts, multiple objfiles may load
+   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
+   loaded this way.  */
+
+struct auto_load_pspace_info
+{
+  /* For each program space we keep track of loaded scripts.  */
+  struct htab *loaded_scripts;
+};
+
+/* Objects of this type are stored in the loaded script hash table.  */
+
+struct loaded_script_entry
+{
+  /* Name as provided by the objfile.  */
+  const char *name;
+  /* Full path name or NULL if script wasn't found (or was otherwise
+     inaccessible).  */
+  const char *full_path;
+};
+
+/* This is true if we should auto-load python code when an objfile is opened,
+   false otherwise.  */
+static int gdbpy_auto_load = 1;
+
+/* Per-program-space data key.  */
+static const struct program_space_data *auto_load_pspace_data;
+
+static void
+auto_load_pspace_data_cleanup (struct program_space *pspace, void *arg)
+{
+  struct auto_load_pspace_info *info;
+
+  info = program_space_data (pspace, auto_load_pspace_data);
+  if (info != NULL)
+    {
+      if (info->loaded_scripts)
+	htab_delete (info->loaded_scripts);
+      xfree (info);
+    }
+}
+
+/* Get the current autoload data.  If none is found yet, add it now.  This
+   function always returns a valid object.  */
+
+static struct auto_load_pspace_info *
+get_auto_load_pspace_data (struct program_space *pspace)
+{
+  struct auto_load_pspace_info *info;
+
+  info = program_space_data (pspace, auto_load_pspace_data);
+  if (info == NULL)
+    {
+      info = XZALLOC (struct auto_load_pspace_info);
+      set_program_space_data (pspace, auto_load_pspace_data, info);
+    }
+
+  return info;
+}
+
+/* Hash function for the loaded script hash.  */
+
+static hashval_t
+hash_loaded_script_entry (const void *data)
+{
+  const struct loaded_script_entry *e = data;
+  return htab_hash_string (e->name);
+}
+
+/* Equality function for the loaded script hash.  */
+
+static int
+eq_loaded_script_entry (const void *a, const void *b)
+{
+  const struct loaded_script_entry *ea = a;
+  const struct loaded_script_entry *eb = b;
+  return strcmp (ea->name, eb->name) == 0;
+}
+
+/* Create the hash table used for loaded scripts.
+   Each entry is hashed by the full path name.  */
+
+static void
+create_loaded_scripts_hash (struct auto_load_pspace_info *pspace_info)
+{
+  /* Choose 31 as the starting size of the hash table, somewhat arbitrarily.
+     Space for each entry is obtained with one malloc so we can free them
+     easily.  */
+
+  pspace_info->loaded_scripts = htab_create (31,
+					     hash_loaded_script_entry,
+					     eq_loaded_script_entry,
+					     xfree);
+}
+
+/* Load scripts specified in OBJFILE.
+   START,END delimit a buffer containing a list of nul-terminated
+   file names.
+   SOURCE_NAME is used in error messages.
+
+   Scripts are found per normal "source -s" command processing.
+   First the script is looked for in $cwd.  If not found there the
+   source search path is used.
+
+   The section contains a list of path names of files containing
+   python code to load.  Each path is null-terminated.  */
+
+static void
+source_section_scripts (struct objfile *objfile, const char *source_name,
+			const char *start, const char *end)
+{
+  const char *p;
+  struct auto_load_pspace_info *pspace_info;
+  struct loaded_script_entry **slot, entry;
+
+  pspace_info = get_auto_load_pspace_data (current_program_space);
+  if (pspace_info->loaded_scripts == NULL)
+    create_loaded_scripts_hash (pspace_info);
+
+  for (p = start; p < end; ++p)
+    {
+      const char *file;
+      FILE *stream;
+      char *full_path;
+      int opened, in_hash_table;
+
+      if (*p != 1)
+	{
+	  warning (_("Invalid entry in %s section"), GDBPY_AUTO_SECTION_NAME);
+	  /* We could try various heuristics to find the next valid entry,
+	     but it's safer to just punt.  */
+	  break;
+	}
+      file = ++p;
+
+      while (p < end && *p != '\0')
+	++p;
+      if (p == end)
+	{
+	  char *buf = alloca (p - file + 1);
+	  memcpy (buf, file, p - file);
+	  buf[p - file] = '\0';
+	  warning (_("Non-null-terminated path in %s: %s"),
+		   source_name, buf);
+	  /* Don't load it.  */
+	  break;
+	}
+      if (p == file)
+	{
+	  warning (_("Empty path in %s"), source_name);
+	  continue;
+	}
+
+      opened = find_and_open_script (file, 1 /*search_path*/,
+				     &stream, &full_path);
+
+      /* If the file is not found, we still record the file in the hash table,
+	 we only want to print an error message once.
+	 IWBN if complaints.c were more general-purpose.  */
+
+      entry.name = file;
+      if (opened)
+	entry.full_path = full_path;
+      else
+	entry.full_path = NULL;
+      slot = ((struct loaded_script_entry **)
+	      htab_find_slot (pspace_info->loaded_scripts,
+			      &entry, INSERT));
+      in_hash_table = *slot != NULL;
+
+      /* If this file is not in the hash table, add it.  */
+      if (! in_hash_table)
+	{
+	  char *p;
+	  *slot = xmalloc (sizeof (**slot)
+			   + strlen (file) + 1
+			   + (opened ? (strlen (full_path) + 1) : 0));
+	  p = ((char*) *slot) + sizeof (**slot);
+	  strcpy (p, file);
+	  (*slot)->name = p;
+	  if (opened)
+	    {
+	      p += strlen (p) + 1;
+	      strcpy (p, full_path);
+	      (*slot)->full_path = p;
+	    }
+	  else
+	    (*slot)->full_path = NULL;
+	}
+
+      if (opened)
+	free (full_path);
+
+      if (! opened)
+	{
+	  /* We don't throw an error, the program is still debuggable.
+	     Check in_hash_table to only print the warning once.  */
+	  if (! in_hash_table)
+	    warning (_("%s (referenced in %s): %s\n"),
+		     file, GDBPY_AUTO_SECTION_NAME, safe_strerror (errno));
+	  continue;
+	}
+
+      /* If this file is not currently loaded, load it.  */
+      if (! in_hash_table)
+	source_python_script_for_objfile (objfile, stream, file);
+    }
+}
+
+/* Load scripts specified in section SECTION_NAME of OBJFILE.  */
+
+static void
+auto_load_section_scripts (struct objfile *objfile, const char *section_name)
+{
+  bfd *abfd = objfile->obfd;
+  asection *scripts_sect;
+  bfd_size_type size;
+  char *p;
+  struct cleanup *cleanups;
+
+  scripts_sect = bfd_get_section_by_name (abfd, section_name);
+  if (scripts_sect == NULL)
+    return;
+
+  size = bfd_get_section_size (scripts_sect);
+  p = xmalloc (size);
+  
+  cleanups = make_cleanup (xfree, p);
+
+  if (bfd_get_section_contents (abfd, scripts_sect, p, (file_ptr) 0, size))
+    source_section_scripts (objfile, section_name, p, p + size);
+  else
+    warning (_("Couldn't read %s section of %s"),
+	     section_name, bfd_get_filename (abfd));
+
+  do_cleanups (cleanups);
+}
+
+/* Clear the table of loaded section scripts.  */
+
+static void
+clear_section_scripts (void)
+{
+  struct program_space *pspace = current_program_space;
+  struct auto_load_pspace_info *info;
+
+  info = program_space_data (pspace, auto_load_pspace_data);
+  if (info != NULL && info->loaded_scripts != NULL)
+    {
+      htab_delete (info->loaded_scripts);
+      info->loaded_scripts = NULL;
+    }
+}
+
+/* Look for the auto-load script associated with OBJFILE and load it.  */
+
+static void
+auto_load_objfile_script (struct objfile *objfile, const char *suffix)
+{
+  char *realname;
+  char *filename, *debugfile;
+  int len;
+  FILE *input;
+  struct cleanup *cleanups;
+
+  realname = gdb_realpath (objfile->name);
+  len = strlen (realname);
+  filename = xmalloc (len + strlen (suffix) + 1);
+  memcpy (filename, realname, len);
+  strcpy (filename + len, suffix);
+
+  cleanups = make_cleanup (xfree, filename);
+  make_cleanup (xfree, realname);
+
+  input = fopen (filename, "r");
+  debugfile = filename;
+
+  if (!input && debug_file_directory)
+    {
+      /* Also try the same file in the separate debug info directory.  */
+      debugfile = xmalloc (strlen (filename)
+			   + strlen (debug_file_directory) + 1);
+      strcpy (debugfile, debug_file_directory);
+      /* FILENAME is absolute, so we don't need a "/" here.  */
+      strcat (debugfile, filename);
+
+      make_cleanup (xfree, debugfile);
+      input = fopen (debugfile, "r");
+    }
+
+  if (!input && gdb_datadir)
+    {
+      /* Also try the same file in a subdirectory of gdb's data
+	 directory.  */
+      debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename)
+			   + strlen ("/auto-load") + 1);
+      strcpy (debugfile, gdb_datadir);
+      strcat (debugfile, "/auto-load");
+      /* FILENAME is absolute, so we don't need a "/" here.  */
+      strcat (debugfile, filename);
+
+      make_cleanup (xfree, debugfile);
+      input = fopen (debugfile, "r");
+    }
+
+  if (input)
+    {
+      source_python_script_for_objfile (objfile, input, debugfile);
+      fclose (input);
+    }
+
+  do_cleanups (cleanups);
+}
+
+/* This is a new_objfile observer callback to auto-load scripts.
+
+   Two flavors of auto-loaded scripts are supported.
+   1) based on the path to the objfile
+   2) from .debug_gdb_scripts section  */
+
+static void
+auto_load_new_objfile (struct objfile *objfile)
+{
+  if (!objfile)
+    {
+      /* OBJFILE is NULL when loading a new "main" symbol-file.  */
+      clear_section_scripts ();
+      return;
+    }
+  if (!objfile->name)
+    return;
+
+  if (gdbpy_auto_load)
+    {
+      auto_load_objfile_script (objfile, GDBPY_AUTO_FILE_NAME);
+      auto_load_section_scripts (objfile, GDBPY_AUTO_SECTION_NAME);
+    }
+}
+\f
+/* Traversal function for htab_traverse.
+   Print the entry if specified in the regex.  */
+
+static int
+maybe_print_section_script (void **slot, void *info)
+{
+  struct loaded_script_entry *entry = *slot;
+
+  if (re_exec (entry->name))
+    {
+      printf_filtered (_("Script name: %s\n"), entry->name);
+      printf_filtered (_("  Full name: %s\n"),
+		       entry->full_path ? entry->full_path : _("unknown"));
+    }
+
+  return 1;
+}
+
+/* "maint print section-scripts" command.  */
+
+static void
+maintenance_print_section_scripts (char *pattern, int from_tty)
+{
+  struct auto_load_pspace_info *pspace_info;
+
+  dont_repeat ();
+
+  if (pattern && *pattern)
+    {
+      char *re_err = re_comp (pattern);
+
+      if (re_err)
+	error (_("Invalid regexp: %s"), re_err);
+
+      printf_filtered (_("Objfile scripts matching %s:\n"), pattern);
+    }
+  else
+    {
+      re_comp ("");
+      printf_filtered (_("Objfile scripts:\n"));
+    }
+
+  pspace_info = get_auto_load_pspace_data (current_program_space);
+  if (pspace_info == NULL || pspace_info->loaded_scripts == NULL)
+    return;
+
+  immediate_quit++;
+  htab_traverse_noresize (pspace_info->loaded_scripts,
+			  maybe_print_section_script, NULL);
+  immediate_quit--;
+}
+\f
+void
+gdbpy_initialize_auto_load (void)
+{
+  auto_load_pspace_data
+    = register_program_space_data_with_cleanup (auto_load_pspace_data_cleanup);
+
+  observer_attach_new_objfile (auto_load_new_objfile);
+
+  add_setshow_boolean_cmd ("auto-load", class_maintenance,
+			   &gdbpy_auto_load, _("\
+Enable or disable auto-loading of Python code when an object is opened."), _("\
+Show whether Python code will be auto-loaded when an object is opened."), _("\
+Enables or disables auto-loading of Python code when an object is opened."),
+			   NULL, NULL,
+			   &set_python_list,
+			   &show_python_list);
+
+  add_cmd ("section-scripts", class_maintenance, maintenance_print_section_scripts,
+	   _("Print dump of auto-loaded section scripts matching REGEXP."),
+	   &maintenanceprintlist);
+}
Index: python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.24
diff -u -p -r1.24 python-internal.h
--- python/python-internal.h	15 Apr 2010 19:54:13 -0000	1.24
+++ python/python-internal.h	16 Apr 2010 05:54:35 -0000
@@ -20,6 +20,8 @@
 #ifndef GDB_PYTHON_INTERNAL_H
 #define GDB_PYTHON_INTERNAL_H
 
+#include <stdio.h>
+
 /* Python 2.4 doesn't include stdint.h soon enough to get {u,}intptr_t
    needed by pyport.h.  */
 #include <stdint.h>
@@ -75,6 +77,9 @@ extern PyTypeObject value_object_type;
 extern PyTypeObject block_object_type;
 extern PyTypeObject symbol_object_type;
 
+extern struct cmd_list_element *set_python_list;
+extern struct cmd_list_element *show_python_list;
+
 PyObject *gdbpy_history (PyObject *self, PyObject *args);
 PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
 PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
@@ -107,6 +112,7 @@ struct type *type_object_to_type (PyObje
 struct symtab *symtab_object_to_symtab (PyObject *obj);
 struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
 
+void gdbpy_initialize_auto_load (void);
 void gdbpy_initialize_values (void);
 void gdbpy_initialize_frames (void);
 void gdbpy_initialize_symtabs (void);
@@ -154,6 +160,9 @@ extern const struct language_defn *pytho
 
 void gdbpy_print_stack (void);
 
+void source_python_script_for_objfile (struct objfile *objfile,
+				       FILE *stream, const char *file);
+
 PyObject *python_string_to_unicode (PyObject *obj);
 char *unicode_to_target_string (PyObject *unicode_str);
 char *python_string_to_target_string (PyObject *obj);
Index: python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.32
diff -u -p -r1.32 python.c
--- python/python.c	15 Apr 2010 19:54:13 -0000	1.32
+++ python/python.c	16 Apr 2010 05:54:35 -0000
@@ -25,7 +25,6 @@
 #include "gdbcmd.h"
 #include "progspace.h"
 #include "objfiles.h"
-#include "observer.h"
 #include "value.h"
 #include "language.h"
 #include "exceptions.h"
@@ -36,10 +35,6 @@
    false otherwise.  */
 static int gdbpy_should_print_stack = 1;
 
-/* This is true if we should auto-load python code when an objfile is
-   opened, false otherwise.  */
-static int gdbpy_auto_load = 1;
-
 #ifdef HAVE_PYTHON
 
 #include "python.h"
@@ -460,85 +455,33 @@ gdbpy_progspaces (PyObject *unused1, PyO
 \f
 
 /* 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 gdbpy_new_objfile; it is NULL at other times.  */
+   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.  */
 static struct objfile *gdbpy_current_objfile;
 
-/* The file name we attempt to read.  */
-#define GDBPY_AUTO_FILENAME "-gdb.py"
+/* Set the current objfile to OBJFILE and then read STREAM,FILE as
+   Python code.  */
 
-/* This is a new_objfile observer callback which loads python code
-   based on the path to the objfile.  */
-static void
-gdbpy_new_objfile (struct objfile *objfile)
+void
+source_python_script_for_objfile (struct objfile *objfile,
+				  FILE *stream, const char *file)
 {
-  char *realname;
-  char *filename, *debugfile;
-  int len;
-  FILE *input;
   struct cleanup *cleanups;
 
-  if (!gdbpy_auto_load || !objfile || !objfile->name)
-    return;
-
   cleanups = ensure_python_env (get_objfile_arch (objfile), current_language);
-
   gdbpy_current_objfile = objfile;
 
-  realname = gdb_realpath (objfile->name);
-  len = strlen (realname);
-  filename = xmalloc (len + sizeof (GDBPY_AUTO_FILENAME));
-  memcpy (filename, realname, len);
-  strcpy (filename + len, GDBPY_AUTO_FILENAME);
-
-  input = fopen (filename, "r");
-  debugfile = filename;
-
-  make_cleanup (xfree, filename);
-  make_cleanup (xfree, realname);
-
-  if (!input && debug_file_directory)
-    {
-      /* Also try the same file in the separate debug info directory.  */
-      debugfile = xmalloc (strlen (filename)
-			   + strlen (debug_file_directory) + 1);
-      strcpy (debugfile, debug_file_directory);
-      /* FILENAME is absolute, so we don't need a "/" here.  */
-      strcat (debugfile, filename);
-
-      make_cleanup (xfree, debugfile);
-      input = fopen (debugfile, "r");
-    }
-
-  if (!input && gdb_datadir)
-    {
-      /* Also try the same file in a subdirectory of gdb's data
-	 directory.  */
-      debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename)
-			   + strlen ("/auto-load") + 1);
-      strcpy (debugfile, gdb_datadir);
-      strcat (debugfile, "/auto-load");
-      /* FILENAME is absolute, so we don't need a "/" here.  */
-      strcat (debugfile, filename);
-
-      make_cleanup (xfree, debugfile);
-      input = fopen (debugfile, "r");
-    }
-
-  if (input)
-    {
-      /* We don't want to throw an exception here -- but the user
-	 would like to know that something went wrong.  */
-      if (PyRun_SimpleFile (input, debugfile))
-	gdbpy_print_stack ();
-      fclose (input);
-    }
+  /* We don't want to throw an exception here -- but the user
+     would like to know that something went wrong.  */
+  if (PyRun_SimpleFile (stream, file))
+    gdbpy_print_stack ();
 
   do_cleanups (cleanups);
   gdbpy_current_objfile = NULL;
 }
 
 /* Return the current Objfile, or None if there isn't one.  */
+
 static PyObject *
 gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2)
 {
@@ -617,8 +560,8 @@ source_python_script (FILE *stream, cons
 
 /* Lists for 'maint set python' commands.  */
 
-static struct cmd_list_element *set_python_list;
-static struct cmd_list_element *show_python_list;
+struct cmd_list_element *set_python_list;
+struct cmd_list_element *show_python_list;
 
 /* Function for use by 'maint set python' prefix command.  */
 
@@ -683,15 +626,6 @@ Enables or disables printing of Python s
 			   &set_python_list,
 			   &show_python_list);
 
-  add_setshow_boolean_cmd ("auto-load", class_maintenance,
-			   &gdbpy_auto_load, _("\
-Enable or disable auto-loading of Python code when an object is opened."), _("\
-Show whether Python code will be auto-loaded when an object is opened."), _("\
-Enables or disables auto-loading of Python code when an object is opened."),
-			   NULL, NULL,
-			   &set_python_list,
-			   &show_python_list);
-
 #ifdef HAVE_PYTHON
   Py_Initialize ();
   PyEval_InitThreads ();
@@ -703,6 +637,7 @@ Enables or disables auto-loading of Pyth
   PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name);
   PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
 
+  gdbpy_initialize_auto_load ();
   gdbpy_initialize_values ();
   gdbpy_initialize_frames ();
   gdbpy_initialize_commands ();
@@ -719,8 +654,6 @@ Enables or disables auto-loading of Pyth
   PyRun_SimpleString ("import gdb");
   PyRun_SimpleString ("gdb.pretty_printers = []");
 
-  observer_attach_new_objfile (gdbpy_new_objfile);
-
   gdbpy_to_string_cst = PyString_FromString ("to_string");
   gdbpy_children_cst = PyString_FromString ("children");
   gdbpy_display_hint_cst = PyString_FromString ("display_hint");
Index: testsuite/gdb.python/py-section-script.c
===================================================================
RCS file: testsuite/gdb.python/py-section-script.c
diff -N testsuite/gdb.python/py-section-script.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-section-script.c	16 Apr 2010 05:54:35 -0000
@@ -0,0 +1,52 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2010 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/>.  */
+
+/* Put the path to the pretty-printer script in .debug_gdb_scripts so
+   gdb will automagically loaded it.  */
+
+#define DEFINE_GDB_SCRIPT(script_name) \
+  asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
+.byte 1\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+
+DEFINE_GDB_SCRIPT ("py-section-script.py")
+
+struct ss
+{
+  int a;
+  int b;
+};
+
+void
+init_ss (struct ss *s, int a, int b)
+{
+  s->a = a;
+  s->b = b;
+}
+
+int
+main ()
+{
+  struct ss ss;
+
+  init_ss (&ss, 1, 2);
+
+  return 0;      /* break to inspect struct and union */
+}
Index: testsuite/gdb.python/py-section-script.exp
===================================================================
RCS file: testsuite/gdb.python/py-section-script.exp
diff -N testsuite/gdb.python/py-section-script.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-section-script.exp	16 Apr 2010 05:54:35 -0000
@@ -0,0 +1,65 @@
+# Copyright (C) 2010 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/>.
+
+# This file is part of the GDB testsuite.  It tests automagic loading of
+# scripts specified in the .debug_gdb_scripts section.
+
+# This test can only be run on targets which support ELF and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+    && ![istarget *-*-gnu*]
+    && ![istarget *-*-elf*]
+    && ![istarget *-*-openbsd*]
+    && ![istarget arm-*-eabi*]
+    && ![istarget powerpc-*-eabi*]} {
+    verbose "Skipping py-section-script.exp because of lack of support."
+    return
+}
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set testfile "py-section-script"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+# Make this available to gdb before the program starts, it is
+# automagically loaded by gdb.
+set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] {
+    perror "couldn't run to main"
+    return
+}
+
+gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
+    ".*Breakpoint.*"
+gdb_test "continue" ".*Breakpoint.*"
+
+gdb_test "print ss" " = a=<1> b=<2>"
+
+remote_file host delete ${remote_python_file}
Index: testsuite/gdb.python/py-section-script.py
===================================================================
RCS file: testsuite/gdb.python/py-section-script.py
diff -N testsuite/gdb.python/py-section-script.py
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-section-script.py	16 Apr 2010 05:54:35 -0000
@@ -0,0 +1,63 @@
+# Copyright (C) 2010 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/>.
+
+# This file is part of the GDB testsuite.
+
+import re
+
+class pp_ss:
+    def __init__(self, val):
+        self.val = val
+
+    def to_string(self):
+        return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
+
+def lookup_function (val):
+    "Look-up and return a pretty-printer that can print val."
+
+    # Get the type.
+    type = val.type
+
+    # If it points to a reference, get the reference.
+    if type.code == gdb.TYPE_CODE_REF:
+        type = type.target ()
+
+    # Get the unqualified type, stripped of typedefs.
+    type = type.unqualified ().strip_typedefs ()
+
+    # Get the type name.    
+    typename = type.tag
+
+    if typename == None:
+        return None
+
+    # Iterate over local dictionary of types to determine
+    # if a printer is registered for that type.  Return an
+    # instantiation of the printer if found.
+    for function in pretty_printers_dict:
+        if function.match (typename):
+            return pretty_printers_dict[function] (val)
+        
+    # Cannot find a pretty printer.  Return None.
+
+    return None
+
+def register_pretty_printers ():
+    pretty_printers_dict[re.compile ('^ss$')]  = pp_ss
+
+pretty_printers_dict = {}
+
+register_pretty_printers ()
+gdb.current_progspace().pretty_printers.append (lookup_function)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-16  7:06 [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section Doug Evans
@ 2010-04-16  9:38 ` Eli Zaretskii
  2010-04-16 18:06   ` Doug Evans
  2010-04-20 19:13 ` Tom Tromey
  1 sibling, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2010-04-16  9:38 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

> Date: Fri, 16 Apr 2010 00:05:40 -0700 (PDT)
> From: dje@google.com (Doug Evans)
> 
> This patch adds support for auto-loading scripts mentioned in
> section .debug_gdb_scripts.

Thanks.  I reviewed the documentation part of the patch.  There's also
a single comment to the code part.

> I moved the Auto-loading section of the docs out of the Python API section
> because I like it better that way, and because it solves a technical
> problem: there's no @subsubsubsection. :-)

The existing Python Auto-loading section is not too long, so how about
simply adding the description of this new feature to that section?  I
think ripping it out of "Python API" is not a good idea.

Btw, is this auto-loading feature supposed to be used only for Python
scripts, or does it support scripts written in the GDB scripting
language as well?  If the former, I think we should use "Python
scripts" more often than we do now, to avoid duping the user into
thinking otherwise.

> +** GDB now looks for scripts to auto-load in the .debug_gdb_scripts section.

This is rather cryptic, especially since this section is our own
invention.  How about this text instead:

  ** GDB now looks for names of Python scripts to auto-load in a
  special section named `.debug_gdb_scripts', in addition to looking
  for a OBJFILE-gdb.py script when OBJFILE is read by the debugger.

> +When a new object file is read (for example, due to the @code{file}
> +command, or because the inferior has loaded a shared library),
> +@value{GDBN} will look for support scripts in up to two ways:
                                              ^^^^^^^^^^^^^^^^^
I suggest "in several ways", because 2 is just what we currently
support, and we may extend that to more ways in the future.

> +@file{@var{objfile}-gdb.py} and @file{.debug_gdb_scripts} section.

`.debug_gdb_scripts' is a name of a section, not a file name, so it
should have the @code markup (here and elsewhere).

> +The auto-loading feature is useful for supplying application-specific
> +debugging commands and scripts.

Application-specific or "specific to an objfile"?  I think it's the
latter, because the former is adequately supported by a .gdbinit file
in the source tree.

> +When reading an auto-loaded file, @value{GDBN} sets the ``current
> +objfile''.  This is available via the @code{gdb.current_objfile}
> +function (@pxref{Objfiles In Python}).  This can be useful for
> +registering objfile-specific pretty-printers.

I think this paragraph should be moved to after you describe the
"maint set python auto-load" commands, because it's a minor aspect of
the features.

In addition, please use @dfn{current objfile} instead of the explicit
quotes, since you are introducing new terminology here.

Btw, why are these "maint" commands?  Aren't they useful to Joe Random
Hacker?

> +@node @file{@var{objfile}-gdb.py} file

Using @-commands in node names is a no-no, see the node "Node Line
Requirements" in the Texinfo manual.

> +@subsubsection @file{@var{objfile}-gdb.py} file

Chapter, section, and subsubsection names should follow the English
grammar (node names are exempt from this requirement), so please use
"The @file{@var{objfile}-gdb.py} file" instead (assuming you leave
this as a separate node, which I advise against).

> +If this file does not exist, and if the parameter
> +@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
> +then @value{GDBN} will use for its each separated directory component
> +@code{component} the file named @file{@code{component}/@var{real-name}}, where
> +@var{real-name} is the object file's real name, as described above.

I know you just copied this from the original text, but this is
confusingly complicated.  How about this rewording:

  If this file does not exist, and if the parameter
  @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
  then @value{GDBN} will look for the file in that directory and in
  all of its parents.

Btw, what does the text mean when it says "by ensuring that the file
name is absolute"?  Is this a requirement to the form of OBJFILE as it
is recorded in the binary?  Or does it mean GDB converts it to an
absolute file name if it is not?  In the former case, I presume that
@var{real-name} in the original text corresponds to the basename of
the script's name, not to its full absolute file name; is that
correct?  If the latter, then what does GDB do if the file name is
_not_ absolute?

> +Finally, if this file does not exist, then @value{GDBN} will look for
> +a file named @file{@var{data-directory}/python/auto-load/@var{real-name}}, where
> +@var{data-directory} is @value{GDBN}'s data directory (available via
> +@code{show data-directory}, @pxref{Data Files}),

Doesn't @pxref produce a capitalized "See" for this @pxref?  If so,
please use "see @ref" instead, or move "available via ..." part out of
the parentheses.

>                                                    and @var{real-name}
> +is the object file's real name, as described above.

Again, what about the leading directories in @var{real-name}?

> +So, your @samp{-gdb.py} file should take care to ensure that it may be
> +evaluated multiple times without error.

  So your @samp{-gdb.py} file should take care to ensure that, if it
  is evaluated multiple times, it does that without errors.

Or, better yet

  So your @file{-gdb.py} file should be careful to avoid errors if it
  is evaluated more than once.

> +@node @file{.debug_gdb_scripts} section
> +@subsubsection @file{.debug_gdb_scripts} section

Again, don't use @-commands in node names and use "The" in the
subsubsection name.

> +@cindex .debug_gdb_scripts section

Please give `.debug_gdb_scripts' a @code markup here (there's no
problem doing that in @cindex entries, which by default are typeset in
normal Roman typeface, unlike @findex etc.).

> +For systems using the ELF file format, and other formats supporting
> +multiple sections,

It would be good to state which platforms support multiple sections.
(I think all modern platforms do, in native debugging, but maybe I'm
wrong.)  The reader should not be required to be an expert in binary
formats, in order to understand whether this can be used on her
platform.

>                      when @value{GDBN} loads an @var{objfile}
> +it will look for scripts in the @file{.debug_gdb_scripts} section
> +when an objfile is loaded.
> +This section contains a list of names of scripts to load.

  when @value{GDBN} loads a new object file @var{objfile}, it will
  look for a special section named @samp{.debug_gdb_scripts}.  If this
  section exists, its contents should be a string specifying the name
  of the script file to load.

IOW, first say that GDB look for the section, then what its contents
are, and only then that the specified file will be auto-loaded.

> +File names are recorded instead of the file's contents so that
> +the user doesn't have to relink if a script changes,
> +and so that the plethora of random scripts are better managed,

If this is important, it should be at most in a @footnote.  We don't
generally explain our design decisions in the user manual.

> +The scripts are searched for first in the current directory, and then
> +in the source search path

  @value{GDBN} will look for the specified script file first in the
  current directory and then along the source search path

IOW, avoid unnecessary passive tense.

> +with the exception that @file{$cdir} is not searched, the compilation
> +directory is not relevant to scripts.

  except that @file{$cdir} is not searched, since the compilation
  directory is not relevant to scripts.

> +@example
> +#define DEFINE_GDB_SCRIPT(script_name) \
> +  asm("\
> +.pushsection \".debug_gdb_scripts\", \"MS\",@@progbits,1\n\
> +.byte 1\n\
> +.asciz \"" script_name "\"\n\
> +.popsection \n\
> +");
> +@end example

I'm far from being an expert on inline assembly, but doesn't the
".asciz" line have too many quotes, the script_name argument being
itself in quotes?

> +Then one can reference the macro in a header or source file like this:

Please put @noindent before this line, because it does not start a new
paragraph.  It is an explanation for the @example.

> +@example
> +DEFINE_GDB_SCRIPT ("my-app-scripts.py")
> +@end example

We should tell if the file name can be absolute, or whether it can
include any leading directories.  Btw, does the format of sections
impose any limitations on characters that can appear in this file
name?  If it does, we should state them.

> +Unlike loading of @file{@var{objfile}-gdb.py} scripts,
> +@value{GDBN} keeps track of scripts loaded this way.
> +If the reference to the script is coming from a header file,
> +the script can be referenced by multiple shared libraries.
> +As an optimization to prevent loading the script 100's or even 1000's
> +of times, @value{GDBN} will only auto-load a script once in each
> +program space.
> +However, you should still write your scripts to ensure
> +that it may be evaluated multiple times without error.

The last sentence means, IMO, that this paragraph should be removed.
The user should not need to think differently about the script
depending on how it is loaded, because it's quite reasonable to expect
the same script to be loaded using both methods in the same
application.  This text just adds confusion, IMO.

> +@node Which flavor to choose?
> +@subsubsection Which flavor to choose?
> +
> +Given the two ways of auto-loading scripts, it might not always be clear
> +which one to choose.  This section provides some guidance.

Btw, WIBNI the places where GDB searches for the two kinds of
auto-loaded scripts were not as dissimilar as they are now?  Why do we
need them to be so different?  After all, there's a reasonable chance
that both these methods will be used in the same project, so why force
the users to spread the same scripts in several different places?

> +For publicly installed libraries, e.g. libstdc++, there typically isn't a
                                     ^^^^^^^^^^^^^^
  e.g., @file{libstdc++}

(Note the comma after "e.g.", without it TeX will typeset the "e.g."
as if it ends a sentence.)

> +@kindex maint print section-scripts
> +@cindex info for known .debug_gdb_scripts-loaded scripts
> +@item maint print section-scripts [@var{regexp}]
> +Print a dump of scripts specified in the @file{.debug_gdb_section} section.
> +If @var{regexp} is specified, only print scripts loaded by object files
> +matching @var{regexp}.
> +For each script, this command prints its name as specified in the objfile,
> +and the full path if known.

This should have an @xref to the node where this feature is described.

> +  if (!input && debug_file_directory)
> +    {
> +      /* Also try the same file in the separate debug info directory.  */
> +      debugfile = xmalloc (strlen (filename)
> +			   + strlen (debug_file_directory) + 1);
> +      strcpy (debugfile, debug_file_directory);
> +      /* FILENAME is absolute, so we don't need a "/" here.  */
> +      strcat (debugfile, filename);

What will that last strcat do if FILENAME has a drive letter?

> +      strcpy (debugfile, gdb_datadir);
> +      strcat (debugfile, "/auto-load");
> +      /* FILENAME is absolute, so we don't need a "/" here.  */
> +      strcat (debugfile, filename);

Ditto.

Thanks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-16  9:38 ` Eli Zaretskii
@ 2010-04-16 18:06   ` Doug Evans
  2010-04-16 21:25     ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Doug Evans @ 2010-04-16 18:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On Fri, Apr 16, 2010 at 2:37 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>> Date: Fri, 16 Apr 2010 00:05:40 -0700 (PDT)
>> From: dje@google.com (Doug Evans)
>>
>> This patch adds support for auto-loading scripts mentioned in
>> section .debug_gdb_scripts.
>
> Thanks.  I reviewed the documentation part of the patch.  There's also
> a single comment to the code part.
>
>> I moved the Auto-loading section of the docs out of the Python API section
>> because I like it better that way, and because it solves a technical
>> problem: there's no @subsubsubsection. :-)
>
> The existing Python Auto-loading section is not too long, so how about
> simply adding the description of this new feature to that section?  I
> think ripping it out of "Python API" is not a good idea.

To me the Auto-loading section is not really part of the API.
I can relax my definition of "API" to include auto-loading, but it's a hack.
So I *do* like moving Auto-loading out of "Python API", even though it
does also solve a technical problem.

> Btw, is this auto-loading feature supposed to be used only for Python
> scripts, or does it support scripts written in the GDB scripting
> language as well?  If the former, I think we should use "Python
> scripts" more often than we do now, to avoid duping the user into
> thinking otherwise.

An early version of the patch supported auto-loading gdb scripts in
.debug_gdb_scripts too.
But in the interests of not trying to accomplish too much at once, I
deferred completing it for later.

>> +** GDB now looks for scripts to auto-load in the .debug_gdb_scripts section.
>
> This is rather cryptic, especially since this section is our own
> invention.  How about this text instead:
>
>  ** GDB now looks for names of Python scripts to auto-load in a
>  special section named `.debug_gdb_scripts', in addition to looking
>  for a OBJFILE-gdb.py script when OBJFILE is read by the debugger.

Sure.

>> +When a new object file is read (for example, due to the @code{file}
>> +command, or because the inferior has loaded a shared library),
>> +@value{GDBN} will look for support scripts in up to two ways:
>                                              ^^^^^^^^^^^^^^^^^
> I suggest "in several ways", because 2 is just what we currently
> support, and we may extend that to more ways in the future.

We could just change the text when that happens, but sure.

>> +@file{@var{objfile}-gdb.py} and @file{.debug_gdb_scripts} section.
>
> `.debug_gdb_scripts' is a name of a section, not a file name, so it
> should have the @code markup (here and elsewhere).

thanks

>> +The auto-loading feature is useful for supplying application-specific
>> +debugging commands and scripts.
>
> Application-specific or "specific to an objfile"?  I think it's the
> latter, because the former is adequately supported by a .gdbinit file
> in the source tree.

This text is already present in the current docs.
I don't care whether its "application" or "objfile" though.

>> +When reading an auto-loaded file, @value{GDBN} sets the ``current
>> +objfile''.  This is available via the @code{gdb.current_objfile}
>> +function (@pxref{Objfiles In Python}).  This can be useful for
>> +registering objfile-specific pretty-printers.
>
> I think this paragraph should be moved to after you describe the
> "maint set python auto-load" commands, because it's a minor aspect of
> the features.

I disagree, but ok.

> In addition, please use @dfn{current objfile} instead of the explicit
> quotes, since you are introducing new terminology here.

cut-n-paste from existing text, but sure.

> Btw, why are these "maint" commands?  Aren't they useful to Joe Random
> Hacker?

Good question.  I think they shouldn't maint commands, but it's a
separate question to this patch.
[For reference sake, an early version of this patch had separate
options for enabling -gdb.py vs .debug_gdb_scripts.  It felt useful
enough, but wasn't important enough to try to get it into the tree.]

>> +@node @file{@var{objfile}-gdb.py} file
>
> Using @-commands in node names is a no-no, see the node "Node Line
> Requirements" in the Texinfo manual.

Ah.

>> +@subsubsection @file{@var{objfile}-gdb.py} file
>
> Chapter, section, and subsubsection names should follow the English
> grammar (node names are exempt from this requirement), so please use
> "The @file{@var{objfile}-gdb.py} file" instead (assuming you leave
> this as a separate node, which I advise against).

Thanks.

>> +If this file does not exist, and if the parameter
>> +@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
>> +then @value{GDBN} will use for its each separated directory component
>> +@code{component} the file named @file{@code{component}/@var{real-name}}, where
>> +@var{real-name} is the object file's real name, as described above.
>
> I know you just copied this from the original text, but this is
> confusingly complicated.  How about this rewording:
>
>  If this file does not exist, and if the parameter
>  @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
>  then @value{GDBN} will look for the file in that directory and in
>  all of its parents.

"all of its parents"?
I *think* that comment is referring to the fact that
"debug-file-directory" contains a colon-separated list of directories
to try (bad option name of course - presumably kept for backward
compatibility).

> Btw, what does the text mean when it says "by ensuring that the file
> name is absolute"?  Is this a requirement to the form of OBJFILE as it
> is recorded in the binary?  Or does it mean GDB converts it to an
> absolute file name if it is not?  In the former case, I presume that
> @var{real-name} in the original text corresponds to the basename of
> the script's name, not to its full absolute file name; is that
> correct?  If the latter, then what does GDB do if the file name is
> _not_ absolute?

I think it was written that way to express the fact that we
(presumably) want to avoid ambiguities in the lookup of the file in,
for example, /usr/lib/debug.  We want to look up one path regardless
of whatever symlinks appear in the path that gdb is using.
E.g. if OBJFILE is /usr/lib/foo.so, and foo.so is a symlink to
/usr/lib/bar.so, we want to look up /usr/lib/debug/usr/lib/bar.so.
I think.

AIUI, real-name will always be absolute, it's the complete path of the objfile.

>
>> +Finally, if this file does not exist, then @value{GDBN} will look for
>> +a file named @file{@var{data-directory}/python/auto-load/@var{real-name}}, where
>> +@var{data-directory} is @value{GDBN}'s data directory (available via
>> +@code{show data-directory}, @pxref{Data Files}),
>
> Doesn't @pxref produce a capitalized "See" for this @pxref?  If so,
> please use "see @ref" instead, or move "available via ..." part out of
> the parentheses.

I guess makeinfo is smart enough to decide because I see lowercase in gdb.info.

>>                                                    and @var{real-name}
>> +is the object file's real name, as described above.
>
> Again, what about the leading directories in @var{real-name}?

I think real-name means the canonicalized full path name.

>> +So, your @samp{-gdb.py} file should take care to ensure that it may be
>> +evaluated multiple times without error.
>
>  So your @samp{-gdb.py} file should take care to ensure that, if it
>  is evaluated multiple times, it does that without errors.
>
> Or, better yet
>
>  So your @file{-gdb.py} file should be careful to avoid errors if it
>  is evaluated more than once.

ok.

>> +@node @file{.debug_gdb_scripts} section
>> +@subsubsection @file{.debug_gdb_scripts} section
>
> Again, don't use @-commands in node names and use "The" in the
> subsubsection name.

k

>> +@cindex .debug_gdb_scripts section
>
> Please give `.debug_gdb_scripts' a @code markup here (there's no
> problem doing that in @cindex entries, which by default are typeset in
> normal Roman typeface, unlike @findex etc.).

sure

>> +For systems using the ELF file format, and other formats supporting
>> +multiple sections,
>
> It would be good to state which platforms support multiple sections.
> (I think all modern platforms do, in native debugging, but maybe I'm
> wrong.)  The reader should not be required to be an expert in binary
> formats, in order to understand whether this can be used on her
> platform.

Being an expert isn't required, but I understand the point.
OTOH, I'm not familiar with all formats, only the ones I've used.
Mentioning ELF and COFF I guess should suffice I think.

>>                      when @value{GDBN} loads an @var{objfile}
>> +it will look for scripts in the @file{.debug_gdb_scripts} section
>> +when an objfile is loaded.
>> +This section contains a list of names of scripts to load.
>
>  when @value{GDBN} loads a new object file @var{objfile}, it will
>  look for a special section named @samp{.debug_gdb_scripts}.  If this
>  section exists, its contents should be a string specifying the name
>  of the script file to load.

I didn't want to go into implementation details of what
.debug_gdb_scripts contains here, and "should be a string" feels more
technical than "list of names of scripts" to load. :-) But whatever.
The actual format is slightly more detailed than just a string.

> IOW, first say that GDB look for the section, then what its contents
> are, and only then that the specified file will be auto-loaded.
>
>> +File names are recorded instead of the file's contents so that
>> +the user doesn't have to relink if a script changes,
>> +and so that the plethora of random scripts are better managed,
>
> If this is important, it should be at most in a @footnote.  We don't
> generally explain our design decisions in the user manual.

ok

>> +The scripts are searched for first in the current directory, and then
>> +in the source search path
>
>  @value{GDBN} will look for the specified script file first in the
>  current directory and then along the source search path
>
> IOW, avoid unnecessary passive tense.
>
>> +with the exception that @file{$cdir} is not searched, the compilation
>> +directory is not relevant to scripts.
>
>  except that @file{$cdir} is not searched, since the compilation
>  directory is not relevant to scripts.

ok

>> +@example
>> +#define DEFINE_GDB_SCRIPT(script_name) \
>> +  asm("\
>> +.pushsection \".debug_gdb_scripts\", \"MS\",@@progbits,1\n\
>> +.byte 1\n\
>> +.asciz \"" script_name "\"\n\
>> +.popsection \n\
>> +");
>> +@end example
>
> I'm far from being an expert on inline assembly, but doesn't the
> ".asciz" line have too many quotes, the script_name argument being
> itself in quotes?

No, it's correct.  It's that way to make the transition from
concatenated C strings "foo" "bar" "baz" to what the assembler needs
to see: foo "bar" baz.

>> +Then one can reference the macro in a header or source file like this:
>
> Please put @noindent before this line, because it does not start a new
> paragraph.  It is an explanation for the @example.

Ah.

>> +@example
>> +DEFINE_GDB_SCRIPT ("my-app-scripts.py")
>> +@end example
>
> We should tell if the file name can be absolute, or whether it can
> include any leading directories.  Btw, does the format of sections
> impose any limitations on characters that can appear in this file
> name?  If it does, we should state them.

The file name can contain drive letters, directories, be relative or absolute.
The only restriction (that I can think of) is that it can't contain nul '\0'.

>> +Unlike loading of @file{@var{objfile}-gdb.py} scripts,
>> +@value{GDBN} keeps track of scripts loaded this way.
>> +If the reference to the script is coming from a header file,
>> +the script can be referenced by multiple shared libraries.
>> +As an optimization to prevent loading the script 100's or even 1000's
>> +of times, @value{GDBN} will only auto-load a script once in each
>> +program space.
>> +However, you should still write your scripts to ensure
>> +that it may be evaluated multiple times without error.
>
> The last sentence means, IMO, that this paragraph should be removed.
> The user should not need to think differently about the script
> depending on how it is loaded, because it's quite reasonable to expect
> the same script to be loaded using both methods in the same
> application.  This text just adds confusion, IMO.

"works for me"

>> +@node Which flavor to choose?
>> +@subsubsection Which flavor to choose?
>> +
>> +Given the two ways of auto-loading scripts, it might not always be clear
>> +which one to choose.  This section provides some guidance.
>
> Btw, WIBNI the places where GDB searches for the two kinds of
> auto-loaded scripts were not as dissimilar as they are now?  Why do we
> need them to be so different?  After all, there's a reasonable chance
> that both these methods will be used in the same project, so why force
> the users to spread the same scripts in several different places?

I don't disagree but there *is* a distinction between the two flavors.
For example, it doesn't make much sense to search for OBJFILE-gdb.py
scripts in the source tree.

>> +For publicly installed libraries, e.g. libstdc++, there typically isn't a
>                                     ^^^^^^^^^^^^^^
>  e.g., @file{libstdc++}
>
> (Note the comma after "e.g.", without it TeX will typeset the "e.g."
> as if it ends a sentence.)

Right.

>> +@kindex maint print section-scripts
>> +@cindex info for known .debug_gdb_scripts-loaded scripts
>> +@item maint print section-scripts [@var{regexp}]
>> +Print a dump of scripts specified in the @file{.debug_gdb_section} section.
>> +If @var{regexp} is specified, only print scripts loaded by object files
>> +matching @var{regexp}.
>> +For each script, this command prints its name as specified in the objfile,
>> +and the full path if known.
>
> This should have an @xref to the node where this feature is described.

Sure.

>> +  if (!input && debug_file_directory)
>> +    {
>> +      /* Also try the same file in the separate debug info directory.  */
>> +      debugfile = xmalloc (strlen (filename)
>> +                        + strlen (debug_file_directory) + 1);
>> +      strcpy (debugfile, debug_file_directory);
>> +      /* FILENAME is absolute, so we don't need a "/" here.  */
>> +      strcat (debugfile, filename);
>
> What will that last strcat do if FILENAME has a drive letter?
>
>> +      strcpy (debugfile, gdb_datadir);
>> +      strcat (debugfile, "/auto-load");
>> +      /* FILENAME is absolute, so we don't need a "/" here.  */
>> +      strcat (debugfile, filename);
>
> Ditto.

This is cut-n-pasted from the existing code to auto-load -gdb.py
scripts.  I don't know if filename can have a drive letter here.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-16 18:06   ` Doug Evans
@ 2010-04-16 21:25     ` Eli Zaretskii
  2010-04-20 21:45       ` Doug Evans
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2010-04-16 21:25 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

> Date: Fri, 16 Apr 2010 11:06:44 -0700
> From: Doug Evans <dje@google.com>
> Cc: gdb-patches@sourceware.org
> 
> > The existing Python Auto-loading section is not too long, so how about
> > simply adding the description of this new feature to that section?  I
> > think ripping it out of "Python API" is not a good idea.
> 
> To me the Auto-loading section is not really part of the API.

Well, yes, but this feature is currently specific to Python, so why
move it out of the Python chapter?

> >> +If this file does not exist, and if the parameter
> >> +@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
> >> +then @value{GDBN} will use for its each separated directory component
> >> +@code{component} the file named @file{@code{component}/@var{real-name}}, where
> >> +@var{real-name} is the object file's real name, as described above.
> >
> > I know you just copied this from the original text, but this is
> > confusingly complicated.  How about this rewording:
> >
> >  If this file does not exist, and if the parameter
> >  @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
> >  then @value{GDBN} will look for the file in that directory and in
> >  all of its parents.
> 
> "all of its parents"?
> I *think* that comment is referring to the fact that
> "debug-file-directory" contains a colon-separated list of directories
> to try

Right you are.  So

  If this file does not exist, and if the parameter
  @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
  then @value{GDBN} will look for the file in all of the directories
  mentioned in the value of @code{debug-file-directory}.

> bad option name of course

A terrible name.

> >> +  if (!input && debug_file_directory)
> >> +    {
> >> +      /* Also try the same file in the separate debug info directory.  */
> >> +      debugfile = xmalloc (strlen (filename)
> >> +                        + strlen (debug_file_directory) + 1);
> >> +      strcpy (debugfile, debug_file_directory);
> >> +      /* FILENAME is absolute, so we don't need a "/" here.  */
> >> +      strcat (debugfile, filename);
> >
> > What will that last strcat do if FILENAME has a drive letter?
> >
> >> +      strcpy (debugfile, gdb_datadir);
> >> +      strcat (debugfile, "/auto-load");
> >> +      /* FILENAME is absolute, so we don't need a "/" here.  */
> >> +      strcat (debugfile, filename);
> >
> > Ditto.
> 
> This is cut-n-pasted from the existing code to auto-load -gdb.py
> scripts.  I don't know if filename can have a drive letter here.

Yes, it can.  It depends how the files were called out in the
compilation command line.

I think we should strip the drive letter and the colon before
concatenating the rest with the leading directory.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-16  7:06 [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section Doug Evans
  2010-04-16  9:38 ` Eli Zaretskii
@ 2010-04-20 19:13 ` Tom Tromey
  2010-04-20 21:38   ` Doug Evans
  1 sibling, 1 reply; 12+ messages in thread
From: Tom Tromey @ 2010-04-20 19:13 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

>>>>> "Doug" == Doug Evans <dje@google.com> writes:

Doug> This patch adds support for auto-loading scripts mentioned in
Doug> section .debug_gdb_scripts.

It seems reasonable to me.  I looked through the patch and didn't see
anything I disagreed with.

I'm curious why these new scripts are attached to the program space and
not just the objfile from which the section came.  But, I don't think it
really matters.

I'm somewhat concerned about security.  I don't know why I didn't think
of this before :-(.  The issue is that either approach can result in
random Python code being loaded into gdb.

One idea for a fix would be to check the script file's ownership and
permissions before reading it.  I think we'd need to allow files to be
owned by the current user or by root in order for this to work nicely in
the distro case.

Tom

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-20 19:13 ` Tom Tromey
@ 2010-04-20 21:38   ` Doug Evans
  0 siblings, 0 replies; 12+ messages in thread
From: Doug Evans @ 2010-04-20 21:38 UTC (permalink / raw)
  To: tromey; +Cc: gdb-patches

On Tue, Apr 20, 2010 at 12:13 PM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Doug" == Doug Evans <dje@google.com> writes:
>
> Doug> This patch adds support for auto-loading scripts mentioned in
> Doug> section .debug_gdb_scripts.
>
> It seems reasonable to me.  I looked through the patch and didn't see
> anything I disagreed with.

Great.

> I'm curious why these new scripts are attached to the program space and
> not just the objfile from which the section came.  But, I don't think it
> really matters.

In the case of multiple scripts each being defined in multiple
objfiles, I wanted to minimize the accumulated number of scripts one
had to deal with (there could be *lots* of duplicates).  Once one does
that one can't attach scripts to objfiles because one doesn't
necessarily want the script to go away if the objfile goes away.  I
had a patch that reference counted them, but it seemed excessive for
now so I abandoned it.

> I'm somewhat concerned about security.  I don't know why I didn't think
> of this before :-(.  The issue is that either approach can result in
> random Python code being loaded into gdb.
>
> One idea for a fix would be to check the script file's ownership and
> permissions before reading it.  I think we'd need to allow files to be
> owned by the current user or by root in order for this to work nicely in
> the distro case.

That's probably the right default  choice, but I can imagine wanting
more flexibility.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-16 21:25     ` Eli Zaretskii
@ 2010-04-20 21:45       ` Doug Evans
  2010-04-21 19:23         ` Doug Evans
  0 siblings, 1 reply; 12+ messages in thread
From: Doug Evans @ 2010-04-20 21:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On Fri, Apr 16, 2010 at 2:25 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>> Date: Fri, 16 Apr 2010 11:06:44 -0700
>> From: Doug Evans <dje@google.com>
>> Cc: gdb-patches@sourceware.org
>>
>> > The existing Python Auto-loading section is not too long, so how about
>> > simply adding the description of this new feature to that section?  I
>> > think ripping it out of "Python API" is not a good idea.
>>
>> To me the Auto-loading section is not really part of the API.
>
> Well, yes, but this feature is currently specific to Python, so why
> move it out of the Python chapter?

I moved it from the "Python API" node to the "Python" node.
It's up one level but it's still in the Python chapter.

>> >> +  if (!input && debug_file_directory)
>> >> +    {
>> >> +      /* Also try the same file in the separate debug info directory.  */
>> >> +      debugfile = xmalloc (strlen (filename)
>> >> +                        + strlen (debug_file_directory) + 1);
>> >> +      strcpy (debugfile, debug_file_directory);
>> >> +      /* FILENAME is absolute, so we don't need a "/" here.  */
>> >> +      strcat (debugfile, filename);
>> >
>> > What will that last strcat do if FILENAME has a drive letter?
>> >
>> >> +      strcpy (debugfile, gdb_datadir);
>> >> +      strcat (debugfile, "/auto-load");
>> >> +      /* FILENAME is absolute, so we don't need a "/" here.  */
>> >> +      strcat (debugfile, filename);
>> >
>> > Ditto.
>>
>> This is cut-n-pasted from the existing code to auto-load -gdb.py
>> scripts.  I don't know if filename can have a drive letter here.
>
> Yes, it can.  It depends how the files were called out in the
> compilation command line.
>
> I think we should strip the drive letter and the colon before
> concatenating the rest with the leading directory.

Sure.
I'll do that.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-20 21:45       ` Doug Evans
@ 2010-04-21 19:23         ` Doug Evans
  2010-04-21 20:39           ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Doug Evans @ 2010-04-21 19:23 UTC (permalink / raw)
  To: Eli Zaretskii, Tom Tromey, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1805 bytes --]

I've applied the requested doc changes, except that Auto-loading is
still moved up one level, moved from node Python API to node Python.

I'm going to defer fixing DOS path support to a separate patch.  This
is a bug in the existing code (all this patch does is move said code
from one file to another), and I don't want to overload this patch.

If there are no objections I will check this in tomorrow.

2010-04-21  Doug Evans  <dje@google.com>

	Add support for auto-loading scripts from .debug_gdb_scripts section.
	* NEWS: Add entry for .debug_gdb_scripts.
	* Makefile.in SUBDIR_PYTHON_OBS): Add py-auto-load.o.
	(SUBDIR_PYTHON_SRCS): Add py-auto-load.c.
	(py-auto-load.o): New rule.
	* cli/cli-cmds.c (find_and_open_script): Make externally visible.
	* cli/cli-cmds.h (find_and_open_script): Update prototype.
	* python/py-auto-load.c: New file.
	* python/python-internal.h: #include <stdio.h>.
	(set_python_list, show_python_list): Declare.
	(gdbpy_initialize_auto_load): Declare.
	(source_python_script_for_objfile): Declare.
	* python/python.c: Remove #include of observer.h.
	(gdbpy_auto_load): Moved to py-auto-load.c.
	(GDBPY_AUTO_FILENAME): Ditto.
	(gdbpy_new_objfile): Delete.
	(source_python_script_for_objfile): New function.
	(set_python_list, show_python_list): Make externally visible.
	(_initialize_python): Move "auto-load" command to py-auto-load.c
	and observer_attach_new_objfile to py-auto-load.c.

	doc/
	* gdb.texinfo (Python): Move Auto-loading section here ...
	(Python API): from here.
	(Auto-loading): Add docs for .debug_gdb_scripts auto-loaded scripts.
	(Maintenance Commands): Add docs for "maint print section-scripts".

	testsuite/
	* gdb.python/py-section-script.c: New file.
	* gdb.python/py-section-script.exp: New file.
	* gdb.python/py-section-script.py: New file.

[-- Attachment #2: gdb-100421-debug-gdb-scripts-2.patch.txt --]
[-- Type: text/plain, Size: 41953 bytes --]

2010-04-21  Doug Evans  <dje@google.com>

	Add support for auto-loading scripts from .debug_gdb_scripts section.
	* NEWS: Add entry for .debug_gdb_scripts.
	* Makefile.in SUBDIR_PYTHON_OBS): Add py-auto-load.o.
	(SUBDIR_PYTHON_SRCS): Add py-auto-load.c.
	(py-auto-load.o): New rule.
	* cli/cli-cmds.c (find_and_open_script): Make externally visible.
	* cli/cli-cmds.h (find_and_open_script): Update prototype.
	* python/py-auto-load.c: New file.
	* python/python-internal.h: #include <stdio.h>.
	(set_python_list, show_python_list): Declare.
	(gdbpy_initialize_auto_load): Declare.
	(source_python_script_for_objfile): Declare.
	* python/python.c: Remove #include of observer.h.
	(gdbpy_auto_load): Moved to py-auto-load.c.
	(GDBPY_AUTO_FILENAME): Ditto.
	(gdbpy_new_objfile): Delete.
	(source_python_script_for_objfile): New function.
	(set_python_list, show_python_list): Make externally visible.
	(_initialize_python): Move "auto-load" command to py-auto-load.c
	and observer_attach_new_objfile to py-auto-load.c.

	doc/
	* gdb.texinfo (Python): Move Auto-loading section here ...
	(Python API): from here.
	(Auto-loading): Add docs for .debug_gdb_scripts auto-loaded scripts.
	(Maintenance Commands): Add docs for "maint print section-scripts".

	testsuite/
	* gdb.python/py-section-script.c: New file.
	* gdb.python/py-section-script.exp: New file.
	* gdb.python/py-section-script.py: New file.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1118
diff -u -p -r1.1118 Makefile.in
--- Makefile.in	15 Apr 2010 19:54:12 -0000	1.1118
+++ Makefile.in	21 Apr 2010 19:07:16 -0000
@@ -267,6 +267,7 @@ SUBDIR_TUI_CFLAGS= \
 #
 SUBDIR_PYTHON_OBS = \
 	python.o \
+	py-auto-load.o \
 	py-block.o \
 	py-breakpoint.o \
 	py-cmd.o \
@@ -283,6 +284,7 @@ SUBDIR_PYTHON_OBS = \
 	py-value.o
 SUBDIR_PYTHON_SRCS = \
 	python/python.c \
+	python/py-auto-load.c \
 	python/py-block.c \
 	python/py-breakpoint.c \
 	python/py-cmd.c \
@@ -1986,6 +1988,10 @@ python.o: $(srcdir)/python/python.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
 	$(POSTCOMPILE)
 
+py-auto-load.o: $(srcdir)/python/py-auto-load.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-auto-load.c
+	$(POSTCOMPILE)
+
 py-block.o: $(srcdir)/python/py-block.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-block.c
 	$(POSTCOMPILE)
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.373
diff -u -p -r1.373 NEWS
--- NEWS	19 Apr 2010 00:48:43 -0000	1.373
+++ NEWS	21 Apr 2010 19:07:17 -0000
@@ -67,6 +67,10 @@ is now deprecated.
 
 ** Pretty-printers are now also looked up in the current program space.
 
+** GDB now looks for names of Python scripts to auto-load in a
+   special section named `.debug_gdb_scripts', in addition to looking
+   for a OBJFILE-gdb.py script when OBJFILE is read by the debugger.
+
 * Tracepoint actions were unified with breakpoint commands. In particular,
 there are no longer differences in "info break" output for breakpoints and
 tracepoints and the "commands" command can be used for both tracepoints and
Index: cli/cli-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-cmds.c,v
retrieving revision 1.101
diff -u -p -r1.101 cli-cmds.c
--- cli/cli-cmds.c	15 Apr 2010 17:45:52 -0000	1.101
+++ cli/cli-cmds.c	21 Apr 2010 19:07:17 -0000
@@ -483,7 +483,7 @@ Script filename extension recognition is
    NOTE: This calls openp which uses xfullpath to compute the full path
    instead of gdb_realpath.  Symbolic links are not resolved.  */
 
-static int
+int
 find_and_open_script (const char *script_file, int search_path,
 		      FILE **streamp, char **full_pathp)
 {
Index: cli/cli-cmds.h
===================================================================
RCS file: /cvs/src/src/gdb/cli/cli-cmds.h,v
retrieving revision 1.14
diff -u -p -r1.14 cli-cmds.h
--- cli/cli-cmds.h	1 Jan 2010 07:31:46 -0000	1.14
+++ cli/cli-cmds.h	21 Apr 2010 19:07:17 -0000
@@ -123,6 +123,11 @@ extern void quit_command (char *, int);
 
 extern void source_script (char *, int);
 
+/* Exported to objfiles.c.  */
+
+extern int find_and_open_script (const char *file, int search_path,
+				 FILE **streamp, char **full_path);
+
 /* Used everywhere whenever at least one parameter is required and
   none is specified. */
 
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.708
diff -u -p -r1.708 gdb.texinfo
--- doc/gdb.texinfo	19 Apr 2010 00:48:44 -0000	1.708
+++ doc/gdb.texinfo	21 Apr 2010 19:07:18 -0000
@@ -19685,6 +19685,7 @@ Python programming language}.  This feat
 @menu
 * Python Commands::             Accessing Python from @value{GDBN}.
 * Python API::                  Accessing @value{GDBN} from Python.
+* Auto-loading::                Automatically loading Python code.
 @end menu
 
 @node Python Commands
@@ -19762,7 +19763,6 @@ situation, a Python @code{KeyboardInterr
 @menu
 * Basic Python::                Basic Python Functions.
 * Exception Handling::
-* Auto-loading::                Automatically loading Python code.
 * Values From Inferior::
 * Types In Python::		Python representation of types.
 * Pretty Printing::		Pretty-printing values.
@@ -19908,53 +19908,6 @@ message as its value, and the Python cal
 Python statement closest to where the @value{GDBN} error occured as the
 traceback.
 
-@node Auto-loading
-@subsubsection Auto-loading
-@cindex auto-loading, Python
-
-When a new object file is read (for example, due to the @code{file}
-command, or because the inferior has loaded a shared library),
-@value{GDBN} will look for a file named @file{@var{objfile}-gdb.py},
-where @var{objfile} is the object file's real name, formed by ensuring
-that the file name is absolute, following all symlinks, and resolving
-@code{.} and @code{..}  components.  If this file exists and is
-readable, @value{GDBN} will evaluate it as a Python script.
-
-If this file does not exist, and if the parameter
-@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
-then @value{GDBN} will use for its each separated directory component
-@code{component} the file named @file{@code{component}/@var{real-name}}, where
-@var{real-name} is the object file's real name, as described above.
-
-Finally, if this file does not exist, then @value{GDBN} will look for
-a file named @file{@var{data-directory}/python/auto-load/@var{real-name}}, where
-@var{data-directory} is @value{GDBN}'s data directory (available via
-@code{show data-directory}, @pxref{Data Files}), and @var{real-name}
-is the object file's real name, as described above.
-
-When reading an auto-loaded file, @value{GDBN} sets the ``current
-objfile''.  This is available via the @code{gdb.current_objfile}
-function (@pxref{Objfiles In Python}).  This can be useful for
-registering objfile-specific pretty-printers.
-
-The auto-loading feature is useful for supplying application-specific
-debugging commands and scripts.  You can enable or disable this
-feature, and view its current state.
-
-@table @code
-@kindex maint set python auto-load
-@item maint set python auto-load [yes|no]
-Enable or disable the Python auto-loading feature.
-
-@kindex maint show python auto-load
-@item maint show python auto-load
-Show whether Python auto-loading is enabled or disabled.
-@end table
-
-@value{GDBN} does not track which files it has already auto-loaded.
-So, your @samp{-gdb.py} file should take care to ensure that it may be
-evaluated multiple times without error.
-
 @node Values From Inferior
 @subsubsection Values From Inferior
 @cindex values from inferior, with Python
@@ -21611,6 +21564,163 @@ resolve this to the lazy string's charac
 writable.
 @end defivar
 
+@node Auto-loading
+@subsection Auto-loading
+@cindex auto-loading, Python
+
+When a new object file is read (for example, due to the @code{file}
+command, or because the inferior has loaded a shared library),
+@value{GDBN} will look for Python support scripts in several ways:
+@file{@var{objfile}-gdb.py} and @code{.debug_gdb_scripts} section.
+
+@menu
+* objfile-gdb.py file::         The @file{@var{objfile}-gdb.py} file
+* .debug_gdb_scripts section::  The @code{.debug_gdb_scripts} section
+* Which flavor to choose?::
+@end menu
+
+The auto-loading feature is useful for supplying application-specific
+debugging commands and scripts.
+
+Auto-loading can be enabled or disabled.
+
+@table @code
+@kindex maint set python auto-load
+@item maint set python auto-load [yes|no]
+Enable or disable the Python auto-loading feature.
+
+@kindex maint show python auto-load
+@item maint show python auto-load
+Show whether Python auto-loading is enabled or disabled.
+@end table
+
+When reading an auto-loaded file, @value{GDBN} sets the
+@dfn{current objfile}.  This is available via the @code{gdb.current_objfile}
+function (@pxref{Objfiles In Python}).  This can be useful for
+registering objfile-specific pretty-printers.
+
+@node objfile-gdb.py file
+@subsubsection The @file{@var{objfile}-gdb.py} file
+@cindex @file{@var{objfile}-gdb.py}
+
+When a new object file is read, @value{GDBN} looks for
+a file named @file{@var{objfile}-gdb.py},
+where @var{objfile} is the object file's real name, formed by ensuring
+that the file name is absolute, following all symlinks, and resolving
+@code{.} and @code{..} components.  If this file exists and is
+readable, @value{GDBN} will evaluate it as a Python script.
+
+If this file does not exist, and if the parameter
+@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
+then @value{GDBN} will use for its each separated directory component
+@code{component} the file named @file{@code{component}/@var{real-name}}, where
+@var{real-name} is the object file's real name, as described above.
+
+Finally, if this file does not exist, then @value{GDBN} will look for
+a file named @file{@var{data-directory}/python/auto-load/@var{real-name}}, where
+@var{data-directory} is @value{GDBN}'s data directory (available via
+@code{show data-directory}, @pxref{Data Files}), and @var{real-name}
+is the object file's real name, as described above.
+
+@value{GDBN} does not track which files it has already auto-loaded this way.
+@value{GDBN} will load the associated script every time the corresponding
+@var{objfile} is opened.
+So your @file{-gdb.py} file should be careful to avoid errors if it
+is evaluated more than once.
+
+@node .debug_gdb_scripts section
+@subsubsection The @code{.debug_gdb_scripts} section
+@cindex @code{.debug_gdb_scripts} section
+
+For systems using file formats like ELF and COFF,
+when @value{GDBN} loads a new object file
+it will look for a special section named @samp{.debug_gdb_scripts}.
+If this section exists, its contents is a list of names of scripts to load.
+
+@value{GDBN} will look for each specified script file first in the
+current directory and then along the source search path
+(@pxref{Source Path, ,Specifying Source Directories}),
+except that @file{$cdir} is not searched, since the compilation
+directory is not relevant to scripts.
+
+Entries can be placed in section @code{.debug_gdb_scripts} with,
+for example, this GCC macro:
+
+@example
+/* Note: The "MS" section flags are to remote duplicates.  */
+#define DEFINE_GDB_SCRIPT(script_name) \
+  asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@@progbits,1\n\
+.byte 1\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+@end example
+
+@noindent
+Then one can reference the macro in a header or source file like this:
+
+@example
+DEFINE_GDB_SCRIPT ("my-app-scripts.py")
+@end example
+
+The script name may include directories if desired.
+
+If the macro is put in a header, any application or library
+using this header will get a reference to the specified script.
+
+@node Which flavor to choose?
+@subsubsection Which flavor to choose?
+
+Given the multiple ways of auto-loading Python scripts, it might not always
+be clear which one to choose.  This section provides some guidance.
+
+Benefits of the @file{-gdb.py} way:
+
+@itemize @bullet
+@item
+Can be used with file formats that don't support multiple sections.
+
+@item
+Ease of finding scripts for public libraries.
+
+Scripts specified in the @code{.debug_gdb_scripts} section are searched for
+in the source search path.
+For publicly installed libraries, e.g., @file{libstdc++}, there typically
+isn't a source directory in which to find the script.
+
+@item
+Doesn't require source code additions.
+@end itemize
+
+Benefits of the @code{.debug_gdb_scripts} way:
+
+@itemize @bullet
+@item
+Works with static linking.
+
+Scripts for libraries done the @file{-gdb.py} way require an objfile to
+trigger their loading.  When an application is statically linked the only
+objfile available is the executable, and it is cumbersome to attach all the
+scripts from all the input libraries to the executable's @file{-gdb.py} script.
+
+@item
+Works with classes that are entirely inlined.
+
+Some classes can be entirely inlined, and thus there may not be an associated
+shared library to attach a @file{-gdb.py} script to.
+
+@item
+Scripts needn't be copied out of the source tree.
+
+In some circumstances, apps can be built out of large collections of internal
+libraries, and the build infrastructure necessary to install the
+@file{-gdb.py} scripts in a place where @value{GDBN} can find them is
+cumbersome.  It may be easier to specify the scripts in the
+@code{.debug_gdb_scripts} section as relative paths, and add a path to the
+top of the source tree to the source search path.
+@end itemize
+
 @node Interpreters
 @chapter Command Interpreters
 @cindex command interpreters
@@ -29413,6 +29523,16 @@ Print a dump of all known object files. 
 command prints its name, address in memory, and all of its psymtabs
 and symtabs.
 
+@kindex maint print section-scripts
+@cindex info for known .debug_gdb_scripts-loaded scripts
+@item maint print section-scripts [@var{regexp}]
+Print a dump of scripts specified in the @code{.debug_gdb_section} section.
+If @var{regexp} is specified, only print scripts loaded by object files
+matching @var{regexp}.
+For each script, this command prints its name as specified in the objfile,
+and the full path if known.
+@xref{.debug_gdb_scripts section}.
+
 @kindex maint print statistics
 @cindex bcache statistics
 @item maint print statistics
Index: python/py-auto-load.c
===================================================================
RCS file: python/py-auto-load.c
diff -N python/py-auto-load.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ python/py-auto-load.c	21 Apr 2010 19:07:18 -0000
@@ -0,0 +1,459 @@
+/* GDB routines for supporting auto-loaded scripts.
+
+   Copyright (C) 2010 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/>.  */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "gdb_regex.h"
+#include "top.h"
+#include "exceptions.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "observer.h"
+#include "progspace.h"
+#include "objfiles.h"
+#include "python.h"
+#include "python-internal.h"
+#include "cli/cli-cmds.h"
+
+/* NOTE: It's trivial to also support auto-loading normal gdb scripts.
+   There has yet to be a need so it's not implemented.  */
+
+/* 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"
+
+/* The section to look for scripts (in file formats that support sections).
+   Each entry in this section is a byte of value 1, and then the nul-terminated
+   name of the script.  The script name may include a directory.
+   The leading byte is to allow upward compatible extensions.  */
+#define GDBPY_AUTO_SECTION_NAME ".debug_gdb_scripts"
+
+/* For scripts specified in .debug_gdb_scripts, multiple objfiles may load
+   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
+   loaded this way.  */
+
+struct auto_load_pspace_info
+{
+  /* For each program space we keep track of loaded scripts.  */
+  struct htab *loaded_scripts;
+};
+
+/* Objects of this type are stored in the loaded script hash table.  */
+
+struct loaded_script_entry
+{
+  /* Name as provided by the objfile.  */
+  const char *name;
+  /* Full path name or NULL if script wasn't found (or was otherwise
+     inaccessible).  */
+  const char *full_path;
+};
+
+/* This is true if we should auto-load python code when an objfile is opened,
+   false otherwise.  */
+static int gdbpy_auto_load = 1;
+
+/* Per-program-space data key.  */
+static const struct program_space_data *auto_load_pspace_data;
+
+static void
+auto_load_pspace_data_cleanup (struct program_space *pspace, void *arg)
+{
+  struct auto_load_pspace_info *info;
+
+  info = program_space_data (pspace, auto_load_pspace_data);
+  if (info != NULL)
+    {
+      if (info->loaded_scripts)
+	htab_delete (info->loaded_scripts);
+      xfree (info);
+    }
+}
+
+/* Get the current autoload data.  If none is found yet, add it now.  This
+   function always returns a valid object.  */
+
+static struct auto_load_pspace_info *
+get_auto_load_pspace_data (struct program_space *pspace)
+{
+  struct auto_load_pspace_info *info;
+
+  info = program_space_data (pspace, auto_load_pspace_data);
+  if (info == NULL)
+    {
+      info = XZALLOC (struct auto_load_pspace_info);
+      set_program_space_data (pspace, auto_load_pspace_data, info);
+    }
+
+  return info;
+}
+
+/* Hash function for the loaded script hash.  */
+
+static hashval_t
+hash_loaded_script_entry (const void *data)
+{
+  const struct loaded_script_entry *e = data;
+  return htab_hash_string (e->name);
+}
+
+/* Equality function for the loaded script hash.  */
+
+static int
+eq_loaded_script_entry (const void *a, const void *b)
+{
+  const struct loaded_script_entry *ea = a;
+  const struct loaded_script_entry *eb = b;
+  return strcmp (ea->name, eb->name) == 0;
+}
+
+/* Create the hash table used for loaded scripts.
+   Each entry is hashed by the full path name.  */
+
+static void
+create_loaded_scripts_hash (struct auto_load_pspace_info *pspace_info)
+{
+  /* Choose 31 as the starting size of the hash table, somewhat arbitrarily.
+     Space for each entry is obtained with one malloc so we can free them
+     easily.  */
+
+  pspace_info->loaded_scripts = htab_create (31,
+					     hash_loaded_script_entry,
+					     eq_loaded_script_entry,
+					     xfree);
+}
+
+/* Load scripts specified in OBJFILE.
+   START,END delimit a buffer containing a list of nul-terminated
+   file names.
+   SOURCE_NAME is used in error messages.
+
+   Scripts are found per normal "source -s" command processing.
+   First the script is looked for in $cwd.  If not found there the
+   source search path is used.
+
+   The section contains a list of path names of files containing
+   python code to load.  Each path is null-terminated.  */
+
+static void
+source_section_scripts (struct objfile *objfile, const char *source_name,
+			const char *start, const char *end)
+{
+  const char *p;
+  struct auto_load_pspace_info *pspace_info;
+  struct loaded_script_entry **slot, entry;
+
+  pspace_info = get_auto_load_pspace_data (current_program_space);
+  if (pspace_info->loaded_scripts == NULL)
+    create_loaded_scripts_hash (pspace_info);
+
+  for (p = start; p < end; ++p)
+    {
+      const char *file;
+      FILE *stream;
+      char *full_path;
+      int opened, in_hash_table;
+
+      if (*p != 1)
+	{
+	  warning (_("Invalid entry in %s section"), GDBPY_AUTO_SECTION_NAME);
+	  /* We could try various heuristics to find the next valid entry,
+	     but it's safer to just punt.  */
+	  break;
+	}
+      file = ++p;
+
+      while (p < end && *p != '\0')
+	++p;
+      if (p == end)
+	{
+	  char *buf = alloca (p - file + 1);
+	  memcpy (buf, file, p - file);
+	  buf[p - file] = '\0';
+	  warning (_("Non-null-terminated path in %s: %s"),
+		   source_name, buf);
+	  /* Don't load it.  */
+	  break;
+	}
+      if (p == file)
+	{
+	  warning (_("Empty path in %s"), source_name);
+	  continue;
+	}
+
+      opened = find_and_open_script (file, 1 /*search_path*/,
+				     &stream, &full_path);
+
+      /* If the file is not found, we still record the file in the hash table,
+	 we only want to print an error message once.
+	 IWBN if complaints.c were more general-purpose.  */
+
+      entry.name = file;
+      if (opened)
+	entry.full_path = full_path;
+      else
+	entry.full_path = NULL;
+      slot = ((struct loaded_script_entry **)
+	      htab_find_slot (pspace_info->loaded_scripts,
+			      &entry, INSERT));
+      in_hash_table = *slot != NULL;
+
+      /* If this file is not in the hash table, add it.  */
+      if (! in_hash_table)
+	{
+	  char *p;
+	  *slot = xmalloc (sizeof (**slot)
+			   + strlen (file) + 1
+			   + (opened ? (strlen (full_path) + 1) : 0));
+	  p = ((char*) *slot) + sizeof (**slot);
+	  strcpy (p, file);
+	  (*slot)->name = p;
+	  if (opened)
+	    {
+	      p += strlen (p) + 1;
+	      strcpy (p, full_path);
+	      (*slot)->full_path = p;
+	    }
+	  else
+	    (*slot)->full_path = NULL;
+	}
+
+      if (opened)
+	free (full_path);
+
+      if (! opened)
+	{
+	  /* We don't throw an error, the program is still debuggable.
+	     Check in_hash_table to only print the warning once.  */
+	  if (! in_hash_table)
+	    warning (_("%s (referenced in %s): %s\n"),
+		     file, GDBPY_AUTO_SECTION_NAME, safe_strerror (errno));
+	  continue;
+	}
+
+      /* If this file is not currently loaded, load it.  */
+      if (! in_hash_table)
+	source_python_script_for_objfile (objfile, stream, file);
+    }
+}
+
+/* Load scripts specified in section SECTION_NAME of OBJFILE.  */
+
+static void
+auto_load_section_scripts (struct objfile *objfile, const char *section_name)
+{
+  bfd *abfd = objfile->obfd;
+  asection *scripts_sect;
+  bfd_size_type size;
+  char *p;
+  struct cleanup *cleanups;
+
+  scripts_sect = bfd_get_section_by_name (abfd, section_name);
+  if (scripts_sect == NULL)
+    return;
+
+  size = bfd_get_section_size (scripts_sect);
+  p = xmalloc (size);
+  
+  cleanups = make_cleanup (xfree, p);
+
+  if (bfd_get_section_contents (abfd, scripts_sect, p, (file_ptr) 0, size))
+    source_section_scripts (objfile, section_name, p, p + size);
+  else
+    warning (_("Couldn't read %s section of %s"),
+	     section_name, bfd_get_filename (abfd));
+
+  do_cleanups (cleanups);
+}
+
+/* Clear the table of loaded section scripts.  */
+
+static void
+clear_section_scripts (void)
+{
+  struct program_space *pspace = current_program_space;
+  struct auto_load_pspace_info *info;
+
+  info = program_space_data (pspace, auto_load_pspace_data);
+  if (info != NULL && info->loaded_scripts != NULL)
+    {
+      htab_delete (info->loaded_scripts);
+      info->loaded_scripts = NULL;
+    }
+}
+
+/* Look for the auto-load script associated with OBJFILE and load it.  */
+
+static void
+auto_load_objfile_script (struct objfile *objfile, const char *suffix)
+{
+  char *realname;
+  char *filename, *debugfile;
+  int len;
+  FILE *input;
+  struct cleanup *cleanups;
+
+  realname = gdb_realpath (objfile->name);
+  len = strlen (realname);
+  filename = xmalloc (len + strlen (suffix) + 1);
+  memcpy (filename, realname, len);
+  strcpy (filename + len, suffix);
+
+  cleanups = make_cleanup (xfree, filename);
+  make_cleanup (xfree, realname);
+
+  input = fopen (filename, "r");
+  debugfile = filename;
+
+  if (!input && debug_file_directory)
+    {
+      /* Also try the same file in the separate debug info directory.  */
+      debugfile = xmalloc (strlen (filename)
+			   + strlen (debug_file_directory) + 1);
+      strcpy (debugfile, debug_file_directory);
+      /* FILENAME is absolute, so we don't need a "/" here.  */
+      strcat (debugfile, filename);
+
+      make_cleanup (xfree, debugfile);
+      input = fopen (debugfile, "r");
+    }
+
+  if (!input && gdb_datadir)
+    {
+      /* Also try the same file in a subdirectory of gdb's data
+	 directory.  */
+      debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename)
+			   + strlen ("/auto-load") + 1);
+      strcpy (debugfile, gdb_datadir);
+      strcat (debugfile, "/auto-load");
+      /* FILENAME is absolute, so we don't need a "/" here.  */
+      strcat (debugfile, filename);
+
+      make_cleanup (xfree, debugfile);
+      input = fopen (debugfile, "r");
+    }
+
+  if (input)
+    {
+      source_python_script_for_objfile (objfile, input, debugfile);
+      fclose (input);
+    }
+
+  do_cleanups (cleanups);
+}
+
+/* This is a new_objfile observer callback to auto-load scripts.
+
+   Two flavors of auto-loaded scripts are supported.
+   1) based on the path to the objfile
+   2) from .debug_gdb_scripts section  */
+
+static void
+auto_load_new_objfile (struct objfile *objfile)
+{
+  if (!objfile)
+    {
+      /* OBJFILE is NULL when loading a new "main" symbol-file.  */
+      clear_section_scripts ();
+      return;
+    }
+  if (!objfile->name)
+    return;
+
+  if (gdbpy_auto_load)
+    {
+      auto_load_objfile_script (objfile, GDBPY_AUTO_FILE_NAME);
+      auto_load_section_scripts (objfile, GDBPY_AUTO_SECTION_NAME);
+    }
+}
+\f
+/* Traversal function for htab_traverse.
+   Print the entry if specified in the regex.  */
+
+static int
+maybe_print_section_script (void **slot, void *info)
+{
+  struct loaded_script_entry *entry = *slot;
+
+  if (re_exec (entry->name))
+    {
+      printf_filtered (_("Script name: %s\n"), entry->name);
+      printf_filtered (_("  Full name: %s\n"),
+		       entry->full_path ? entry->full_path : _("unknown"));
+    }
+
+  return 1;
+}
+
+/* "maint print section-scripts" command.  */
+
+static void
+maintenance_print_section_scripts (char *pattern, int from_tty)
+{
+  struct auto_load_pspace_info *pspace_info;
+
+  dont_repeat ();
+
+  if (pattern && *pattern)
+    {
+      char *re_err = re_comp (pattern);
+
+      if (re_err)
+	error (_("Invalid regexp: %s"), re_err);
+
+      printf_filtered (_("Objfile scripts matching %s:\n"), pattern);
+    }
+  else
+    {
+      re_comp ("");
+      printf_filtered (_("Objfile scripts:\n"));
+    }
+
+  pspace_info = get_auto_load_pspace_data (current_program_space);
+  if (pspace_info == NULL || pspace_info->loaded_scripts == NULL)
+    return;
+
+  immediate_quit++;
+  htab_traverse_noresize (pspace_info->loaded_scripts,
+			  maybe_print_section_script, NULL);
+  immediate_quit--;
+}
+\f
+void
+gdbpy_initialize_auto_load (void)
+{
+  auto_load_pspace_data
+    = register_program_space_data_with_cleanup (auto_load_pspace_data_cleanup);
+
+  observer_attach_new_objfile (auto_load_new_objfile);
+
+  add_setshow_boolean_cmd ("auto-load", class_maintenance,
+			   &gdbpy_auto_load, _("\
+Enable or disable auto-loading of Python code when an object is opened."), _("\
+Show whether Python code will be auto-loaded when an object is opened."), _("\
+Enables or disables auto-loading of Python code when an object is opened."),
+			   NULL, NULL,
+			   &set_python_list,
+			   &show_python_list);
+
+  add_cmd ("section-scripts", class_maintenance, maintenance_print_section_scripts,
+	   _("Print dump of auto-loaded section scripts matching REGEXP."),
+	   &maintenanceprintlist);
+}
Index: python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.24
diff -u -p -r1.24 python-internal.h
--- python/python-internal.h	15 Apr 2010 19:54:13 -0000	1.24
+++ python/python-internal.h	21 Apr 2010 19:07:18 -0000
@@ -20,6 +20,8 @@
 #ifndef GDB_PYTHON_INTERNAL_H
 #define GDB_PYTHON_INTERNAL_H
 
+#include <stdio.h>
+
 /* Python 2.4 doesn't include stdint.h soon enough to get {u,}intptr_t
    needed by pyport.h.  */
 #include <stdint.h>
@@ -75,6 +77,9 @@ extern PyTypeObject value_object_type;
 extern PyTypeObject block_object_type;
 extern PyTypeObject symbol_object_type;
 
+extern struct cmd_list_element *set_python_list;
+extern struct cmd_list_element *show_python_list;
+
 PyObject *gdbpy_history (PyObject *self, PyObject *args);
 PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
 PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
@@ -107,6 +112,7 @@ struct type *type_object_to_type (PyObje
 struct symtab *symtab_object_to_symtab (PyObject *obj);
 struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
 
+void gdbpy_initialize_auto_load (void);
 void gdbpy_initialize_values (void);
 void gdbpy_initialize_frames (void);
 void gdbpy_initialize_symtabs (void);
@@ -154,6 +160,9 @@ extern const struct language_defn *pytho
 
 void gdbpy_print_stack (void);
 
+void source_python_script_for_objfile (struct objfile *objfile,
+				       FILE *stream, const char *file);
+
 PyObject *python_string_to_unicode (PyObject *obj);
 char *unicode_to_target_string (PyObject *unicode_str);
 char *python_string_to_target_string (PyObject *obj);
Index: python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.32
diff -u -p -r1.32 python.c
--- python/python.c	15 Apr 2010 19:54:13 -0000	1.32
+++ python/python.c	21 Apr 2010 19:07:18 -0000
@@ -25,7 +25,6 @@
 #include "gdbcmd.h"
 #include "progspace.h"
 #include "objfiles.h"
-#include "observer.h"
 #include "value.h"
 #include "language.h"
 #include "exceptions.h"
@@ -36,10 +35,6 @@
    false otherwise.  */
 static int gdbpy_should_print_stack = 1;
 
-/* This is true if we should auto-load python code when an objfile is
-   opened, false otherwise.  */
-static int gdbpy_auto_load = 1;
-
 #ifdef HAVE_PYTHON
 
 #include "python.h"
@@ -460,85 +455,33 @@ gdbpy_progspaces (PyObject *unused1, PyO
 \f
 
 /* 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 gdbpy_new_objfile; it is NULL at other times.  */
+   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.  */
 static struct objfile *gdbpy_current_objfile;
 
-/* The file name we attempt to read.  */
-#define GDBPY_AUTO_FILENAME "-gdb.py"
+/* Set the current objfile to OBJFILE and then read STREAM,FILE as
+   Python code.  */
 
-/* This is a new_objfile observer callback which loads python code
-   based on the path to the objfile.  */
-static void
-gdbpy_new_objfile (struct objfile *objfile)
+void
+source_python_script_for_objfile (struct objfile *objfile,
+				  FILE *stream, const char *file)
 {
-  char *realname;
-  char *filename, *debugfile;
-  int len;
-  FILE *input;
   struct cleanup *cleanups;
 
-  if (!gdbpy_auto_load || !objfile || !objfile->name)
-    return;
-
   cleanups = ensure_python_env (get_objfile_arch (objfile), current_language);
-
   gdbpy_current_objfile = objfile;
 
-  realname = gdb_realpath (objfile->name);
-  len = strlen (realname);
-  filename = xmalloc (len + sizeof (GDBPY_AUTO_FILENAME));
-  memcpy (filename, realname, len);
-  strcpy (filename + len, GDBPY_AUTO_FILENAME);
-
-  input = fopen (filename, "r");
-  debugfile = filename;
-
-  make_cleanup (xfree, filename);
-  make_cleanup (xfree, realname);
-
-  if (!input && debug_file_directory)
-    {
-      /* Also try the same file in the separate debug info directory.  */
-      debugfile = xmalloc (strlen (filename)
-			   + strlen (debug_file_directory) + 1);
-      strcpy (debugfile, debug_file_directory);
-      /* FILENAME is absolute, so we don't need a "/" here.  */
-      strcat (debugfile, filename);
-
-      make_cleanup (xfree, debugfile);
-      input = fopen (debugfile, "r");
-    }
-
-  if (!input && gdb_datadir)
-    {
-      /* Also try the same file in a subdirectory of gdb's data
-	 directory.  */
-      debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename)
-			   + strlen ("/auto-load") + 1);
-      strcpy (debugfile, gdb_datadir);
-      strcat (debugfile, "/auto-load");
-      /* FILENAME is absolute, so we don't need a "/" here.  */
-      strcat (debugfile, filename);
-
-      make_cleanup (xfree, debugfile);
-      input = fopen (debugfile, "r");
-    }
-
-  if (input)
-    {
-      /* We don't want to throw an exception here -- but the user
-	 would like to know that something went wrong.  */
-      if (PyRun_SimpleFile (input, debugfile))
-	gdbpy_print_stack ();
-      fclose (input);
-    }
+  /* We don't want to throw an exception here -- but the user
+     would like to know that something went wrong.  */
+  if (PyRun_SimpleFile (stream, file))
+    gdbpy_print_stack ();
 
   do_cleanups (cleanups);
   gdbpy_current_objfile = NULL;
 }
 
 /* Return the current Objfile, or None if there isn't one.  */
+
 static PyObject *
 gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2)
 {
@@ -617,8 +560,8 @@ source_python_script (FILE *stream, cons
 
 /* Lists for 'maint set python' commands.  */
 
-static struct cmd_list_element *set_python_list;
-static struct cmd_list_element *show_python_list;
+struct cmd_list_element *set_python_list;
+struct cmd_list_element *show_python_list;
 
 /* Function for use by 'maint set python' prefix command.  */
 
@@ -683,16 +626,7 @@ Enables or disables printing of Python s
 			   &set_python_list,
 			   &show_python_list);
 
-  add_setshow_boolean_cmd ("auto-load", class_maintenance,
-			   &gdbpy_auto_load, _("\
-Enable or disable auto-loading of Python code when an object is opened."), _("\
-Show whether Python code will be auto-loaded when an object is opened."), _("\
-Enables or disables auto-loading of Python code when an object is opened."),
-			   NULL, NULL,
-			   &set_python_list,
-			   &show_python_list);
-
 #ifdef HAVE_PYTHON
   Py_Initialize ();
   PyEval_InitThreads ();
 
@@ -703,6 +643,7 @@ Enables or disables auto-loading of Pyth
   PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name);
   PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
 
+  gdbpy_initialize_auto_load ();
   gdbpy_initialize_values ();
   gdbpy_initialize_frames ();
   gdbpy_initialize_commands ();
@@ -719,8 +660,6 @@ Enables or disables auto-loading of Pyth
   PyRun_SimpleString ("import gdb");
   PyRun_SimpleString ("gdb.pretty_printers = []");
 
-  observer_attach_new_objfile (gdbpy_new_objfile);
-
   gdbpy_to_string_cst = PyString_FromString ("to_string");
   gdbpy_children_cst = PyString_FromString ("children");
   gdbpy_display_hint_cst = PyString_FromString ("display_hint");
Index: testsuite/gdb.python/py-section-script.c
===================================================================
RCS file: testsuite/gdb.python/py-section-script.c
diff -N testsuite/gdb.python/py-section-script.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-section-script.c	21 Apr 2010 19:07:18 -0000
@@ -0,0 +1,52 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2010 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/>.  */
+
+/* Put the path to the pretty-printer script in .debug_gdb_scripts so
+   gdb will automagically loaded it.  */
+
+#define DEFINE_GDB_SCRIPT(script_name) \
+  asm("\
+.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
+.byte 1\n\
+.asciz \"" script_name "\"\n\
+.popsection \n\
+");
+
+DEFINE_GDB_SCRIPT ("py-section-script.py")
+
+struct ss
+{
+  int a;
+  int b;
+};
+
+void
+init_ss (struct ss *s, int a, int b)
+{
+  s->a = a;
+  s->b = b;
+}
+
+int
+main ()
+{
+  struct ss ss;
+
+  init_ss (&ss, 1, 2);
+
+  return 0;      /* break to inspect struct and union */
+}
Index: testsuite/gdb.python/py-section-script.exp
===================================================================
RCS file: testsuite/gdb.python/py-section-script.exp
diff -N testsuite/gdb.python/py-section-script.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-section-script.exp	21 Apr 2010 19:07:18 -0000
@@ -0,0 +1,65 @@
+# Copyright (C) 2010 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/>.
+
+# This file is part of the GDB testsuite.  It tests automagic loading of
+# scripts specified in the .debug_gdb_scripts section.
+
+# This test can only be run on targets which support ELF and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+    && ![istarget *-*-gnu*]
+    && ![istarget *-*-elf*]
+    && ![istarget *-*-openbsd*]
+    && ![istarget arm-*-eabi*]
+    && ![istarget powerpc-*-eabi*]} {
+    verbose "Skipping py-section-script.exp because of lack of support."
+    return
+}
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set testfile "py-section-script"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+# Make this available to gdb before the program starts, it is
+# automagically loaded by gdb.
+set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] {
+    perror "couldn't run to main"
+    return
+}
+
+gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
+    ".*Breakpoint.*"
+gdb_test "continue" ".*Breakpoint.*"
+
+gdb_test "print ss" " = a=<1> b=<2>"
+
+remote_file host delete ${remote_python_file}
Index: testsuite/gdb.python/py-section-script.py
===================================================================
RCS file: testsuite/gdb.python/py-section-script.py
diff -N testsuite/gdb.python/py-section-script.py
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-section-script.py	21 Apr 2010 19:07:18 -0000
@@ -0,0 +1,63 @@
+# Copyright (C) 2010 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/>.
+
+# This file is part of the GDB testsuite.
+
+import re
+
+class pp_ss:
+    def __init__(self, val):
+        self.val = val
+
+    def to_string(self):
+        return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
+
+def lookup_function (val):
+    "Look-up and return a pretty-printer that can print val."
+
+    # Get the type.
+    type = val.type
+
+    # If it points to a reference, get the reference.
+    if type.code == gdb.TYPE_CODE_REF:
+        type = type.target ()
+
+    # Get the unqualified type, stripped of typedefs.
+    type = type.unqualified ().strip_typedefs ()
+
+    # Get the type name.    
+    typename = type.tag
+
+    if typename == None:
+        return None
+
+    # Iterate over local dictionary of types to determine
+    # if a printer is registered for that type.  Return an
+    # instantiation of the printer if found.
+    for function in pretty_printers_dict:
+        if function.match (typename):
+            return pretty_printers_dict[function] (val)
+        
+    # Cannot find a pretty printer.  Return None.
+
+    return None
+
+def register_pretty_printers ():
+    pretty_printers_dict[re.compile ('^ss$')]  = pp_ss
+
+pretty_printers_dict = {}
+
+register_pretty_printers ()
+gdb.current_progspace().pretty_printers.append (lookup_function)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-21 19:23         ` Doug Evans
@ 2010-04-21 20:39           ` Eli Zaretskii
  2010-04-21 21:54             ` Doug Evans
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2010-04-21 20:39 UTC (permalink / raw)
  To: Doug Evans; +Cc: tromey, gdb-patches

> Date: Wed, 21 Apr 2010 12:23:16 -0700
> From: Doug Evans <dje@google.com>
> 
> I've applied the requested doc changes, except that Auto-loading is
> still moved up one level, moved from node Python API to node Python.

Thanks.

> +If this file does not exist, and if the parameter
> +@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
> +then @value{GDBN} will use for its each separated directory component
> +@code{component} the file named @file{@code{component}/@var{real-name}}, where
> +@var{real-name} is the object file's real name, as described above.

In my review, I suggested a better wording for this sentence.  Please
use it.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-21 20:39           ` Eli Zaretskii
@ 2010-04-21 21:54             ` Doug Evans
  2010-04-22  3:13               ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Doug Evans @ 2010-04-21 21:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tromey, gdb-patches

On Wed, Apr 21, 2010 at 1:37 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>> Date: Wed, 21 Apr 2010 12:23:16 -0700
>> From: Doug Evans <dje@google.com>
>>
>> I've applied the requested doc changes, except that Auto-loading is
>> still moved up one level, moved from node Python API to node Python.
>
> Thanks.
>
>> +If this file does not exist, and if the parameter
>> +@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
>> +then @value{GDBN} will use for its each separated directory component
>> +@code{component} the file named @file{@code{component}/@var{real-name}}, where
>> +@var{real-name} is the object file's real name, as described above.
>
> In my review, I suggested a better wording for this sentence.  Please
> use it.
>

Ah.  Missed that:

> If this file does not exist, and if the parameter
> @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
> then @value{GDBN} will look for the file in all of the directories
> mentioned in the value of @code{debug-file-directory}.

I think the new wording still isn't sufficiently clear.
It doesn't say that each element in debug-file-directory is
concatenated with the full file name.  The user might think that only
the base name of the file is used.
[At least that is my understanding of how debug-file-directory would be used.]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-21 21:54             ` Doug Evans
@ 2010-04-22  3:13               ` Eli Zaretskii
  2010-04-23 18:10                 ` Doug Evans
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2010-04-22  3:13 UTC (permalink / raw)
  To: Doug Evans; +Cc: tromey, gdb-patches

> Date: Wed, 21 Apr 2010 14:54:05 -0700
> From: Doug Evans <dje@google.com>
> Cc: tromey@redhat.com, gdb-patches@sourceware.org
> 
> > If this file does not exist, and if the parameter
> > @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
> > then @value{GDBN} will look for the file in all of the directories
> > mentioned in the value of @code{debug-file-directory}.
> 
> I think the new wording still isn't sufficiently clear.
> It doesn't say that each element in debug-file-directory is
> concatenated with the full file name.

That's a trivial change:

 If this file does not exist, and if the parameter
 @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
 then @value{GDBN} will look for @var{real-name} in all of the
 directories mentioned in the value of @code{debug-file-directory}.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section
  2010-04-22  3:13               ` Eli Zaretskii
@ 2010-04-23 18:10                 ` Doug Evans
  0 siblings, 0 replies; 12+ messages in thread
From: Doug Evans @ 2010-04-23 18:10 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tromey, gdb-patches

On Wed, Apr 21, 2010 at 8:12 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>> Date: Wed, 21 Apr 2010 14:54:05 -0700
>> From: Doug Evans <dje@google.com>
>> Cc: tromey@redhat.com, gdb-patches@sourceware.org
>>
>> > If this file does not exist, and if the parameter
>> > @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
>> > then @value{GDBN} will look for the file in all of the directories
>> > mentioned in the value of @code{debug-file-directory}.
>>
>> I think the new wording still isn't sufficiently clear.
>> It doesn't say that each element in debug-file-directory is
>> concatenated with the full file name.
>
> That's a trivial change:
>
>  If this file does not exist, and if the parameter
>  @code{debug-file-directory} is set (@pxref{Separate Debug Files}),
>  then @value{GDBN} will look for @var{real-name} in all of the
>  directories mentioned in the value of @code{debug-file-directory}.
>

Sure.
Checked in.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2010-04-23 18:10 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-16  7:06 [RFA] [1/2] auto-loading scripts from .debug_gdb_scripts section Doug Evans
2010-04-16  9:38 ` Eli Zaretskii
2010-04-16 18:06   ` Doug Evans
2010-04-16 21:25     ` Eli Zaretskii
2010-04-20 21:45       ` Doug Evans
2010-04-21 19:23         ` Doug Evans
2010-04-21 20:39           ` Eli Zaretskii
2010-04-21 21:54             ` Doug Evans
2010-04-22  3:13               ` Eli Zaretskii
2010-04-23 18:10                 ` Doug Evans
2010-04-20 19:13 ` Tom Tromey
2010-04-20 21:38   ` Doug Evans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).