aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/infcmd.c4
-rw-r--r--gdb/inferior.h4
-rw-r--r--gdb/infrun.c5
-rw-r--r--gdb/linux-thread-db.c24
-rw-r--r--gdb/remote.c22
6 files changed, 64 insertions, 7 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 53d77aa..05c307b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,15 @@
+2021-06-08 Simon Marchi <simon.marchi@polymtl.ca>
+
+ * inferior.h (class inferior) <in_initial_library_scan>: New.
+ * infcmd.c (post_create_inferior): Set in_initial_library_scan.
+ * infrun.c (follow_fork_inferior): Likewise.
+ * linux-thread-db.c (try_thread_db_load): Catch exception thrown
+ by try_thread_db_load_1
+ (thread_db_load): Return early if in_initial_library_scan is
+ set.
+ * remote.c (remote_new_objfile): Return early if
+ in_initial_library_scan is set.
+
2021-06-07 Pedro Alves <pedro@palves.net>
* dwarf2/read.c (struct partial_die_info): Add defaulted copy
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 38947ca..8190ba3 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -315,6 +315,10 @@ post_create_inferior (int from_tty)
const unsigned solib_add_generation
= current_program_space->solib_add_generation;
+ scoped_restore restore_in_initial_library_scan
+ = make_scoped_restore (&current_inferior ()->in_initial_library_scan,
+ true);
+
/* Create the hooks to handle shared library load and unload
events. */
solib_create_inferior_hook (from_tty);
diff --git a/gdb/inferior.h b/gdb/inferior.h
index f4b8b02..f61b588 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -522,6 +522,10 @@ public:
architecture/description. */
bool needs_setup = false;
+ /* True when we are reading the library list of the inferior during an
+ attach or handling a fork child. */
+ bool in_initial_library_scan = false;
+
/* Private data used by the target vector implementation. */
std::unique_ptr<private_inferior> priv;
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 488bcc1..4bd21fd 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -521,6 +521,9 @@ holding the child stopped. Try \"set detach-on-fork\" or \
breakpoint. If a "cloned-VM" event was propagated
better throughout the core, this wouldn't be
required. */
+ scoped_restore restore_in_initial_library_scan
+ = make_scoped_restore (&child_inf->in_initial_library_scan,
+ true);
solib_create_inferior_hook (0);
}
}
@@ -656,6 +659,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \
shared libraries, and install the solib event breakpoint.
If a "cloned-VM" event was propagated better throughout
the core, this wouldn't be required. */
+ scoped_restore restore_in_initial_library_scan
+ = make_scoped_restore (&child_inf->in_initial_library_scan, true);
solib_create_inferior_hook (0);
}
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 9925b02..d1e8c22 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -1012,8 +1012,17 @@ try_thread_db_load (const char *library, bool check_auto_load_safe)
if (strchr (library, '/') != NULL)
info->filename = gdb_realpath (library).release ();
- if (try_thread_db_load_1 (info))
- return true;
+ try
+ {
+ if (try_thread_db_load_1 (info))
+ return true;
+ }
+ catch (const gdb_exception_error &except)
+ {
+ if (libthread_db_debug)
+ exception_fprintf (gdb_stdlog, except,
+ "Warning: While trying to load libthread_db: ");
+ }
/* This library "refused" to work on current inferior. */
delete_thread_db_info (current_inferior ()->process_target (),
@@ -1184,10 +1193,15 @@ has_libpthread (void)
static bool
thread_db_load (void)
{
- struct thread_db_info *info;
+ inferior *inf = current_inferior ();
- info = get_thread_db_info (current_inferior ()->process_target (),
- inferior_ptid.pid ());
+ /* When attaching / handling fork child, don't try loading libthread_db
+ until we know about all shared libraries. */
+ if (inf->in_initial_library_scan)
+ return false;
+
+ thread_db_info *info = get_thread_db_info (inf->process_target (),
+ inferior_ptid.pid ());
if (info != NULL)
return true;
diff --git a/gdb/remote.c b/gdb/remote.c
index de04aab..39bdd2e 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -14522,8 +14522,26 @@ remote_new_objfile (struct objfile *objfile)
{
remote_target *remote = get_current_remote_target ();
- if (remote != NULL) /* Have a remote connection. */
- remote->remote_check_symbols ();
+ /* First, check whether the current inferior's process target is a remote
+ target. */
+ if (remote == nullptr)
+ return;
+
+ /* When we are attaching or handling a fork child and the shared library
+ subsystem reads the list of loaded libraries, we receive new objfile
+ events in between each found library. The libraries are read in an
+ undefined order, so if we gave the remote side a chance to look up
+ symbols between each objfile, we might give it an inconsistent picture
+ of the inferior. It could appear that a library A appears loaded but
+ a library B does not, even though library A requires library B. That
+ would present a state that couldn't normally exist in the inferior.
+
+ So, skip these events, we'll give the remote a chance to look up symbols
+ once all the loaded libraries and their symbols are known to GDB. */
+ if (current_inferior ()->in_initial_library_scan)
+ return;
+
+ remote->remote_check_symbols ();
}
/* Pull all the tracepoints defined on the target and create local