diff options
author | John Baldwin <jhb@FreeBSD.org> | 2021-01-01 00:00:54 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2021-01-01 00:00:54 +0000 |
commit | 9acce1c99299b5b59998e2d0c461bcf01d959374 (patch) | |
tree | fbcae7fb8470b8a08ea16d0646550367b8a97082 | |
parent | 4e7d1b527c1ef77851b15f65e2d78b8017b669aa (diff) |
Enumerate processes via the pid hash table in kdb_thr_*().
Processes part way through exit1() are not included in allproc. Using
allproc to enumerate processes prevented getting the stack trace of a
thread in this part of exit1() via ddb.
Reviewed by: kib
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D27826
-rw-r--r-- | sys/kern/subr_kdb.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index 4fa35064cb54..04b9b5a838df 100644 --- a/sys/kern/subr_kdb.c +++ b/sys/kern/subr_kdb.c @@ -586,12 +586,15 @@ kdb_thr_first(void) { struct proc *p; struct thread *thr; - - FOREACH_PROC_IN_SYSTEM(p) { - if (p->p_flag & P_INMEM) { - thr = FIRST_THREAD_IN_PROC(p); - if (thr != NULL) - return (thr); + u_int i; + + for (i = 0; i <= pidhash; i++) { + LIST_FOREACH(p, &pidhashtbl[i], p_hash) { + if (p->p_flag & P_INMEM) { + thr = FIRST_THREAD_IN_PROC(p); + if (thr != NULL) + return (thr); + } } } return (NULL); @@ -602,7 +605,7 @@ kdb_thr_from_pid(pid_t pid) { struct proc *p; - FOREACH_PROC_IN_SYSTEM(p) { + LIST_FOREACH(p, PIDHASH(pid), p_hash) { if (p->p_flag & P_INMEM && p->p_pid == pid) return (FIRST_THREAD_IN_PROC(p)); } @@ -624,17 +627,23 @@ struct thread * kdb_thr_next(struct thread *thr) { struct proc *p; + u_int hash; p = thr->td_proc; thr = TAILQ_NEXT(thr, td_plist); - do { - if (thr != NULL) - return (thr); - p = LIST_NEXT(p, p_list); - if (p != NULL && (p->p_flag & P_INMEM)) - thr = FIRST_THREAD_IN_PROC(p); - } while (p != NULL); - return (NULL); + if (thr != NULL) + return (thr); + hash = p->p_pid & pidhash; + for (;;) { + p = LIST_NEXT(p, p_hash); + while (p == NULL) { + if (++hash > pidhash) + return (NULL); + p = LIST_FIRST(&pidhashtbl[hash]); + } + if (p->p_flag & P_INMEM) + return (FIRST_THREAD_IN_PROC(p)); + } } int |