| 2687 | |
| 2688 | #if defined(STACK) || defined(DDB) |
| 2689 | static int |
| 2690 | sysctl_kern_proc_kstack(SYSCTL_HANDLER_ARGS) |
| 2691 | { |
| 2692 | struct kinfo_kstack *kkstp; |
| 2693 | int error, i, *name, numthreads; |
| 2694 | lwpid_t *lwpidarray; |
| 2695 | struct thread *td; |
| 2696 | struct stack *st; |
| 2697 | struct sbuf sb; |
| 2698 | struct proc *p; |
| 2699 | |
| 2700 | name = (int *)arg1; |
| 2701 | error = pget((pid_t)name[0], PGET_NOTINEXEC | PGET_WANTREAD, &p); |
| 2702 | if (error != 0) |
| 2703 | return (error); |
| 2704 | |
| 2705 | kkstp = malloc(sizeof(*kkstp), M_TEMP, M_WAITOK); |
| 2706 | st = stack_create(M_WAITOK); |
| 2707 | |
| 2708 | lwpidarray = NULL; |
| 2709 | PROC_LOCK(p); |
| 2710 | do { |
| 2711 | if (lwpidarray != NULL) { |
| 2712 | free(lwpidarray, M_TEMP); |
| 2713 | lwpidarray = NULL; |
| 2714 | } |
| 2715 | numthreads = p->p_numthreads; |
| 2716 | PROC_UNLOCK(p); |
| 2717 | lwpidarray = malloc(sizeof(*lwpidarray) * numthreads, M_TEMP, |
| 2718 | M_WAITOK | M_ZERO); |
| 2719 | PROC_LOCK(p); |
| 2720 | } while (numthreads < p->p_numthreads); |
| 2721 | |
| 2722 | /* |
| 2723 | * XXXRW: During the below loop, execve(2) and countless other sorts |
| 2724 | * of changes could have taken place. Should we check to see if the |
| 2725 | * vmspace has been replaced, or the like, in order to prevent |
| 2726 | * giving a snapshot that spans, say, execve(2), with some threads |
| 2727 | * before and some after? Among other things, the credentials could |
| 2728 | * have changed, in which case the right to extract debug info might |
| 2729 | * no longer be assured. |
| 2730 | */ |
| 2731 | i = 0; |
| 2732 | FOREACH_THREAD_IN_PROC(p, td) { |
| 2733 | KASSERT(i < numthreads, |
| 2734 | ("sysctl_kern_proc_kstack: numthreads")); |
| 2735 | lwpidarray[i] = td->td_tid; |
| 2736 | i++; |
| 2737 | } |
| 2738 | PROC_UNLOCK(p); |
| 2739 | numthreads = i; |
| 2740 | for (i = 0; i < numthreads; i++) { |
| 2741 | td = tdfind(lwpidarray[i], p->p_pid); |
| 2742 | if (td == NULL) { |
| 2743 | continue; |
| 2744 | } |
| 2745 | bzero(kkstp, sizeof(*kkstp)); |
| 2746 | (void)sbuf_new(&sb, kkstp->kkst_trace, |
nothing calls this directly
no test coverage detected