PERFORCE change 57628 for review
David Xu
davidxu at FreeBSD.org
Sun Jul 18 06:34:30 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=57628
Change 57628 by davidxu at davidxu_alona on 2004/07/18 13:34:11
Rewrite fbsd_thread_resume. Use ptrace to control LWP, when single stepping
a thread, we don't use td_thr_dbsuspend or td_thr_dbresume, I think those
two functions are used by user on command line to suspend/resume thread,
do not try to use them internally, it may involve too much thing not related
to single stepping. because we now bind thread in kernel if the thread
generates a SIGTRAP, we are safe to single step it without bothering UTS which
may can not run when process stops. Current, I still use PT_SUSPEND PT_RESUME,
I think we may need change ptrace code to let PT_CONTINUE/PT_STEP resume
only one LWP, TBD...
Affected files ...
.. //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#14 edit
Differences ...
==== //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#14 (text+ko) ====
@@ -70,7 +70,7 @@
static td_thragent_t *thread_agent;
/* The last thread we are single stepping */
-static ptid_t last_single_step_thread;
+static lwpid_t last_single_step_lwp;
/* Pointers to the libthread_db functions. */
@@ -316,7 +316,6 @@
gdb_assert (proc_handle.pid == 0);
keep_thread_db = 1;
}
-
/* We can only poke around if there actually is a child process.
If there is no child process alive, postpone the steps below
until one has been created. */
@@ -383,7 +382,7 @@
td_thrinfo_t ti;
ptid_t work_ptid;
int resume_all, ret;
- long lwp, thvalid = 0;
+ long lwp;
#if 0
printf_filtered("%s ptid=%ld.%ld.%ld step=%d\n", __func__,
@@ -399,7 +398,7 @@
return;
}
- if (GET_PID(ptid) != -1 && step != 0)
+ if (GET_PID (ptid) != -1 && step != 0)
{
resume_all = 0;
work_ptid = ptid;
@@ -432,49 +431,59 @@
ret = td_thr_get_info_p (&th, &ti);
if (ret)
error (thread_db_err_str (ret));
- thvalid = 1;
lwp = ti.ti_lid;
}
+ if (!resume_all && lwp == 0)
+ {
+ error ("sorry this version of FreeBSD can not resume inactivated thread");
+ }
+
if (lwp)
{
int req = step ? PT_SETSTEP : PT_CLEARSTEP;
- if (ptrace (req, (pid_t) lwp, (caddr_t) 1, target_signal_to_host(signo)))
+ if (ptrace (req, (pid_t) lwp, 0, 0))
perror_with_name ("PT_SETSTEP/PT_CLEARSTEP");
}
- if (!ptid_equal (last_single_step_thread, null_ptid))
+ int nlwps = ptrace (PT_GETNUMLWPS, proc_handle.pid, 0, 0);
+ if (nlwps == -1)
+ perror_with_name ("PT_GETNUMLWPS");
+ lwpid_t *lwps = malloc (nlwps * sizeof(lwpid_t));
+ nlwps = ptrace (PT_GETLWPLIST, proc_handle.pid, (caddr_t)lwps, nlwps);
+ if (nlwps == -1)
{
- ret = td_ta_thr_iter_p (thread_agent, resume_thread_callback, NULL,
- TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
- TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
- if (ret != TD_OK)
- error ("resume error: %s", thread_db_err_str (ret));
+ perror_with_name ("PT_GETLWPLIST");
+ free (lwps);
}
- if (!resume_all)
+ int i;
+ if (last_single_step_lwp != 0)
{
- ret = td_ta_thr_iter_p (thread_agent, suspend_thread_callback, NULL,
- TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
- TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
- if (ret != TD_OK)
- error ("suspend error: %s", thread_db_err_str (ret));
- last_single_step_thread = work_ptid;
+ /* resume all threads if ever suspend them */
+ for (i = 0; i < nlwps; ++i)
+ {
+ if (ptrace (PT_RESUME, lwps[i], 0, 0))
+ perror_with_name ("PT_SUSPEND");
+ }
}
- else
- last_single_step_thread = null_ptid;
- if (thvalid)
+ if (!resume_all)
{
- ret = td_thr_dbresume_p (&th);
- if (ret != TD_OK)
- error ("resume error: %s", thread_db_err_str (ret));
+ for (i = 0; i < nlwps; ++i)
+ {
+ if (lwps[i] == lwp)
+ continue;
+ if (ptrace (PT_SUSPEND, lwps[i], 0, 0))
+ perror_with_name ("PT_SUSPEND");
+ }
+ last_single_step_lwp = lwp;
}
else
- {
- /* it is not necessary, put it here for completness */
- ret = ptrace(PT_RESUME, lwp, 0, 0);
- }
+ last_single_step_lwp = 0;
+
+ free (lwps);
+/* ret = ptrace(PT_RESUME, lwp, 0, 0); */
/* now continue the process, suspended thread wont run */
if (ptrace (PT_CONTINUE, proc_handle.pid , (caddr_t)1,
@@ -496,6 +505,17 @@
ret = thread_from_lwp (BUILD_LWP (lwp, GET_PID (ret)));
if (!in_thread_list (ret))
add_thread (ret);
+ /* this is a hack, if an event won't cause gdb to stop, for example,
+ SIGARLM, gdb resumes the process immediatly without setting
+ inferior_ptid to the new thread returned here, this is a bug
+ because inferior_ptid may already not exist there, and passing
+ a none existing thread to fbsd_thread_resume causes error, this
+ should be treated as a bug of gdb. */
+ if (!fbsd_thread_alive (inferior_ptid))
+ {
+ delete_thread (inferior_ptid);
+ inferior_ptid = ret;
+ }
}
return (ret);
More information about the p4-projects
mailing list