aboutsummaryrefslogtreecommitdiff
path: root/gdb/symfile.c
diff options
context:
space:
mode:
authorSandra Loosemore <sandra@codesourcery.com>2016-10-26 12:12:01 -0500
committerPedro Alves <palves@redhat.com>2016-10-26 16:47:46 +0100
commitecf45d2cc7667ed4692d07e52fc77a2c9a8adf1c (patch)
treeabc757e04ab221b35d3d0db5afba7f9f82da645a /gdb/symfile.c
parentb15cc25cbe7c13e450f77b4a309223b9b3da3936 (diff)
PR 20569, segv in follow_exec
The following testcases make GDB crash whenever an invalid sysroot is provided, when GDB is unable to find a valid path to the symbol file: gdb.base/catch-syscall.exp gdb.base/execl-update-breakpoints.exp gdb.base/foll-exec-mode.exp gdb.base/foll-exec.exp gdb.base/foll-vfork.exp gdb.base/pie-execl.exp gdb.multi/bkpt-multi-exec.exp gdb.python/py-finish-breakpoint.exp gdb.threads/execl.exp gdb.threads/non-ldr-exc-1.exp gdb.threads/non-ldr-exc-2.exp gdb.threads/non-ldr-exc-3.exp gdb.threads/non-ldr-exc-4.exp gdb.threads/thread-execl.exp The immediate cause of the segv is that follow_exec is passing a NULL argument (the result of exec_file_find) to strlen. However, the problem is deeper than that: follow_exec simply isn't prepared for the case where sysroot translation fails to locate the new executable. Actually all callers of exec_file_find have bugs due to confusion between host and target pathnames. This commit attempts to fix all that. In terms of the testcases that were formerly segv'ing, GDB now prints a warning but continues execution of the new program, so that the tests now mostly FAIL instead. You could argue the FAILs are due to a legitimate problem with the test environment setting up the sysroot translation incorrectly. A new representative test is added which exercises the ne wwarning code path even with native testing. Tested on x86_64 Fedora 23, native and gdbserver. gdb/ChangeLog: 2016-10-25 Sandra Loosemore <sandra@codesourcery.com> Luis Machado <lgustavo@codesourcery.com> Pedro Alves <palves@redhat.com> PR gdb/20569 * exceptions.c (exception_print_same): Moved here from exec.c. * exceptions.h (exception_print_same): Declare. * exec.h: Include "symfile-add-flags.h". (try_open_exec_file): New declaration. * exec.c (exception_print_same): Moved to exceptions.c. (try_open_exec_file): New function. (exec_file_locate_attach): Rename exec_file and full_exec_path variables to avoid confusion between target and host pathnames. Move pathname processing logic to exec_file_find. Do not return early if pathname lookup fails; Call try_open_exec_file. * infrun.c (follow_exec): Split and rename execd_pathname variable to avoid confusion between target and host pathnames. Warn if pathname lookup fails. Pass target pathname to target_follow_exec, not hostpathname. Call try_open_exec_file. * main.c (symbol_file_add_main_adapter): New function. (captured_main_1): Use it. * solib-svr4.c (open_symbol_file_object): Adjust to pass symfile_add_flags to symbol_file_add_main. * solib.c (exec_file_find): Incorporate fallback logic for relative pathnames formerly in exec_file_locate_attach. * symfile.c (symbol_file_add_main, symbol_file_add_main_1): Replace 'from_tty' parameter with a symfile_add_file. (symbol_file_command): Adjust to pass symfile_add_flags to symbol_file_add_main. * symfile.h (symbol_file_add_main): Replace 'from_tty' parameter with a symfile_add_file. gdb/testsuite/ChangeLog: 2016-10-25 Luis Machado <lgustavo@codesourcery.com> * gdb.base/exec-invalid-sysroot.exp: New file.
Diffstat (limited to 'gdb/symfile.c')
-rw-r--r--gdb/symfile.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 616fef0f8c..f524f56b36 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -85,7 +85,7 @@ int readnow_symbol_files; /* Read full symbols immediately. */
static void load_command (char *, int);
-static void symbol_file_add_main_1 (const char *args, int from_tty,
+static void symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags,
objfile_flags flags);
static void add_symbol_file_command (char *, int);
@@ -1306,19 +1306,16 @@ symbol_file_add (const char *name, symfile_add_flags add_flags,
command itself. */
void
-symbol_file_add_main (const char *args, int from_tty)
+symbol_file_add_main (const char *args, symfile_add_flags add_flags)
{
- symbol_file_add_main_1 (args, from_tty, 0);
+ symbol_file_add_main_1 (args, add_flags, 0);
}
static void
-symbol_file_add_main_1 (const char *args, int from_tty, objfile_flags flags)
+symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags,
+ objfile_flags flags)
{
- symfile_add_flags add_flags = (current_inferior ()->symfile_flags
- | SYMFILE_MAINLINE);
-
- if (from_tty)
- add_flags |= SYMFILE_VERBOSE;
+ add_flags |= current_inferior ()->symfile_flags | SYMFILE_MAINLINE;
symbol_file_add (args, add_flags, NULL, flags);
@@ -1655,9 +1652,13 @@ symbol_file_command (char *args, int from_tty)
{
char **argv = gdb_buildargv (args);
objfile_flags flags = OBJF_USERLOADED;
+ symfile_add_flags add_flags = 0;
struct cleanup *cleanups;
char *name = NULL;
+ if (from_tty)
+ add_flags |= SYMFILE_VERBOSE;
+
cleanups = make_cleanup_freeargv (argv);
while (*argv != NULL)
{
@@ -1667,7 +1668,7 @@ symbol_file_command (char *args, int from_tty)
error (_("unknown option `%s'"), *argv);
else
{
- symbol_file_add_main_1 (*argv, from_tty, flags);
+ symbol_file_add_main_1 (*argv, add_flags, flags);
name = *argv;
}