Deleted Added
full compact
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}