procstat_kstack.c (249685) | procstat_kstack.c (287486) |
---|---|
1/*- 2 * Copyright (c) 2007 Robert N. M. Watson | 1/*- 2 * Copyright (c) 2007 Robert N. M. Watson |
3 * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> |
|
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright --- 7 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright --- 7 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * |
26 * $FreeBSD: head/usr.bin/procstat/procstat_kstack.c 249685 2013-04-20 08:19:06Z trociny $ | 27 * $FreeBSD: head/usr.bin/procstat/procstat_kstack.c 287486 2015-09-05 17:02:01Z allanjude $ |
27 */ 28 29#include <sys/param.h> 30#include <sys/sysctl.h> 31#include <sys/user.h> 32 33#include <err.h> 34#include <errno.h> --- 65 unchanged lines hidden (view full) --- 100 if (ts == TS_FUNC || (kflag > 1 && ts == TS_OFF)) { 101 *cp_new = *cp_old; 102 cp_new++; 103 } 104 } 105 *cp_new = '\0'; 106} 107 | 28 */ 29 30#include <sys/param.h> 31#include <sys/sysctl.h> 32#include <sys/user.h> 33 34#include <err.h> 35#include <errno.h> --- 65 unchanged lines hidden (view full) --- 101 if (ts == TS_FUNC || (kflag > 1 && ts == TS_OFF)) { 102 *cp_new = *cp_old; 103 cp_new++; 104 } 105 } 106 *cp_new = '\0'; 107} 108 |
109static void 110kstack_cleanup_encoded(const char *old, char *new, int kflag) 111{ 112 enum trace_state old_ts, ts; 113 const char *cp_old; 114 char *cp_new, *cp_loop, *cp_tofree, *cp_line; 115 116 ts = TS_FRAMENUM; 117 if (kflag == 1) { 118 for (cp_old = old, cp_new = new; *cp_old != '\0'; cp_old++) { 119 switch (*cp_old) { 120 case '\n': 121 *cp_new = *cp_old; 122 cp_new++; 123 case ' ': 124 case '+': 125 old_ts = ts; 126 ts = kstack_nextstate(old_ts); 127 continue; 128 } 129 if (ts == TS_FUNC) { 130 *cp_new = *cp_old; 131 cp_new++; 132 } 133 } 134 cp_tofree = cp_loop = strdup(new); 135 } else 136 cp_tofree = cp_loop = strdup(old); 137 while ((cp_line = strsep(&cp_loop, "\n")) != NULL) { 138 if (strlen(cp_line) != 0 && *cp_line != 127) 139 xo_emit("{le:token/%s}", cp_line); 140 } 141 *cp_new = '\0'; 142 free(cp_tofree); 143} 144 |
|
108/* 109 * Sort threads by tid. 110 */ 111static int 112kinfo_kstack_compare(const void *a, const void *b) 113{ 114 115 return ((const struct kinfo_kstack *)a)->kkst_tid - --- 8 unchanged lines hidden (view full) --- 124} 125 126 127void 128procstat_kstack(struct procstat *procstat, struct kinfo_proc *kipp, int kflag) 129{ 130 struct kinfo_kstack *kkstp, *kkstp_free; 131 struct kinfo_proc *kip, *kip_free; | 145/* 146 * Sort threads by tid. 147 */ 148static int 149kinfo_kstack_compare(const void *a, const void *b) 150{ 151 152 return ((const struct kinfo_kstack *)a)->kkst_tid - --- 8 unchanged lines hidden (view full) --- 161} 162 163 164void 165procstat_kstack(struct procstat *procstat, struct kinfo_proc *kipp, int kflag) 166{ 167 struct kinfo_kstack *kkstp, *kkstp_free; 168 struct kinfo_proc *kip, *kip_free; |
132 char trace[KKST_MAXLEN]; | 169 char trace[KKST_MAXLEN], encoded_trace[KKST_MAXLEN]; |
133 unsigned int i, j; 134 unsigned int kip_count, kstk_count; 135 136 if (!hflag) | 170 unsigned int i, j; 171 unsigned int kip_count, kstk_count; 172 173 if (!hflag) |
137 printf("%5s %6s %-16s %-16s %-29s\n", "PID", "TID", "COMM", | 174 xo_emit("{T:/%5s %6s %-16s %-16s %-29s}\n", "PID", "TID", "COMM", |
138 "TDNAME", "KSTACK"); 139 140 kkstp = kkstp_free = procstat_getkstack(procstat, kipp, &kstk_count); 141 if (kkstp == NULL) 142 return; 143 144 /* 145 * We need to re-query for thread information, so don't use *kipp. --- 18 unchanged lines hidden (view full) --- 164 for (j = 0; j < kip_count; j++) { 165 kipp = &kip_free[j]; 166 if (kkstp->kkst_tid == kipp->ki_tid) 167 break; 168 } 169 if (kipp == NULL) 170 continue; 171 | 175 "TDNAME", "KSTACK"); 176 177 kkstp = kkstp_free = procstat_getkstack(procstat, kipp, &kstk_count); 178 if (kkstp == NULL) 179 return; 180 181 /* 182 * We need to re-query for thread information, so don't use *kipp. --- 18 unchanged lines hidden (view full) --- 201 for (j = 0; j < kip_count; j++) { 202 kipp = &kip_free[j]; 203 if (kkstp->kkst_tid == kipp->ki_tid) 204 break; 205 } 206 if (kipp == NULL) 207 continue; 208 |
172 printf("%5d ", kipp->ki_pid); 173 printf("%6d ", kkstp->kkst_tid); 174 printf("%-16s ", kipp->ki_comm); 175 printf("%-16s ", (strlen(kipp->ki_tdname) && | 209 xo_emit("{k:process_id/%5d/%d} ", kipp->ki_pid); 210 xo_emit("{:thread_id/%6d/%d} ", kkstp->kkst_tid); 211 xo_emit("{:command/%-16s/%s} ", kipp->ki_comm); 212 xo_emit("{:thread_name/%-16s/%s} ", (strlen(kipp->ki_tdname) && |
176 (strcmp(kipp->ki_comm, kipp->ki_tdname) != 0)) ? 177 kipp->ki_tdname : "-"); 178 179 switch (kkstp->kkst_state) { 180 case KKST_STATE_RUNNING: | 213 (strcmp(kipp->ki_comm, kipp->ki_tdname) != 0)) ? 214 kipp->ki_tdname : "-"); 215 216 switch (kkstp->kkst_state) { 217 case KKST_STATE_RUNNING: |
181 printf("%-29s\n", "<running>"); | 218 xo_emit("{:state/%-29s/%s}\n", "<running>"); |
182 continue; 183 184 case KKST_STATE_SWAPPED: | 219 continue; 220 221 case KKST_STATE_SWAPPED: |
185 printf("%-29s\n", "<swapped>"); | 222 xo_emit("{:state/%-29s/%s}\n", "<swapped>"); |
186 continue; 187 188 case KKST_STATE_STACKOK: 189 break; 190 191 default: | 223 continue; 224 225 case KKST_STATE_STACKOK: 226 break; 227 228 default: |
192 printf("%-29s\n", "<unknown>"); | 229 xo_emit("{:state/%-29s/%s}\n", "<unknown>"); |
193 continue; 194 } 195 196 /* 197 * The kernel generates a trace with carriage returns between 198 * entries, but for a more compact view, we convert carriage 199 * returns to spaces. 200 */ 201 kstack_cleanup(kkstp->kkst_trace, trace, kflag); | 230 continue; 231 } 232 233 /* 234 * The kernel generates a trace with carriage returns between 235 * entries, but for a more compact view, we convert carriage 236 * returns to spaces. 237 */ 238 kstack_cleanup(kkstp->kkst_trace, trace, kflag); |
202 printf("%-29s\n", trace); | 239 xo_open_list("trace"); 240 kstack_cleanup_encoded(kkstp->kkst_trace, encoded_trace, kflag); 241 xo_close_list("trace"); 242 xo_emit("{d:trace/%-29s}\n", trace); |
203 } 204 procstat_freekstack(procstat, kkstp_free); 205 procstat_freeprocs(procstat, kip_free); 206} | 243 } 244 procstat_freekstack(procstat, kkstp_free); 245 procstat_freeprocs(procstat, kip_free); 246} |