Add support for inlining scripts into .debug_gdb_scripts.

include/gdb/ChangeLog:

	* section-scripts.h: Remove "future extension" comment.
	(SECTION_SCRIPT_ID_PYTHON_TEXT): New macro.
	(SECTION_SCRIPT_ID_SCHEME_TEXT): New macro.

gdb/ChangeLog:

	* NEWS: Mention inlined scripts in .debug_gdb_scripts section.
	* auto-load.c: #include ctype.h.
	(struct auto_load_pspace_info): Replace member loaded_scripts with
	new members loaded_script_files, loaded_script_texts.
	(auto_load_pspace_data_cleanup): Update.
	(init_loaded_scripts_info): Update.
	(get_auto_load_pspace_data_for_loading): Update.
	(maybe_add_script_file): Renamed from maybe_add_script.  All callers
	updated.
	(maybe_add_script_text): New function.
	(clear_section_scripts): Update.
	(source_script_file, execute_script_contents): New functions.
	(source_section_scripts): Add support for
	SECTION_SCRIPT_ID_PYTHON_TEXT, SECTION_SCRIPT_ID_GUILE_TEXT.
	(print_scripts): New function.
	(auto_load_info_scripts): Also print inlined scripts.
	(maybe_print_unsupported_script_warning): Renamed from
	unsupported_script_warning_print.  All callers updated.
	(maybe_print_script_not_found_warning): Renamed from
	script_not_found_warning_print.  All callers updated.
	* extension-priv.h (struct extension_language_script_ops): New member
	objfile_script_executor.
	* extension.c (ext_lang_objfile_script_executor): New function.
	* extension.h (objfile_script_executor_func): New typedef.
	(ext_lang_objfile_script_executor): Declare.
	* guile/guile-internal.h (gdbscm_execute_objfile_script): Declare.
	* guile/guile.c (guile_extension_script_ops): Update.
	* guile/scm-objfile.c (gdbscm_execute_objfile_script): New function.
	* python/python.c (python_extension_script_ops): Update.
	(gdbpy_execute_objfile_script): New function.

gdb/doc/ChangeLog:

	* gdb.texinfo (dotdebug_gdb_scripts section): Update docs to
	distinguish script files vs inlined scripts.
	* python.texi (Python Auto-loading): Ditto.

gdb/testsuite/ChangeLog:

	* gdb.guile/scm-section-script.c: Add duplicate inlined section script
	entries.  Duplicate file section script entries.
	* gdb.guile/scm-section-script.exp: Add tests for duplicate entries,
	inlined entries.  Add test for safe-path rejection.
	* gdb.python/py-section-script.c: Add duplicate inlined section script
	entries.  Duplicate file section script entries.
	* gdb.python/py-section-script.exp: Add tests for duplicate entries,
	inlined entries.  Add test for safe-path rejection.
This commit is contained in:
Doug Evans 2015-01-31 12:01:13 -08:00
parent 312809f883
commit 9f0500621b
20 changed files with 744 additions and 194 deletions

View File

@ -1,3 +1,36 @@
2015-01-31 Doug Evans <xdje42@gmail.com>
* NEWS: Mention inlined scripts in .debug_gdb_scripts section.
* auto-load.c: #include ctype.h.
(struct auto_load_pspace_info): Replace member loaded_scripts with
new members loaded_script_files, loaded_script_texts.
(auto_load_pspace_data_cleanup): Update.
(init_loaded_scripts_info): Update.
(get_auto_load_pspace_data_for_loading): Update.
(maybe_add_script_file): Renamed from maybe_add_script. All callers
updated.
(maybe_add_script_text): New function.
(clear_section_scripts): Update.
(source_script_file, execute_script_contents): New functions.
(source_section_scripts): Add support for
SECTION_SCRIPT_ID_PYTHON_TEXT, SECTION_SCRIPT_ID_GUILE_TEXT.
(print_scripts): New function.
(auto_load_info_scripts): Also print inlined scripts.
(maybe_print_unsupported_script_warning): Renamed from
unsupported_script_warning_print. All callers updated.
(maybe_print_script_not_found_warning): Renamed from
script_not_found_warning_print. All callers updated.
* extension-priv.h (struct extension_language_script_ops): New member
objfile_script_executor.
* extension.c (ext_lang_objfile_script_executor): New function.
* extension.h (objfile_script_executor_func): New typedef.
(ext_lang_objfile_script_executor): Declare.
* guile/guile-internal.h (gdbscm_execute_objfile_script): Declare.
* guile/guile.c (guile_extension_script_ops): Update.
* guile/scm-objfile.c (gdbscm_execute_objfile_script): New function.
* python/python.c (python_extension_script_ops): Update.
(gdbpy_execute_objfile_script): New function.
2015-01-31 Eli Zaretskii <eliz@gnu.org>
* tui/tui-io.c (tui_expand_tabs): New function.

View File

@ -18,6 +18,11 @@
* The command 'thread apply all' can now support new option '-ascending'
to call its specified command for all threads in ascending order.
* Python/Guile scripting
** GDB now supports auto-loading of Python/Guile scripts contained in the
special section named `.debug_gdb_scripts'.
*** Changes in GDB 7.9
* GDB now supports hardware watchpoints on x86 GNU Hurd.

View File

@ -18,6 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include <ctype.h>
#include "auto-load.h"
#include "progspace.h"
#include "gdb_regex.h"
@ -48,14 +49,15 @@
followed by the path of a python script to load. */
#define AUTO_SECTION_NAME ".debug_gdb_scripts"
static int maybe_add_script (struct auto_load_pspace_info *pspace_info,
int loaded, const char *name,
const char *full_path,
const struct extension_language_defn *language);
static void maybe_print_unsupported_script_warning
(struct auto_load_pspace_info *, struct objfile *objfile,
const struct extension_language_defn *language,
const char *section_name, unsigned offset);
static int unsupported_script_warning_print (struct auto_load_pspace_info *);
static int script_not_found_warning_print (struct auto_load_pspace_info *);
static void maybe_print_script_not_found_warning
(struct auto_load_pspace_info *, struct objfile *objfile,
const struct extension_language_defn *language,
const char *section_name, unsigned offset);
/* Value of the 'set debug auto-load' configuration variable. */
static int debug_auto_load = 0;
@ -541,8 +543,10 @@ For more information about this security protection see the\n\
struct auto_load_pspace_info
{
/* For each program space we keep track of loaded scripts. */
struct htab *loaded_scripts;
/* For each program space we keep track of loaded scripts, both when
specified as file names and as scripts to be executed directly. */
struct htab *loaded_script_files;
struct htab *loaded_script_texts;
/* Non-zero if we've issued the warning about an auto-load script not being
supported. We only want to issue this warning once. */
@ -553,7 +557,7 @@ struct auto_load_pspace_info
int script_not_found_warning_printed;
};
/* Objects of this type are stored in the loaded script hash table. */
/* Objects of this type are stored in the loaded_script hash table. */
struct loaded_script
{
@ -561,7 +565,7 @@ struct loaded_script
const char *name;
/* Full path name or NULL if script wasn't found (or was otherwise
inaccessible). */
inaccessible), or NULL for loaded_script_texts. */
const char *full_path;
/* Non-zero if this script has been loaded. */
@ -578,8 +582,10 @@ auto_load_pspace_data_cleanup (struct program_space *pspace, void *arg)
{
struct auto_load_pspace_info *info = arg;
if (info->loaded_scripts)
htab_delete (info->loaded_scripts);
if (info->loaded_script_files)
htab_delete (info->loaded_script_files);
if (info->loaded_script_texts)
htab_delete (info->loaded_script_texts);
xfree (info);
}
@ -632,10 +638,14 @@ init_loaded_scripts_info (struct auto_load_pspace_info *pspace_info)
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);
pspace_info->loaded_script_files = htab_create (31,
hash_loaded_script_entry,
eq_loaded_script_entry,
xfree);
pspace_info->loaded_script_texts = htab_create (31,
hash_loaded_script_entry,
eq_loaded_script_entry,
xfree);
pspace_info->unsupported_script_warning_printed = FALSE;
pspace_info->script_not_found_warning_printed = FALSE;
@ -650,23 +660,24 @@ get_auto_load_pspace_data_for_loading (struct program_space *pspace)
struct auto_load_pspace_info *info;
info = get_auto_load_pspace_data (pspace);
if (info->loaded_scripts == NULL)
if (info->loaded_script_files == NULL)
init_loaded_scripts_info (info);
return info;
}
/* Add script NAME in LANGUAGE to hash table of PSPACE_INFO. LOADED 1 if the
script has been (is going to) be loaded, 0 otherwise (such as if it has not
been found). FULL_PATH is NULL if the script wasn't found. The result is
true if the script was already in the hash table. */
/* Add script file NAME in LANGUAGE to hash table of PSPACE_INFO.
LOADED 1 if the script has been (is going to) be loaded, 0 otherwise
(such as if it has not been found).
FULL_PATH is NULL if the script wasn't found.
The result is true if the script was already in the hash table. */
static int
maybe_add_script (struct auto_load_pspace_info *pspace_info, int loaded,
const char *name, const char *full_path,
const struct extension_language_defn *language)
maybe_add_script_file (struct auto_load_pspace_info *pspace_info, int loaded,
const char *name, const char *full_path,
const struct extension_language_defn *language)
{
struct htab *htab = pspace_info->loaded_scripts;
struct htab *htab = pspace_info->loaded_script_files;
struct loaded_script **slot, entry;
int in_hash_table;
@ -677,7 +688,7 @@ maybe_add_script (struct auto_load_pspace_info *pspace_info, int loaded,
/* If this script is not in the hash table, add it. */
if (! in_hash_table)
if (!in_hash_table)
{
char *p;
@ -703,6 +714,44 @@ maybe_add_script (struct auto_load_pspace_info *pspace_info, int loaded,
return in_hash_table;
}
/* Add script contents NAME in LANGUAGE to hash table of PSPACE_INFO.
LOADED 1 if the script has been (is going to) be loaded, 0 otherwise
(such as if it has not been found).
The result is true if the script was already in the hash table. */
static int
maybe_add_script_text (struct auto_load_pspace_info *pspace_info,
int loaded, const char *name,
const struct extension_language_defn *language)
{
struct htab *htab = pspace_info->loaded_script_texts;
struct loaded_script **slot, entry;
int in_hash_table;
entry.name = name;
entry.language = language;
slot = (struct loaded_script **) htab_find_slot (htab, &entry, INSERT);
in_hash_table = *slot != NULL;
/* If this script is not in the hash table, add it. */
if (!in_hash_table)
{
char *p;
/* Allocate all space in one chunk so it's easier to free. */
*slot = xmalloc (sizeof (**slot) + strlen (name) + 1);
p = ((char*) *slot) + sizeof (**slot);
strcpy (p, name);
(*slot)->name = p;
(*slot)->full_path = NULL;
(*slot)->loaded = loaded;
(*slot)->language = language;
}
return in_hash_table;
}
/* Clear the table of loaded section scripts. */
static void
@ -712,10 +761,12 @@ clear_section_scripts (void)
struct auto_load_pspace_info *info;
info = program_space_data (pspace, auto_load_pspace_data);
if (info != NULL && info->loaded_scripts != NULL)
if (info != NULL && info->loaded_script_files != NULL)
{
htab_delete (info->loaded_scripts);
info->loaded_scripts = NULL;
htab_delete (info->loaded_script_files);
htab_delete (info->loaded_script_texts);
info->loaded_script_files = NULL;
info->loaded_script_texts = NULL;
info->unsupported_script_warning_printed = FALSE;
info->script_not_found_warning_printed = FALSE;
}
@ -803,7 +854,8 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
"info auto-load ${lang}-scripts" can print it. */
pspace_info
= get_auto_load_pspace_data_for_loading (current_program_space);
maybe_add_script (pspace_info, is_safe, debugfile, debugfile, language);
maybe_add_script_file (pspace_info, is_safe, debugfile, debugfile,
language);
/* To preserve existing behaviour we don't check for whether the
script was already in the table, and always load it.
@ -864,17 +916,183 @@ auto_load_objfile_script (struct objfile *objfile,
do_cleanups (cleanups);
}
/* Subroutine of source_section_scripts to simplify it.
Load FILE as a script in extension language LANGUAGE.
The script is from section SECTION_NAME in OBJFILE at offset OFFSET. */
static void
source_script_file (struct auto_load_pspace_info *pspace_info,
struct objfile *objfile,
const struct extension_language_defn *language,
const char *section_name, unsigned int offset,
const char *file)
{
FILE *stream;
char *full_path;
int opened, in_hash_table;
struct cleanup *cleanups;
objfile_script_sourcer_func *sourcer;
/* Skip this script if support is not compiled in. */
sourcer = ext_lang_objfile_script_sourcer (language);
if (sourcer == NULL)
{
/* We don't throw an error, the program is still debuggable. */
maybe_print_unsupported_script_warning (pspace_info, objfile, language,
section_name, offset);
/* We *could* still try to open it, but there's no point. */
maybe_add_script_file (pspace_info, 0, file, NULL, language);
return;
}
/* Skip this script if auto-loading it has been disabled. */
if (!ext_lang_auto_load_enabled (language))
{
/* No message is printed, just skip it. */
return;
}
opened = find_and_open_script (file, 1 /*search_path*/,
&stream, &full_path);
cleanups = make_cleanup (null_cleanup, NULL);
if (opened)
{
make_cleanup_fclose (stream);
make_cleanup (xfree, full_path);
if (!file_is_auto_load_safe (full_path,
_("auto-load: Loading %s script "
"\"%s\" from section \"%s\" of "
"objfile \"%s\".\n"),
ext_lang_name (language), full_path,
section_name, objfile_name (objfile)))
opened = 0;
}
else
{
full_path = NULL;
/* If one script isn't found it's not uncommon for more to not be
found either. We don't want to print a message for each script,
too much noise. Instead, we print the warning once and tell the
user how to find the list of scripts that weren't loaded.
We don't throw an error, the program is still debuggable.
IWBN if complaints.c were more general-purpose. */
maybe_print_script_not_found_warning (pspace_info, objfile, language,
section_name, offset);
}
in_hash_table = maybe_add_script_file (pspace_info, opened, file, full_path,
language);
/* If this file is not currently loaded, load it. */
if (opened && !in_hash_table)
sourcer (language, objfile, stream, full_path);
do_cleanups (cleanups);
}
/* Subroutine of source_section_scripts to simplify it.
Execute SCRIPT as a script in extension language LANG.
The script is from section SECTION_NAME in OBJFILE at offset OFFSET. */
static void
execute_script_contents (struct auto_load_pspace_info *pspace_info,
struct objfile *objfile,
const struct extension_language_defn *language,
const char *section_name, unsigned int offset,
const char *script)
{
objfile_script_executor_func *executor;
const char *newline, *script_text;
char *name, *end;
int is_safe, in_hash_table;
struct cleanup *cleanups;
cleanups = make_cleanup (null_cleanup, NULL);
/* The first line of the script is the name of the script.
It must not contain any kind of space character. */
name = NULL;
newline = strchr (script, '\n');
if (newline != NULL)
{
char *buf, *p;
/* Put the name in a buffer and validate it. */
buf = xstrndup (script, newline - script);
make_cleanup (xfree, buf);
for (p = buf; *p != '\0'; ++p)
{
if (isspace (*p))
break;
}
/* We don't allow nameless scripts, they're not helpful to the user. */
if (p != buf && *p == '\0')
name = buf;
}
if (name == NULL)
{
/* We don't throw an error, the program is still debuggable. */
warning (_("\
Missing/bad script name in entry at offset %u in section %s\n\
of file %s."),
offset, section_name, objfile_name (objfile));
do_cleanups (cleanups);
return;
}
script_text = newline + 1;
/* Skip this script if support is not compiled in. */
executor = ext_lang_objfile_script_executor (language);
if (executor == NULL)
{
/* We don't throw an error, the program is still debuggable. */
maybe_print_unsupported_script_warning (pspace_info, objfile, language,
section_name, offset);
maybe_add_script_text (pspace_info, 0, name, language);
do_cleanups (cleanups);
return;
}
/* Skip this script if auto-loading it has been disabled. */
if (!ext_lang_auto_load_enabled (language))
{
/* No message is printed, just skip it. */
do_cleanups (cleanups);
return;
}
is_safe = file_is_auto_load_safe (objfile_name (objfile),
_("auto-load: Loading %s script "
"\"%s\" from section \"%s\" of "
"objfile \"%s\".\n"),
ext_lang_name (language), name,
section_name, objfile_name (objfile));
in_hash_table = maybe_add_script_text (pspace_info, is_safe, name, language);
/* If this file is not currently loaded, load it. */
if (is_safe && !in_hash_table)
executor (language, objfile, name, script_text);
do_cleanups (cleanups);
}
/* Load scripts specified in OBJFILE.
START,END delimit a buffer containing a list of nul-terminated
file names.
SECTION_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.
Scripts specified as file names 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 script files to load.
Each path is null-terminated. */
The section contains a list of path names of script files to load or
actual script contents. Each entry is nul-terminated. */
static void
source_section_scripts (struct objfile *objfile, const char *section_name,
@ -887,20 +1105,19 @@ source_section_scripts (struct objfile *objfile, const char *section_name,
for (p = start; p < end; ++p)
{
const char *file;
FILE *stream;
char *full_path;
int opened, in_hash_table;
struct cleanup *back_to;
const char *entry;
const struct extension_language_defn *language;
objfile_script_sourcer_func *sourcer;
unsigned int offset = p - start;
int code = *p;
switch (*p)
switch (code)
{
case SECTION_SCRIPT_ID_PYTHON_FILE:
case SECTION_SCRIPT_ID_PYTHON_TEXT:
language = get_ext_lang_defn (EXT_LANG_PYTHON);
break;
case SECTION_SCRIPT_ID_SCHEME_FILE:
case SECTION_SCRIPT_ID_SCHEME_TEXT:
language = get_ext_lang_defn (EXT_LANG_GUILE);
break;
default:
@ -909,105 +1126,37 @@ source_section_scripts (struct objfile *objfile, const char *section_name,
but it's safer to just punt. */
return;
}
file = ++p;
entry = ++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"),
section_name, buf);
/* Don't load it. */
warning (_("Non-nul-terminated entry in %s at offset %u"),
section_name, offset);
/* Don't load/execute it. */
break;
}
if (p == file)
{
warning (_("Empty path in %s"), section_name);
continue;
}
/* Until we support more types of records in .debug_gdb_scripts we do
all the processing here. The expectation is to add a new
extension_language_script_ops "method" that handles all the records
for the language. For now we can just use
extension_language_script_ops.objfile_script_sourcer. */
/* Skip this script if support is not compiled in. */
sourcer = ext_lang_objfile_script_sourcer (language);
if (sourcer == NULL)
switch (code)
{
/* We don't throw an error, the program is still debuggable. */
if (!unsupported_script_warning_print (pspace_info))
case SECTION_SCRIPT_ID_PYTHON_FILE:
case SECTION_SCRIPT_ID_SCHEME_FILE:
if (p == entry)
{
warning (_("Unsupported auto-load scripts referenced in"
" %s section\n"
"of file %s.\n"
"Use `info auto-load %s-scripts [REGEXP]'"
" to list them."),
section_name, objfile_name (objfile),
ext_lang_name (language));
warning (_("Empty entry in %s at offset %u"),
section_name, offset);
continue;
}
/* We *could* still try to open it, but there's no point. */
maybe_add_script (pspace_info, 0, file, NULL, language);
continue;
source_script_file (pspace_info, objfile, language,
section_name, offset, entry);
break;
case SECTION_SCRIPT_ID_PYTHON_TEXT:
case SECTION_SCRIPT_ID_SCHEME_TEXT:
execute_script_contents (pspace_info, objfile, language,
section_name, offset, entry);
break;
}
/* Skip this script if auto-loading it has been disabled. */
if (!ext_lang_auto_load_enabled (language))
{
/* No message is printed, just skip it. */
continue;
}
opened = find_and_open_script (file, 1 /*search_path*/,
&stream, &full_path);
back_to = make_cleanup (null_cleanup, NULL);
if (opened)
{
make_cleanup_fclose (stream);
make_cleanup (xfree, full_path);
if (!file_is_auto_load_safe (full_path,
_("auto-load: Loading %s script "
"\"%s\" from section \"%s\" of "
"objfile \"%s\".\n"),
ext_lang_name (language), full_path,
section_name, objfile_name (objfile)))
opened = 0;
}
else
{
full_path = NULL;
/* If one script isn't found it's not uncommon for more to not be
found either. We don't want to print a message for each script,
too much noise. Instead, we print the warning once and tell the
user how to find the list of scripts that weren't loaded.
We don't throw an error, the program is still debuggable.
IWBN if complaints.c were more general-purpose. */
if (script_not_found_warning_print (pspace_info))
warning (_("Missing auto-load scripts referenced in section %s\n\
of file %s\n\
Use `info auto-load %s-scripts [REGEXP]' to list them."),
section_name, objfile_name (objfile),
ext_lang_name (language));
}
in_hash_table = maybe_add_script (pspace_info, opened, file, full_path,
language);
/* If this file is not currently loaded, load it. */
if (opened && !in_hash_table)
sourcer (language, objfile, stream, full_path);
do_cleanups (back_to);
}
}
@ -1146,6 +1295,23 @@ sort_scripts_by_name (const void *ap, const void *bp)
"info auto-load" invocation. Extra newline will be printed if needed. */
char auto_load_info_scripts_pattern_nl[] = "";
/* Subroutine of auto_load_info_scripts to simplify it.
Print SCRIPTS. */
static void
print_scripts (VEC (loaded_script_ptr) *scripts)
{
struct ui_out *uiout = current_uiout;
int i;
loaded_script_ptr script;
qsort (VEC_address (loaded_script_ptr, scripts),
VEC_length (loaded_script_ptr, scripts),
sizeof (loaded_script_ptr), sort_scripts_by_name);
for (i = 0; VEC_iterate (loaded_script_ptr, scripts, i, script); ++i)
print_script (script);
}
/* Implementation for "info auto-load gdb-scripts"
(and "info auto-load python-scripts"). List scripts in LANGUAGE matching
PATTERN. FROM_TTY is the usual GDB boolean for user interactivity. */
@ -1157,7 +1323,7 @@ auto_load_info_scripts (char *pattern, int from_tty,
struct ui_out *uiout = current_uiout;
struct auto_load_pspace_info *pspace_info;
struct cleanup *script_chain;
VEC (loaded_script_ptr) *scripts;
VEC (loaded_script_ptr) *script_files, *script_texts;
int nr_scripts;
dont_repeat ();
@ -1180,25 +1346,38 @@ auto_load_info_scripts (char *pattern, int from_tty,
Plus we want to sort the scripts by name.
So first traverse the hash table collecting the matching scripts. */
scripts = VEC_alloc (loaded_script_ptr, 10);
script_chain = make_cleanup (VEC_cleanup (loaded_script_ptr), &scripts);
script_files = VEC_alloc (loaded_script_ptr, 10);
script_texts = VEC_alloc (loaded_script_ptr, 10);
script_chain = make_cleanup (VEC_cleanup (loaded_script_ptr), &script_files);
make_cleanup (VEC_cleanup (loaded_script_ptr), &script_texts);
if (pspace_info != NULL && pspace_info->loaded_scripts != NULL)
if (pspace_info != NULL && pspace_info->loaded_script_files != NULL)
{
struct collect_matching_scripts_data data = { &scripts, language };
struct collect_matching_scripts_data data = { &script_files, language };
/* Pass a pointer to scripts as VEC_safe_push can realloc space. */
htab_traverse_noresize (pspace_info->loaded_scripts,
htab_traverse_noresize (pspace_info->loaded_script_files,
collect_matching_scripts, &data);
}
nr_scripts = VEC_length (loaded_script_ptr, scripts);
if (pspace_info != NULL && pspace_info->loaded_script_texts != NULL)
{
struct collect_matching_scripts_data data = { &script_texts, language };
/* Pass a pointer to scripts as VEC_safe_push can realloc space. */
htab_traverse_noresize (pspace_info->loaded_script_texts,
collect_matching_scripts, &data);
}
nr_scripts = (VEC_length (loaded_script_ptr, script_files)
+ VEC_length (loaded_script_ptr, script_texts));
/* Table header shifted right by preceding "gdb-scripts: " would not match
its columns. */
if (nr_scripts > 0 && pattern == auto_load_info_scripts_pattern_nl)
ui_out_text (uiout, "\n");
/* Note: This creates a cleanup to output the table end marker. */
make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts,
"AutoLoadedScriptsTable");
@ -1206,18 +1385,10 @@ auto_load_info_scripts (char *pattern, int from_tty,
ui_out_table_header (uiout, 70, ui_left, "script", "Script");
ui_out_table_body (uiout);
if (nr_scripts > 0)
{
int i;
loaded_script_ptr script;
qsort (VEC_address (loaded_script_ptr, scripts),
VEC_length (loaded_script_ptr, scripts),
sizeof (loaded_script_ptr), sort_scripts_by_name);
for (i = 0; VEC_iterate (loaded_script_ptr, scripts, i, script); ++i)
print_script (script);
}
print_scripts (script_files);
print_scripts (script_texts);
/* Finish up the table before checking for no matching scripts. */
do_cleanups (script_chain);
if (nr_scripts == 0)
@ -1253,32 +1424,48 @@ info_auto_load_local_gdbinit (char *args, int from_tty)
auto_load_local_gdbinit_pathname);
}
/* Return non-zero if UNSUPPORTED_SCRIPT_WARNING_PRINTED of PSPACE_INFO was
unset before calling this function. Always set
UNSUPPORTED_SCRIPT_WARNING_PRINTED of PSPACE_INFO. */
/* Print an "unsupported script" warning if it has not already been printed.
The script is in language LANGUAGE at offset OFFSET in section SECTION_NAME
of OBJFILE. */
static int
unsupported_script_warning_print (struct auto_load_pspace_info *pspace_info)
static void
maybe_print_unsupported_script_warning
(struct auto_load_pspace_info *pspace_info,
struct objfile *objfile, const struct extension_language_defn *language,
const char *section_name, unsigned offset)
{
int retval = !pspace_info->unsupported_script_warning_printed;
pspace_info->unsupported_script_warning_printed = 1;
return retval;
if (!pspace_info->unsupported_script_warning_printed)
{
warning (_("\
Unsupported auto-load script at offset %u in section %s\n\
of file %s.\n\
Use `info auto-load %s-scripts [REGEXP]' to list them."),
offset, section_name, objfile_name (objfile),
ext_lang_name (language));
pspace_info->unsupported_script_warning_printed = 1;
}
}
/* Return non-zero if SCRIPT_NOT_FOUND_WARNING_PRINTED of PSPACE_INFO was unset
before calling this function. Always set SCRIPT_NOT_FOUND_WARNING_PRINTED
of PSPACE_INFO. */
static int
script_not_found_warning_print (struct auto_load_pspace_info *pspace_info)
static void
maybe_print_script_not_found_warning
(struct auto_load_pspace_info *pspace_info,
struct objfile *objfile, const struct extension_language_defn *language,
const char *section_name, unsigned offset)
{
int retval = !pspace_info->script_not_found_warning_printed;
pspace_info->script_not_found_warning_printed = 1;
return retval;
if (!pspace_info->script_not_found_warning_printed)
{
warning (_("\
Missing auto-load script at offset %u in section %s\n\
of file %s.\n\
Use `info auto-load %s-scripts [REGEXP]' to list them."),
offset, section_name, objfile_name (objfile),
ext_lang_name (language));
pspace_info->script_not_found_warning_printed = 1;
}
}
/* The only valid "set auto-load" argument is off|0|no|disable. */

View File

@ -1,3 +1,9 @@
2015-01-31 Doug Evans <xdje42@gmail.com>
* gdb.texinfo (dotdebug_gdb_scripts section): Update docs to
distinguish script files vs inlined scripts.
* python.texi (Python Auto-loading): Ditto.
2015-01-30 Doug Evans <dje@google.com>
* gdb.texinfo (Symbols) <info source>: Output now contains producer

View File

@ -23977,17 +23977,29 @@ is evaluated more than once.
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 @code{.debug_gdb_scripts}.
If this section exists, its contents is a list of NUL-terminated names
of scripts to load. Each entry begins with a non-NULL prefix byte that
specifies the kind of entry, typically the extension language.
If this section exists, its contents is a list of null-terminated entries
specifying scripts to load. Each entry begins with a non-null prefix byte that
specifies the kind of entry, typically the extension language and whether the
script is in a file or inlined in @code{.debug_gdb_scripts}.
@value{GDBN} will look for each specified script file first in the
current directory and then along the source search path
The following entries are supported:
@table @code
@item SECTION_SCRIPT_ID_PYTHON_FILE = 1
@item SECTION_SCRIPT_ID_SCHEME_FILE = 3
@item SECTION_SCRIPT_ID_PYTHON_TEXT = 4
@item SECTION_SCRIPT_ID_SCHEME_TEXT = 6
@end table
@subsubsection Script File Entries
If the entry specifies a file, @value{GDBN} will look for the 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,
File entries can be placed in section @code{.debug_gdb_scripts} with,
for example, this GCC macro for Python scripts.
@example
@ -24019,6 +24031,45 @@ using this header will get a reference to the specified script,
and with the use of @code{"MS"} attributes on the section, the linker
will remove duplicates.
@subsubsection Script Text Entries
Script text entries allow to put the executable script in the entry
itself instead of loading it from a file.
The first line of the entry, everything after the prefix byte and up to
the first newline (@code{0xa}) character, is the script name, and must not
contain any kind of space character, e.g., spaces or tabs.
The rest of the entry, up to the trailing null byte, is the script to
execute in the specified language. The name needs to be unique among
all script names, as @value{GDBN} executes each script only once based
on its name.
Here is an example from file @file{py-section-script.c} in the @value{GDBN}
testsuite.
@example
#include "symcat.h"
#include "gdb/section-scripts.h"
asm(
".pushsection \".debug_gdb_scripts\", \"MS\",@@progbits,1\n"
".byte " XSTRING (SECTION_SCRIPT_ID_PYTHON_TEXT) "\n"
".ascii \"gdb.inlined-script\\n\"\n"
".ascii \"class test_cmd (gdb.Command):\\n\"\n"
".ascii \" def __init__ (self):\\n\"\n"
".ascii \" super (test_cmd, self).__init__ ("
"\\\"test-cmd\\\", gdb.COMMAND_OBSCURE)\\n\"\n"
".ascii \" def invoke (self, arg, from_tty):\\n\"\n"
".ascii \" print (\\\"test-cmd output, arg = %s\\\" % arg)\\n\"\n"
".ascii \"test_cmd ()\\n\"\n"
".byte 0\n"
".popsection\n"
);
@end example
Loading of inlined scripts requires a properly configured
@code{auto-load safe-path} (@pxref{Auto-loading safe path}).
The path to specify in @code{auto-load safe-path} is the path of the file
containing the @code{.debug_gdb_scripts} section.
@node Which flavor to choose?
@subsection Which flavor to choose?

View File

@ -4754,8 +4754,9 @@ Show whether auto-loading of Python scripts is enabled or disabled.
Print the list of all Python scripts that @value{GDBN} auto-loaded.
Also printed is the list of Python scripts that were mentioned in
the @code{.debug_gdb_scripts} section and were not found
(@pxref{dotdebug_gdb_scripts section}).
the @code{.debug_gdb_scripts} section and were either not found
(@pxref{dotdebug_gdb_scripts section}) or were not auto-loaded due to
@code{auto-load safe-path} rejection (@pxref{Auto-loading}).
This is useful because their names are not printed when @value{GDBN}
tries to load them and fails. There may be many of them, and printing
an error message for each one is problematic.
@ -4773,7 +4774,7 @@ No my-foo-pretty-printers.py
@end smallexample
@end table
When reading an auto-loaded file, @value{GDBN} sets the
When reading an auto-loaded file or script, @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 and frame-filters.

View File

@ -103,6 +103,11 @@ struct extension_language_script_ops
but is not required to, throw an error. */
objfile_script_sourcer_func *objfile_script_sourcer;
/* Execute a script attached to an objfile.
If there's an error while processing the script this function may,
but is not required to, throw an error. */
objfile_script_executor_func *objfile_script_executor;
/* Return non-zero if auto-loading scripts in this extension language
is enabled. */
int (*auto_load_enabled) (const struct extension_language_defn *);

View File

@ -61,6 +61,7 @@ static const struct extension_language_script_ops
{
source_gdb_script,
source_gdb_objfile_script,
NULL, /* objfile_script_executor */
auto_load_gdb_scripts_enabled
};
@ -286,6 +287,21 @@ ext_lang_objfile_script_sourcer (const struct extension_language_defn *extlang)
return extlang->script_ops->objfile_script_sourcer;
}
/* Return the objfile script "executor" function for EXTLANG.
This is the function that executes a script for a particular objfile.
If support for this language isn't compiled in, NULL is returned.
The extension language is not required to implement this function. */
objfile_script_executor_func *
ext_lang_objfile_script_executor
(const struct extension_language_defn *extlang)
{
if (extlang->script_ops == NULL)
return NULL;
return extlang->script_ops->objfile_script_executor;
}
/* Return non-zero if auto-loading of EXTLANG scripts is enabled.
Zero is returned if support for this language isn't compiled in. */

View File

@ -48,6 +48,12 @@ typedef void objfile_script_sourcer_func
(const struct extension_language_defn *,
struct objfile *, FILE *stream, const char *filename);
/* A function to execute a script for an objfile.
Any exceptions are not caught, and are passed to the caller. */
typedef void objfile_script_executor_func
(const struct extension_language_defn *,
struct objfile *, const char *name, const char *script);
/* Enum of each extension(/scripting) language. */
enum extension_language
@ -197,6 +203,9 @@ extern script_sourcer_func *ext_lang_script_sourcer
extern objfile_script_sourcer_func *ext_lang_objfile_script_sourcer
(const struct extension_language_defn *);
extern objfile_script_executor_func *ext_lang_objfile_script_executor
(const struct extension_language_defn *);
extern int ext_lang_auto_load_enabled (const struct extension_language_defn *);
/* Wrappers for each extension language API function that iterate over all

View File

@ -549,6 +549,7 @@ extern struct value *vlscm_convert_value_from_scheme
/* stript_lang methods */
extern objfile_script_sourcer_func gdbscm_source_objfile_script;
extern objfile_script_executor_func gdbscm_execute_objfile_script;
extern int gdbscm_auto_load_enabled (const struct extension_language_defn *);

View File

@ -128,6 +128,7 @@ static const struct extension_language_script_ops guile_extension_script_ops =
{
gdbscm_source_script,
gdbscm_source_objfile_script,
gdbscm_execute_objfile_script,
gdbscm_auto_load_enabled
};

View File

@ -283,7 +283,8 @@ gdbscm_set_objfile_pretty_printers_x (SCM self, SCM printers)
/* 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
gdbscm_source_objfile_script; it is NULL at other times. */
gdbscm_source_objfile_script and gdbscm_execute_objfile_script; it is NULL
at other times. */
static struct objfile *ofscm_current_objfile;
/* Set the current objfile to OBJFILE and then read FILE named FILENAME
@ -311,6 +312,31 @@ gdbscm_source_objfile_script (const struct extension_language_defn *extlang,
ofscm_current_objfile = NULL;
}
/* Set the current objfile to OBJFILE and then read FILE named FILENAME
as Guile code. This does not throw any errors. If an exception
occurs Guile will print the backtrace.
This is the extension_language_script_ops.objfile_script_sourcer
"method". */
void
gdbscm_execute_objfile_script (const struct extension_language_defn *extlang,
struct objfile *objfile, const char *name,
const char *script)
{
char *msg;
ofscm_current_objfile = objfile;
msg = gdbscm_safe_eval_string (script, 0 /* display_result */);
if (msg != NULL)
{
fprintf_filtered (gdb_stderr, "%s", msg);
xfree (msg);
}
ofscm_current_objfile = NULL;
}
/* (current-objfile) -> <gdb:obfjile>
Return the current objfile, or #f if there isn't one.
Ideally this would be named ofscm_current_objfile, but that name is

View File

@ -131,6 +131,7 @@ PyObject *gdbpy_gdb_memory_error;
static script_sourcer_func gdbpy_source_script;
static objfile_script_sourcer_func gdbpy_source_objfile_script;
static objfile_script_executor_func gdbpy_execute_objfile_script;
static void gdbpy_finish_initialization
(const struct extension_language_defn *);
static int gdbpy_initialized (const struct extension_language_defn *);
@ -155,6 +156,7 @@ static const struct extension_language_script_ops python_extension_script_ops =
{
gdbpy_source_script,
gdbpy_source_objfile_script,
gdbpy_execute_objfile_script,
gdbpy_auto_load_enabled
};
@ -1262,7 +1264,8 @@ gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
/* 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_source_objfile_script; it is NULL at other times. */
gdbpy_source_objfile_script and gdbpy_execute_objfile_script; it is NULL
at other times. */
static struct objfile *gdbpy_current_objfile;
/* Set the current objfile to OBJFILE and then read FILE named FILENAME
@ -1290,6 +1293,31 @@ gdbpy_source_objfile_script (const struct extension_language_defn *extlang,
gdbpy_current_objfile = NULL;
}
/* Set the current objfile to OBJFILE and then execute SCRIPT
as Python code. This does not throw any errors. If an exception
occurs python will print the traceback and clear the error indicator.
This is the extension_language_script_ops.objfile_script_executor
"method". */
static void
gdbpy_execute_objfile_script (const struct extension_language_defn *extlang,
struct objfile *objfile, const char *name,
const char *script)
{
struct cleanup *cleanups;
if (!gdb_python_initialized)
return;
cleanups = ensure_python_env (get_objfile_arch (objfile), current_language);
gdbpy_current_objfile = objfile;
PyRun_SimpleString (script);
do_cleanups (cleanups);
gdbpy_current_objfile = NULL;
}
/* Return the current Objfile, or None if there isn't one. */
static PyObject *

View File

@ -1,3 +1,14 @@
2015-01-31 Doug Evans <xdje42@gmail.com>
* gdb.guile/scm-section-script.c: Add duplicate inlined section script
entries. Duplicate file section script entries.
* gdb.guile/scm-section-script.exp: Add tests for duplicate entries,
inlined entries. Add test for safe-path rejection.
* gdb.python/py-section-script.c: Add duplicate inlined section script
entries. Duplicate file section script entries.
* gdb.python/py-section-script.exp: Add tests for duplicate entries,
inlined entries. Add test for safe-path rejection.
2015-01-29 Joel Brobecker <brobecker@adacore.com>
* gdb.ada/disc_arr_bound: New testcase.

View File

@ -19,17 +19,51 @@
#include "gdb/section-scripts.h"
/* Put the path to the pretty-printer script in .debug_gdb_scripts so
gdb will automagically loaded it. */
gdb will automagically loaded it.
Normally "MS" would appear here, as in
.pushsection ".debug_gdb_scripts", "MS",@progbits,1
but we remove it to test files appearing twice in the section. */
#define DEFINE_GDB_SCRIPT(script_name) \
asm("\
.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
.pushsection \".debug_gdb_scripts\", \"S\",@progbits\n\
.byte " XSTRING (SECTION_SCRIPT_ID_SCHEME_FILE) "\n\
.asciz \"" script_name "\"\n\
.popsection \n\
");
#ifndef SCRIPT_FILE
#error "SCRIPT_FILE not defined"
#endif
/* Specify it twice to verify the file is only loaded once. */
DEFINE_GDB_SCRIPT (SCRIPT_FILE)
DEFINE_GDB_SCRIPT (SCRIPT_FILE)
/* Inlined scripts are harder to create in the same way as
DEFINE_GDB_SCRIPT_FILE. Keep things simple and just define it here.
Normally "MS" would appear here, as in
.pushsection ".debug_gdb_scripts", "MS",@progbits,1
but we remove it to test scripts appearing twice in the section. */
#define DEFINE_GDB_SCRIPT_TEXT \
asm( \
".pushsection \".debug_gdb_scripts\", \"S\",@progbits\n" \
".byte " XSTRING (SECTION_SCRIPT_ID_SCHEME_TEXT) "\n" \
".ascii \"gdb.inlined-script\\n\"\n" \
".ascii \"(define test-cmd\\n\"\n" \
".ascii \" (make-command \\\"test-cmd\\\"\\n\"\n" \
".ascii \" #:command-class COMMAND_OBSCURE\\n\"\n" \
".ascii \" #:invoke (lambda (self arg from-tty)\\n\"\n" \
".ascii \" (display (format #f \\\"test-cmd output, arg = ~a\\n\\\" arg)))))\\n\"\n" \
".ascii \"(register-command! test-cmd)\\n\"\n" \
".byte 0\n" \
".popsection\n" \
);
/* Specify it twice to verify the script is only executed once. */
DEFINE_GDB_SCRIPT_TEXT
DEFINE_GDB_SCRIPT_TEXT
struct ss
{

View File

@ -53,14 +53,51 @@ gdb_start
if { [skip_guile_tests] } { continue }
gdb_reinitialize_dir $srcdir/$subdir
gdb_test_no_output "set auto-load safe-path ${remote_guile_file}" \
# Try first with a restrictive safe-path.
gdb_test_no_output "set auto-load safe-path /restricted" \
"set restricted auto-load safe-path"
gdb_load ${binfile}
# Verify gdb did not load the scripts.
set test_name "verify scripts not loaded"
gdb_test_multiple "info auto-load guile-scripts" "$test_name" {
-re "Yes.*${testfile}.scm.*Yes.*inlined-script.*$gdb_prompt $" {
fail "$test_name"
}
-re "No.*${testfile}.scm.*No.*inlined-script.*$gdb_prompt $" {
pass "$test_name"
}
}
# Try again with a working safe-path.
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_test_no_output "set auto-load safe-path ${remote_guile_file}:${binfile}" \
"set auto-load safe-path"
gdb_load ${binfile}
# Verify gdb loaded the script.
gdb_test "info auto-load guile-scripts" "Yes.*${testfile}.scm.*"
# Verify gdb loaded each script and they appear once in the list.
set test_name "verify scripts loaded"
gdb_test_multiple "info auto-load guile-scripts" "$test_name" {
-re "${testfile}.scm.*${testfile}.scm.*$gdb_prompt $" {
fail "$test_name"
}
-re "inlined-script.*inlined-script.*$gdb_prompt $" {
fail "$test_name"
}
-re "Yes.*${testfile}.scm.*Yes.*inlined-script.*$gdb_prompt $" {
pass "$test_name"
}
}
# Again, with a regexp this time.
gdb_test "info auto-load guile-scripts ${testfile}" "Yes.*${testfile}.scm.*"
# Again, with a regexp that matches no scripts.
gdb_test "info auto-load guile-scripts no-script-matches-this" \
"No auto-load scripts matching no-script-matches-this."
@ -74,3 +111,5 @@ gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
gdb_test "continue" ".*Breakpoint.*"
gdb_test "print ss" " = a=<1> b=<2>"
gdb_test "test-cmd 1 2 3" "test-cmd output, arg = 1 2 3"

View File

@ -15,18 +15,55 @@
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. */
#include "symcat.h"
#include "gdb/section-scripts.h"
#define DEFINE_GDB_SCRIPT(script_name) \
/* Put the path to the pretty-printer script in .debug_gdb_scripts so
gdb will automagically loaded it.
Normally "MS" would appear here, as in
.pushsection ".debug_gdb_scripts", "MS",@progbits,1
but we remove it to test files appearing twice in the section. */
#define DEFINE_GDB_SCRIPT_FILE(script_name) \
asm("\
.pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n\
.byte 1\n\
.pushsection \".debug_gdb_scripts\", \"S\",@progbits\n\
.byte " XSTRING (SECTION_SCRIPT_ID_PYTHON_FILE) "\n\
.asciz \"" script_name "\"\n\
.popsection \n\
.popsection\n\
");
DEFINE_GDB_SCRIPT (SCRIPT_FILE)
#ifndef SCRIPT_FILE
#error "SCRIPT_FILE not defined"
#endif
/* Specify it twice to verify the file is only loaded once. */
DEFINE_GDB_SCRIPT_FILE (SCRIPT_FILE)
DEFINE_GDB_SCRIPT_FILE (SCRIPT_FILE)
/* Inlined scripts are harder to create in the same way as
DEFINE_GDB_SCRIPT_FILE. Keep things simple and just define it here.
Normally "MS" would appear here, as in
.pushsection ".debug_gdb_scripts", "MS",@progbits,1
but we remove it to test scripts appearing twice in the section. */
#define DEFINE_GDB_SCRIPT_TEXT \
asm( \
".pushsection \".debug_gdb_scripts\", \"S\",@progbits\n" \
".byte " XSTRING (SECTION_SCRIPT_ID_PYTHON_TEXT) "\n" \
".ascii \"gdb.inlined-script\\n\"\n" \
".ascii \"class test_cmd (gdb.Command):\\n\"\n" \
".ascii \" def __init__ (self):\\n\"\n" \
".ascii \" super (test_cmd, self).__init__ (\\\"test-cmd\\\", gdb.COMMAND_OBSCURE)\\n\"\n" \
".ascii \" def invoke (self, arg, from_tty):\\n\"\n" \
".ascii \" print (\\\"test-cmd output, arg = %s\\\" % arg)\\n\"\n" \
".ascii \"test_cmd ()\\n\"\n" \
".byte 0\n" \
".popsection\n" \
);
/* Specify it twice to verify the script is only executed once. */
DEFINE_GDB_SCRIPT_TEXT
DEFINE_GDB_SCRIPT_TEXT
struct ss
{

View File

@ -39,7 +39,9 @@ set remote_python_file [gdb_remote_download host \
set quoted_name "\"$remote_python_file\""
if {[build_executable $testfile.exp $testfile $srcfile \
[list debug additional_flags=-DSCRIPT_FILE=$quoted_name]] == -1} {
[list debug \
additional_flags=-I${srcdir}/../../include \
additional_flags=-DSCRIPT_FILE=$quoted_name]] == -1} {
return -1
}
@ -51,13 +53,51 @@ gdb_start
if { [skip_python_tests] } { continue }
gdb_reinitialize_dir $srcdir/$subdir
gdb_test_no_output "set auto-load safe-path ${remote_python_file}" "set auto-load safe-path"
# Try first with a restrictive safe-path.
gdb_test_no_output "set auto-load safe-path /restricted" \
"set restricted auto-load safe-path"
gdb_load ${binfile}
# Verify gdb loaded the script.
gdb_test "info auto-load python-scripts" "Yes.*${testfile}.py.*"
# Verify gdb did not load the scripts.
set test_name "verify scripts not loaded"
gdb_test_multiple "info auto-load python-scripts" "$test_name" {
-re "Yes.*${testfile}.py.*Yes.*inlined-script.*$gdb_prompt $" {
fail "$test_name"
}
-re "No.*${testfile}.py.*No.*inlined-script.*$gdb_prompt $" {
pass "$test_name"
}
}
# Try again with a working safe-path.
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_test_no_output "set auto-load safe-path ${remote_python_file}:${binfile}" \
"set auto-load safe-path"
gdb_load ${binfile}
# Verify gdb loaded each script and they appear once in the list.
set test_name "verify scripts loaded"
gdb_test_multiple "info auto-load python-scripts" "$test_name" {
-re "${testfile}.py.*${testfile}.py.*$gdb_prompt $" {
fail "$test_name"
}
-re "inlined-script.*inlined-script.*$gdb_prompt $" {
fail "$test_name"
}
-re "Yes.*${testfile}.py.*Yes.*inlined-script.*$gdb_prompt $" {
pass "$test_name"
}
}
# Again, with a regexp this time.
gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*"
# Again, with a regexp that matches no scripts.
gdb_test "info auto-load python-scripts no-script-matches-this" \
"No auto-load scripts matching no-script-matches-this."
@ -72,3 +112,5 @@ gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
gdb_test "continue" ".*Breakpoint.*"
gdb_test "print ss" " = a=<1> b=<2>"
gdb_test "test-cmd 1 2 3" "test-cmd output, arg = 1 2 3"

View File

@ -1,3 +1,9 @@
2015-01-31 Doug Evans <xdje42@gmail.com>
* section-scripts.h: Remove "future extension" comment.
(SECTION_SCRIPT_ID_PYTHON_TEXT): New macro.
(SECTION_SCRIPT_ID_SCHEME_TEXT): New macro.
2014-12-03 Joel Brobecker <brobecker@adacore.com>
* callback.h (struct host_callback_struct) <to_stat>: Renamed

View File

@ -28,8 +28,6 @@
Other unused values needn't specify different scripting languages,
but we have no need for anything else at the moment.
Future extension: Include the contents of the script in the section.
These values are defined as macros so that they can be used in embedded
asms and assembler source files. */
@ -47,4 +45,18 @@
file. */
#define SECTION_SCRIPT_ID_SCHEME_FILE 3
/* The record is a nul-terminated string.
The first line is the name of the script.
Subsequent lines are interpreted as a python script. */
#define SECTION_SCRIPT_ID_PYTHON_TEXT 4
/* Native GDB scripts are not currently supported in .debug_gdb_scripts,
but we reserve a value for it. */
/*#define SECTION_SCRIPT_ID_GDB_TEXT 5*/
/* The record is a nul-terminated string.
The first line is the name of the script.
Subsequent lines are interpreted as a guile(scheme) script. */
#define SECTION_SCRIPT_ID_SCHEME_TEXT 6
#endif /* GDB_SECTION_SCRIPTS_H */