Fix PR gdb/19676: Internal error in linux-thread.db.c if /proc not mounted

If /proc is not mounted, GDB fails an assertion in find_new_threads_once:

 Continuing.
 .../src/gdb/linux-thread-db.c:1249: internal-error: find_new_threads_once: Assertion `!target_has_execution' failed.
 A problem internal to GDB has been detected,
 further debugging may prove unreliable.
 Quit this debugging session? (y or n)

That was supposed to catch misuses of td_ta_thr_iter, which is unsafe
for live debugging.  However, if /proc is not mounted, we still
fallback to using it.

I didn't bother with a warning, because GDB already prints several
others related to failing to open /proc files.

gdb/ChangeLog:
2016-03-15  Pedro Alves  <palves@redhat.com>

	PR gdb/19676
	* linux-thread-db.c (try_thread_db_load_1): Leave
	info->td_ta_thr_iter_p NULL iff debugging a live process and we
	have /proc access.
	(find_new_threads_once): Assert that we have a non-NULL
	info->td_ta_thr_iter_p instead of checking whether the target has
	execution.
This commit is contained in:
Pedro Alves 2016-03-15 16:33:04 +00:00
parent 16b4184277
commit 1eb2dbb8d7
2 changed files with 20 additions and 6 deletions

View file

@ -1,3 +1,13 @@
2016-03-15 Pedro Alves <palves@redhat.com>
PR gdb/19676
* linux-thread-db.c (try_thread_db_load_1): Leave
info->td_ta_thr_iter_p NULL iff debugging a live process and we
have /proc access.
(find_new_threads_once): Assert that we have a non-NULL
info->td_ta_thr_iter_p instead of checking whether the target has
execution.
2016-03-15 Pedro Alves <palves@redhat.com> 2016-03-15 Pedro Alves <palves@redhat.com>
PR gdb/19676 PR gdb/19676

View file

@ -564,7 +564,6 @@ try_thread_db_load_1 (struct thread_db_info *info)
/* These are essential. */ /* These are essential. */
CHK (TDB_VERBOSE_DLSYM (info, td_ta_map_lwp2thr)); CHK (TDB_VERBOSE_DLSYM (info, td_ta_map_lwp2thr));
CHK (TDB_VERBOSE_DLSYM (info, td_ta_thr_iter));
CHK (TDB_VERBOSE_DLSYM (info, td_thr_validate)); CHK (TDB_VERBOSE_DLSYM (info, td_thr_validate));
CHK (TDB_VERBOSE_DLSYM (info, td_thr_get_info)); CHK (TDB_VERBOSE_DLSYM (info, td_thr_get_info));
@ -572,10 +571,6 @@ try_thread_db_load_1 (struct thread_db_info *info)
TDB_DLSYM (info, td_thr_tls_get_addr); TDB_DLSYM (info, td_thr_tls_get_addr);
TDB_DLSYM (info, td_thr_tlsbase); TDB_DLSYM (info, td_thr_tlsbase);
#undef TDB_VERBOSE_DLSYM
#undef TDB_DLSYM
#undef CHK
/* It's best to avoid td_ta_thr_iter if possible. That walks data /* It's best to avoid td_ta_thr_iter if possible. That walks data
structures in the inferior's address space that may be corrupted, structures in the inferior's address space that may be corrupted,
or, if the target is running, may change while we walk them. If or, if the target is running, may change while we walk them. If
@ -587,6 +582,15 @@ try_thread_db_load_1 (struct thread_db_info *info)
currently on core targets, as it uses ptrace directly. */ currently on core targets, as it uses ptrace directly. */
if (target_has_execution if (target_has_execution
&& linux_proc_task_list_dir_exists (ptid_get_pid (inferior_ptid))) && linux_proc_task_list_dir_exists (ptid_get_pid (inferior_ptid)))
info->td_ta_thr_iter_p = NULL;
else
CHK (TDB_VERBOSE_DLSYM (info, td_ta_thr_iter));
#undef TDB_VERBOSE_DLSYM
#undef TDB_DLSYM
#undef CHK
if (info->td_ta_thr_iter_p == NULL)
{ {
struct lwp_info *lp; struct lwp_info *lp;
int pid = ptid_get_pid (inferior_ptid); int pid = ptid_get_pid (inferior_ptid);
@ -1246,7 +1250,7 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
data.new_threads = 0; data.new_threads = 0;
/* See comment in thread_db_update_thread_list. */ /* See comment in thread_db_update_thread_list. */
gdb_assert (!target_has_execution); gdb_assert (info->td_ta_thr_iter_p != NULL);
TRY TRY
{ {