PR corefile/8210

* linux-thread-db.c (add_thread_db_info): Skip glibc/BZ5983
	workaround on core files.
	(try_thread_db_load_1): Don't try enabling thread event reporting
	on core files.
	(thread_db_load): Allow thread_db on core files.
	(attach_thread): Don't check thread signals on core files, nor try
	really attaching to the thread, nor enabling thread event event
	reporting.
	(thread_db_detach): Don't try disabing thread event reporting or
	removing thread event breakpoints when debugging a core file.
	(find_new_threads_callback): Don't try enabling thread event
	reporting on core files.
	(thread_db_find_new_threads_2): Don't look for a stopped lwp when
	debugging a core file.
	(thread_db_find_new_threads): Don't update thread
	cores (processors) when debugging a core (dump).
This commit is contained in:
Pedro Alves
2010-08-18 12:25:49 +00:00
parent 261b8d0859
commit 856d6f99ff
2 changed files with 73 additions and 31 deletions

View File

@ -1,3 +1,24 @@
2010-08-18 Pedro Alves <pedro@codesourcery.com>
PR corefile/8210
* linux-thread-db.c (add_thread_db_info): Skip glibc/BZ5983
workaround on core files.
(try_thread_db_load_1): Don't try enabling thread event reporting
on core files.
(thread_db_load): Allow thread_db on core files.
(attach_thread): Don't check thread signals on core files, nor try
really attaching to the thread, nor enabling thread event event
reporting.
(thread_db_detach): Don't try disabing thread event reporting or
removing thread event breakpoints when debugging a core file.
(find_new_threads_callback): Don't try enabling thread event
reporting on core files.
(thread_db_find_new_threads_2): Don't look for a stopped lwp when
debugging a core file.
(thread_db_find_new_threads): Don't update thread
cores (processors) when debugging a core (dump).
2010-08-18 Pedro Alves <pedro@codesourcery.com> 2010-08-18 Pedro Alves <pedro@codesourcery.com>
PR corefile/8210 PR corefile/8210

View File

@ -189,7 +189,11 @@ add_thread_db_info (void *handle)
info = xcalloc (1, sizeof (*info)); info = xcalloc (1, sizeof (*info));
info->pid = ptid_get_pid (inferior_ptid); info->pid = ptid_get_pid (inferior_ptid);
info->handle = handle; info->handle = handle;
info->need_stale_parent_threads_check = 1;
/* The workaround works by reading from /proc/pid/status, so it is
disabled for core files. */
if (target_has_execution)
info->need_stale_parent_threads_check = 1;
info->next = thread_db_list; info->next = thread_db_list;
thread_db_list = info; thread_db_list = info;
@ -737,7 +741,9 @@ try_thread_db_load_1 (struct thread_db_info *info)
if (thread_db_list->next == NULL) if (thread_db_list->next == NULL)
push_target (&thread_db_ops); push_target (&thread_db_ops);
enable_thread_event_reporting (); /* Enable event reporting, but not when debugging a core file. */
if (target_has_execution)
enable_thread_event_reporting ();
/* There appears to be a bug in glibc-2.3.6: calls to td_thr_get_info fail /* There appears to be a bug in glibc-2.3.6: calls to td_thr_get_info fail
with TD_ERR for statically linked executables if td_thr_get_info is with TD_ERR for statically linked executables if td_thr_get_info is
@ -869,13 +875,13 @@ thread_db_load (void)
if (info != NULL) if (info != NULL)
return 1; return 1;
/* Don't attempt to use thread_db on targets which can not run /* Don't attempt to use thread_db on executables not running
(executables not running yet, core files) for now. */ yet. */
if (!target_has_execution) if (!target_has_registers)
return 0; return 0;
/* Don't attempt to use thread_db for remote targets. */ /* Don't attempt to use thread_db for remote targets. */
if (!target_can_run (&current_target)) if (!(target_can_run (&current_target) || core_bfd))
return 0; return 0;
if (thread_db_load_search ()) if (thread_db_load_search ())
@ -1030,13 +1036,15 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
} }
} }
check_thread_signals (); if (target_has_execution)
check_thread_signals ();
if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE) if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
return 0; /* A zombie thread -- do not attach. */ return 0; /* A zombie thread -- do not attach. */
/* Under GNU/Linux, we have to attach to each and every thread. */ /* Under GNU/Linux, we have to attach to each and every thread. */
if (tp == NULL if (target_has_execution
&& tp == NULL
&& lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0) && lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0)
return 0; return 0;
@ -1061,11 +1069,16 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
info = get_thread_db_info (GET_PID (ptid)); info = get_thread_db_info (GET_PID (ptid));
/* Enable thread event reporting for this thread. */ /* Enable thread event reporting for this thread, except when
err = info->td_thr_event_enable_p (th_p, 1); debugging a core file. */
if (err != TD_OK) if (target_has_execution)
error (_("Cannot enable thread event reporting for %s: %s"), {
target_pid_to_str (ptid), thread_db_err_str (err)); err = info->td_thr_event_enable_p (th_p, 1);
if (err != TD_OK)
error (_("Cannot enable thread event reporting for %s: %s"),
target_pid_to_str (ptid), thread_db_err_str (err));
}
return 1; return 1;
} }
@ -1097,14 +1110,17 @@ thread_db_detach (struct target_ops *ops, char *args, int from_tty)
if (info) if (info)
{ {
disable_thread_event_reporting (info); if (target_has_execution)
{
disable_thread_event_reporting (info);
/* Delete the old thread event breakpoints. Note that unlike /* Delete the old thread event breakpoints. Note that
when mourning, we can remove them here because there's still unlike when mourning, we can remove them here because
a live inferior to poke at. In any case, GDB will not try to there's still a live inferior to poke at. In any case,
insert anything in the inferior when removing a GDB will not try to insert anything in the inferior when
breakpoint. */ removing a breakpoint. */
remove_thread_event_breakpoints (); remove_thread_event_breakpoints ();
}
delete_thread_db_info (GET_PID (inferior_ptid)); delete_thread_db_info (GET_PID (inferior_ptid));
} }
@ -1317,7 +1333,7 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
return 0; /* A zombie -- ignore. */ return 0; /* A zombie -- ignore. */
if (ti.ti_tid == 0) if (ti.ti_tid == 0 && target_has_execution)
{ {
/* A thread ID of zero means that this is the main thread, but /* A thread ID of zero means that this is the main thread, but
glibc has not yet initialized thread-local storage and the glibc has not yet initialized thread-local storage and the
@ -1417,19 +1433,23 @@ static void
thread_db_find_new_threads_2 (ptid_t ptid, int until_no_new) thread_db_find_new_threads_2 (ptid_t ptid, int until_no_new)
{ {
td_err_e err; td_err_e err;
struct lwp_info *lp;
struct thread_db_info *info; struct thread_db_info *info;
int pid = ptid_get_pid (ptid); int pid = ptid_get_pid (ptid);
int i, loop; int i, loop;
/* In linux, we can only read memory through a stopped lwp. */ if (target_has_execution)
ALL_LWPS (lp, ptid) {
if (lp->stopped && ptid_get_pid (lp->ptid) == pid) struct lwp_info *lp;
break;
if (!lp) /* In linux, we can only read memory through a stopped lwp. */
/* There is no stopped thread. Bail out. */ ALL_LWPS (lp, ptid)
return; if (lp->stopped && ptid_get_pid (lp->ptid) == pid)
break;
if (!lp)
/* There is no stopped thread. Bail out. */
return;
}
info = get_thread_db_info (GET_PID (ptid)); info = get_thread_db_info (GET_PID (ptid));
@ -1480,8 +1500,9 @@ thread_db_find_new_threads (struct target_ops *ops)
thread_db_find_new_threads_1 (inferior_ptid); thread_db_find_new_threads_1 (inferior_ptid);
iterate_over_lwps (minus_one_ptid /* iterate over all */, if (target_has_execution)
update_thread_core, NULL); iterate_over_lwps (minus_one_ptid /* iterate over all */,
update_thread_core, NULL);
} }
static char * static char *