Fix: add missing semicolons after MSG, DBG, ERR print macros
[lttng-tools.git] / src / bin / lttng / commands / add_context.c
CommitLineData
d65106b1
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
d14d33bf
AM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
d65106b1
DG
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
d14d33bf
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
d65106b1
DG
16 */
17
18#define _GNU_SOURCE
6c1c0768 19#define _LGPL_SOURCE
90b9a268 20#include <ctype.h>
d65106b1
DG
21#include <popt.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <unistd.h>
66c214cd 28#include <assert.h>
d65106b1 29
3301e740
DG
30#include <urcu/list.h>
31
89b72577
JRJ
32#include <common/mi-lttng.h>
33
c399183f 34#include "../command.h"
d65106b1 35
b13d56d7
MD
36#define PRINT_LINE_LEN 80
37
d65106b1 38static char *opt_channel_name;
5440dc42 39static char *opt_session_name;
55cc08a6 40static int opt_kernel;
d65106b1 41static int opt_userspace;
d78d6610 42static char *opt_type;
89b72577 43
d78d6610
DG
44#if 0
45/* Not implemented yet */
eeac7d46 46static char *opt_cmd_name;
d65106b1 47static pid_t opt_pid;
d78d6610 48#endif
d65106b1
DG
49
50enum {
51 OPT_HELP = 1,
52 OPT_TYPE,
eeac7d46 53 OPT_USERSPACE,
679b4943 54 OPT_LIST_OPTIONS,
d65106b1
DG
55};
56
cd80958d 57static struct lttng_handle *handle;
89b72577 58static struct mi_writer *writer;
cd80958d 59
90b9a268
DG
60/*
61 * Taken from the LTTng ABI
62 */
63enum context_type {
64 CONTEXT_PID = 0,
aa3514e9 65 CONTEXT_PERF_COUNTER = 1, /* Backward compat. */
95da1297 66 CONTEXT_PROCNAME = 2,
90b9a268
DG
67 CONTEXT_PRIO = 3,
68 CONTEXT_NICE = 4,
69 CONTEXT_VPID = 5,
70 CONTEXT_TID = 6,
71 CONTEXT_VTID = 7,
72 CONTEXT_PPID = 8,
73 CONTEXT_VPPID = 9,
9197c5c4 74 CONTEXT_PTHREAD_ID = 10,
54773d68 75 CONTEXT_HOSTNAME = 11,
7c612c2e 76 CONTEXT_IP = 12,
aa3514e9
MD
77 CONTEXT_PERF_CPU_COUNTER = 13,
78 CONTEXT_PERF_THREAD_COUNTER = 14,
3301e740
DG
79};
80
90b9a268
DG
81/*
82 * Taken from the Perf ABI (all enum perf_*)
83 */
84enum perf_type {
85 PERF_TYPE_HARDWARE = 0,
86 PERF_TYPE_SOFTWARE = 1,
b13d56d7 87 PERF_TYPE_HW_CACHE = 3,
3301e740
DG
88};
89
90b9a268 90enum perf_count_hard {
b13d56d7
MD
91 PERF_COUNT_HW_CPU_CYCLES = 0,
92 PERF_COUNT_HW_INSTRUCTIONS = 1,
93 PERF_COUNT_HW_CACHE_REFERENCES = 2,
94 PERF_COUNT_HW_CACHE_MISSES = 3,
95 PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
96 PERF_COUNT_HW_BRANCH_MISSES = 5,
97 PERF_COUNT_HW_BUS_CYCLES = 6,
98 PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
99 PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
90b9a268
DG
100};
101
102enum perf_count_soft {
103 PERF_COUNT_SW_CPU_CLOCK = 0,
104 PERF_COUNT_SW_TASK_CLOCK = 1,
105 PERF_COUNT_SW_PAGE_FAULTS = 2,
106 PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
107 PERF_COUNT_SW_CPU_MIGRATIONS = 4,
108 PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
109 PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
110 PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
111 PERF_COUNT_SW_EMULATION_FAULTS = 8,
3301e740
DG
112};
113
b13d56d7
MD
114/*
115 * Generalized hardware cache events:
116 *
117 * { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x
118 * { read, write, prefetch } x
119 * { accesses, misses }
120 */
121enum perf_hw_cache_id {
122 PERF_COUNT_HW_CACHE_L1D = 0,
123 PERF_COUNT_HW_CACHE_L1I = 1,
124 PERF_COUNT_HW_CACHE_LL = 2,
125 PERF_COUNT_HW_CACHE_DTLB = 3,
126 PERF_COUNT_HW_CACHE_ITLB = 4,
127 PERF_COUNT_HW_CACHE_BPU = 5,
128
129 PERF_COUNT_HW_CACHE_MAX, /* non-ABI */
130};
131
132enum perf_hw_cache_op_id {
133 PERF_COUNT_HW_CACHE_OP_READ = 0,
134 PERF_COUNT_HW_CACHE_OP_WRITE = 1,
135 PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
136
137 PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */
138};
139
140enum perf_hw_cache_op_result_id {
141 PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
142 PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
143
144 PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */
145};
146
d65106b1
DG
147static struct poptOption long_options[] = {
148 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
149 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
5440dc42 150 {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
d65106b1 151 {"channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0},
d65106b1 152 {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
d78d6610 153 {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
6caa2bcc 154 {"type", 't', POPT_ARG_STRING, &opt_type, OPT_TYPE, 0, 0},
679b4943 155 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
d65106b1
DG
156 {0, 0, 0, 0, 0, 0, 0}
157};
158
90b9a268 159/*
b13d56d7 160 * Context options
90b9a268 161 */
aa3514e9 162#define PERF_HW(optstr, name, type, hide) \
b13d56d7 163 { \
aa3514e9 164 optstr, type, hide, \
b13d56d7
MD
165 .u.perf = { PERF_TYPE_HARDWARE, PERF_COUNT_HW_##name, },\
166 }
90b9a268 167
aa3514e9 168#define PERF_SW(optstr, name, type, hide) \
b13d56d7 169 { \
aa3514e9 170 optstr, type, hide, \
b13d56d7
MD
171 .u.perf = { PERF_TYPE_SOFTWARE, PERF_COUNT_SW_##name, },\
172 }
90b9a268 173
aa3514e9 174#define _PERF_HW_CACHE(optstr, name, type, op, result, hide) \
b13d56d7 175 { \
aa3514e9 176 optstr, type, hide, \
b13d56d7
MD
177 .u.perf = { \
178 PERF_TYPE_HW_CACHE, \
179 (uint64_t) PERF_COUNT_HW_CACHE_##name \
18829107
MD
180 | ((uint64_t) PERF_COUNT_HW_CACHE_OP_##op << 8) \
181 | ((uint64_t) PERF_COUNT_HW_CACHE_RESULT_##result << 16), \
b13d56d7
MD
182 }, \
183 }
184
aa3514e9
MD
185#define PERF_HW_CACHE(optstr, name, type, hide) \
186 _PERF_HW_CACHE(optstr "-loads", name, type, \
187 READ, ACCESS, hide), \
188 _PERF_HW_CACHE(optstr "-load-misses", name, type, \
189 READ, MISS, hide), \
190 _PERF_HW_CACHE(optstr "-stores", name, type, \
191 WRITE, ACCESS, hide), \
192 _PERF_HW_CACHE(optstr "-store-misses", name, type, \
193 WRITE, MISS, hide), \
194 _PERF_HW_CACHE(optstr "-prefetches", name, type, \
195 PREFETCH, ACCESS, hide), \
196 _PERF_HW_CACHE(optstr "-prefetch-misses", name, type, \
197 PREFETCH, MISS, hide)
b13d56d7
MD
198
199static
200const struct ctx_opts {
90b9a268 201 char *symbol;
b13d56d7 202 enum context_type ctx_type;
aa3514e9 203 int hide_help; /* Hide from --help */
b13d56d7
MD
204 union {
205 struct {
206 uint32_t type;
207 uint64_t config;
208 } perf;
209 } u;
210} ctx_opts[] = {
211 { "pid", CONTEXT_PID },
95da1297 212 { "procname", CONTEXT_PROCNAME },
b13d56d7
MD
213 { "prio", CONTEXT_PRIO },
214 { "nice", CONTEXT_NICE },
215 { "vpid", CONTEXT_VPID },
216 { "tid", CONTEXT_TID },
9197c5c4 217 { "pthread_id", CONTEXT_PTHREAD_ID },
b13d56d7
MD
218 { "vtid", CONTEXT_VTID },
219 { "ppid", CONTEXT_PPID },
220 { "vppid", CONTEXT_VPPID },
54773d68 221 { "hostname", CONTEXT_HOSTNAME },
7c612c2e 222 { "ip", CONTEXT_IP },
aa3514e9 223
b13d56d7 224 /* Perf options */
aa3514e9
MD
225
226 /* Perf per-CPU counters */
227 PERF_HW("perf:cpu:cpu-cycles", CPU_CYCLES,
228 CONTEXT_PERF_CPU_COUNTER, 0),
229 PERF_HW("perf:cpu:cycles", CPU_CYCLES,
230 CONTEXT_PERF_CPU_COUNTER, 0),
231 PERF_HW("perf:cpu:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
232 CONTEXT_PERF_CPU_COUNTER, 0),
233 PERF_HW("perf:cpu:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
234 CONTEXT_PERF_CPU_COUNTER, 0),
235 PERF_HW("perf:cpu:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
236 CONTEXT_PERF_CPU_COUNTER, 0),
237 PERF_HW("perf:cpu:idle-cycles-backend", STALLED_CYCLES_BACKEND,
238 CONTEXT_PERF_CPU_COUNTER, 0),
239 PERF_HW("perf:cpu:instructions", INSTRUCTIONS,
240 CONTEXT_PERF_CPU_COUNTER, 0),
241 PERF_HW("perf:cpu:cache-references", CACHE_REFERENCES,
242 CONTEXT_PERF_CPU_COUNTER, 0),
243 PERF_HW("perf:cpu:cache-misses", CACHE_MISSES,
244 CONTEXT_PERF_CPU_COUNTER, 0),
245 PERF_HW("perf:cpu:branch-instructions", BRANCH_INSTRUCTIONS,
246 CONTEXT_PERF_CPU_COUNTER, 0),
247 PERF_HW("perf:cpu:branches", BRANCH_INSTRUCTIONS,
248 CONTEXT_PERF_CPU_COUNTER, 0),
249 PERF_HW("perf:cpu:branch-misses", BRANCH_MISSES,
250 CONTEXT_PERF_CPU_COUNTER, 0),
251 PERF_HW("perf:cpu:bus-cycles", BUS_CYCLES,
252 CONTEXT_PERF_CPU_COUNTER, 0),
253
254 PERF_HW_CACHE("perf:cpu:L1-dcache", L1D,
255 CONTEXT_PERF_CPU_COUNTER, 0),
256 PERF_HW_CACHE("perf:cpu:L1-icache", L1I,
257 CONTEXT_PERF_CPU_COUNTER, 0),
258 PERF_HW_CACHE("perf:cpu:LLC", LL,
259 CONTEXT_PERF_CPU_COUNTER, 0),
260 PERF_HW_CACHE("perf:cpu:dTLB", DTLB,
261 CONTEXT_PERF_CPU_COUNTER, 0),
262 _PERF_HW_CACHE("perf:cpu:iTLB-loads", ITLB,
263 CONTEXT_PERF_CPU_COUNTER, READ, ACCESS, 0),
264 _PERF_HW_CACHE("perf:cpu:iTLB-load-misses", ITLB,
265 CONTEXT_PERF_CPU_COUNTER, READ, MISS, 0),
266 _PERF_HW_CACHE("perf:cpu:branch-loads", BPU,
267 CONTEXT_PERF_CPU_COUNTER, READ, ACCESS, 0),
268 _PERF_HW_CACHE("perf:cpu:branch-load-misses", BPU,
269 CONTEXT_PERF_CPU_COUNTER, READ, MISS, 0),
270
271 PERF_SW("perf:cpu:cpu-clock", CPU_CLOCK,
272 CONTEXT_PERF_CPU_COUNTER, 0),
273 PERF_SW("perf:cpu:task-clock", TASK_CLOCK,
274 CONTEXT_PERF_CPU_COUNTER, 0),
275 PERF_SW("perf:cpu:page-fault", PAGE_FAULTS,
276 CONTEXT_PERF_CPU_COUNTER, 0),
277 PERF_SW("perf:cpu:faults", PAGE_FAULTS,
278 CONTEXT_PERF_CPU_COUNTER, 0),
279 PERF_SW("perf:cpu:major-faults", PAGE_FAULTS_MAJ,
280 CONTEXT_PERF_CPU_COUNTER, 0),
281 PERF_SW("perf:cpu:minor-faults", PAGE_FAULTS_MIN,
282 CONTEXT_PERF_CPU_COUNTER, 0),
283 PERF_SW("perf:cpu:context-switches", CONTEXT_SWITCHES,
284 CONTEXT_PERF_CPU_COUNTER, 0),
285 PERF_SW("perf:cpu:cs", CONTEXT_SWITCHES,
286 CONTEXT_PERF_CPU_COUNTER, 0),
287 PERF_SW("perf:cpu:cpu-migrations", CPU_MIGRATIONS,
288 CONTEXT_PERF_CPU_COUNTER, 0),
289 PERF_SW("perf:cpu:migrations", CPU_MIGRATIONS,
290 CONTEXT_PERF_CPU_COUNTER, 0),
291 PERF_SW("perf:cpu:alignment-faults", ALIGNMENT_FAULTS,
292 CONTEXT_PERF_CPU_COUNTER, 0),
293 PERF_SW("perf:cpu:emulation-faults", EMULATION_FAULTS,
294 CONTEXT_PERF_CPU_COUNTER, 0),
295
296 /* Perf per-thread counters */
297 PERF_HW("perf:thread:cpu-cycles", CPU_CYCLES,
298 CONTEXT_PERF_THREAD_COUNTER, 0),
299 PERF_HW("perf:thread:cycles", CPU_CYCLES,
300 CONTEXT_PERF_THREAD_COUNTER, 0),
301 PERF_HW("perf:thread:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
302 CONTEXT_PERF_THREAD_COUNTER, 0),
303 PERF_HW("perf:thread:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
304 CONTEXT_PERF_THREAD_COUNTER, 0),
305 PERF_HW("perf:thread:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
306 CONTEXT_PERF_THREAD_COUNTER, 0),
307 PERF_HW("perf:thread:idle-cycles-backend", STALLED_CYCLES_BACKEND,
308 CONTEXT_PERF_THREAD_COUNTER, 0),
309 PERF_HW("perf:thread:instructions", INSTRUCTIONS,
310 CONTEXT_PERF_THREAD_COUNTER, 0),
311 PERF_HW("perf:thread:cache-references", CACHE_REFERENCES,
312 CONTEXT_PERF_THREAD_COUNTER, 0),
313 PERF_HW("perf:thread:cache-misses", CACHE_MISSES,
314 CONTEXT_PERF_THREAD_COUNTER, 0),
315 PERF_HW("perf:thread:branch-instructions", BRANCH_INSTRUCTIONS,
316 CONTEXT_PERF_THREAD_COUNTER, 0),
317 PERF_HW("perf:thread:branches", BRANCH_INSTRUCTIONS,
318 CONTEXT_PERF_THREAD_COUNTER, 0),
319 PERF_HW("perf:thread:branch-misses", BRANCH_MISSES,
320 CONTEXT_PERF_THREAD_COUNTER, 0),
321 PERF_HW("perf:thread:bus-cycles", BUS_CYCLES,
322 CONTEXT_PERF_THREAD_COUNTER, 0),
323
324 PERF_HW_CACHE("perf:thread:L1-dcache", L1D,
325 CONTEXT_PERF_THREAD_COUNTER, 0),
326 PERF_HW_CACHE("perf:thread:L1-icache", L1I,
327 CONTEXT_PERF_THREAD_COUNTER, 0),
328 PERF_HW_CACHE("perf:thread:LLC", LL,
329 CONTEXT_PERF_THREAD_COUNTER, 0),
330 PERF_HW_CACHE("perf:thread:dTLB", DTLB,
331 CONTEXT_PERF_THREAD_COUNTER, 0),
332 _PERF_HW_CACHE("perf:thread:iTLB-loads", ITLB,
333 CONTEXT_PERF_THREAD_COUNTER, READ, ACCESS, 0),
334 _PERF_HW_CACHE("perf:thread:iTLB-load-misses", ITLB,
335 CONTEXT_PERF_THREAD_COUNTER, READ, MISS, 0),
336 _PERF_HW_CACHE("perf:thread:branch-loads", BPU,
337 CONTEXT_PERF_THREAD_COUNTER, READ, ACCESS, 0),
338 _PERF_HW_CACHE("perf:thread:branch-load-misses", BPU,
339 CONTEXT_PERF_THREAD_COUNTER, READ, MISS, 0),
340
341 PERF_SW("perf:thread:cpu-clock", CPU_CLOCK,
342 CONTEXT_PERF_THREAD_COUNTER, 0),
343 PERF_SW("perf:thread:task-clock", TASK_CLOCK,
344 CONTEXT_PERF_THREAD_COUNTER, 0),
345 PERF_SW("perf:thread:page-fault", PAGE_FAULTS,
346 CONTEXT_PERF_THREAD_COUNTER, 0),
347 PERF_SW("perf:thread:faults", PAGE_FAULTS,
348 CONTEXT_PERF_THREAD_COUNTER, 0),
349 PERF_SW("perf:thread:major-faults", PAGE_FAULTS_MAJ,
350 CONTEXT_PERF_THREAD_COUNTER, 0),
351 PERF_SW("perf:thread:minor-faults", PAGE_FAULTS_MIN,
352 CONTEXT_PERF_THREAD_COUNTER, 0),
353 PERF_SW("perf:thread:context-switches", CONTEXT_SWITCHES,
354 CONTEXT_PERF_THREAD_COUNTER, 0),
355 PERF_SW("perf:thread:cs", CONTEXT_SWITCHES,
356 CONTEXT_PERF_THREAD_COUNTER, 0),
357 PERF_SW("perf:thread:cpu-migrations", CPU_MIGRATIONS,
358 CONTEXT_PERF_THREAD_COUNTER, 0),
359 PERF_SW("perf:thread:migrations", CPU_MIGRATIONS,
360 CONTEXT_PERF_THREAD_COUNTER, 0),
361 PERF_SW("perf:thread:alignment-faults", ALIGNMENT_FAULTS,
362 CONTEXT_PERF_THREAD_COUNTER, 0),
363 PERF_SW("perf:thread:emulation-faults", EMULATION_FAULTS,
364 CONTEXT_PERF_THREAD_COUNTER, 0),
365
366 /*
367 * Perf per-CPU counters, backward compatibilty for names.
368 * Hidden from help listing.
369 */
370 PERF_HW("perf:cpu-cycles", CPU_CYCLES,
371 CONTEXT_PERF_COUNTER, 1),
372 PERF_HW("perf:cycles", CPU_CYCLES,
373 CONTEXT_PERF_COUNTER, 1),
374 PERF_HW("perf:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
375 CONTEXT_PERF_COUNTER, 1),
376 PERF_HW("perf:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
377 CONTEXT_PERF_COUNTER, 1),
378 PERF_HW("perf:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
379 CONTEXT_PERF_COUNTER, 1),
380 PERF_HW("perf:idle-cycles-backend", STALLED_CYCLES_BACKEND,
381 CONTEXT_PERF_COUNTER, 1),
382 PERF_HW("perf:instructions", INSTRUCTIONS,
383 CONTEXT_PERF_COUNTER, 1),
384 PERF_HW("perf:cache-references", CACHE_REFERENCES,
385 CONTEXT_PERF_COUNTER, 1),
386 PERF_HW("perf:cache-misses", CACHE_MISSES,
387 CONTEXT_PERF_COUNTER, 1),
388 PERF_HW("perf:branch-instructions", BRANCH_INSTRUCTIONS,
389 CONTEXT_PERF_COUNTER, 1),
390 PERF_HW("perf:branches", BRANCH_INSTRUCTIONS,
391 CONTEXT_PERF_COUNTER, 1),
392 PERF_HW("perf:branch-misses", BRANCH_MISSES,
393 CONTEXT_PERF_COUNTER, 1),
394 PERF_HW("perf:bus-cycles", BUS_CYCLES,
395 CONTEXT_PERF_COUNTER, 1),
396
397 PERF_HW_CACHE("perf:L1-dcache", L1D,
398 CONTEXT_PERF_COUNTER, 1),
399 PERF_HW_CACHE("perf:L1-icache", L1I,
400 CONTEXT_PERF_COUNTER, 1),
401 PERF_HW_CACHE("perf:LLC", LL,
402 CONTEXT_PERF_COUNTER, 1),
403 PERF_HW_CACHE("perf:dTLB", DTLB,
404 CONTEXT_PERF_COUNTER, 1),
405 _PERF_HW_CACHE("perf:iTLB-loads", ITLB,
406 CONTEXT_PERF_COUNTER, READ, ACCESS, 1),
407 _PERF_HW_CACHE("perf:iTLB-load-misses", ITLB,
408 CONTEXT_PERF_COUNTER, READ, MISS, 1),
409 _PERF_HW_CACHE("perf:branch-loads", BPU,
410 CONTEXT_PERF_COUNTER, READ, ACCESS, 1),
411 _PERF_HW_CACHE("perf:branch-load-misses", BPU,
412 CONTEXT_PERF_COUNTER, READ, MISS, 1),
413
414 PERF_SW("perf:cpu-clock", CPU_CLOCK,
415 CONTEXT_PERF_COUNTER, 1),
416 PERF_SW("perf:task-clock", TASK_CLOCK,
417 CONTEXT_PERF_COUNTER, 1),
418 PERF_SW("perf:page-fault", PAGE_FAULTS,
419 CONTEXT_PERF_COUNTER, 1),
420 PERF_SW("perf:faults", PAGE_FAULTS,
421 CONTEXT_PERF_COUNTER, 1),
422 PERF_SW("perf:major-faults", PAGE_FAULTS_MAJ,
423 CONTEXT_PERF_COUNTER, 1),
424 PERF_SW("perf:minor-faults", PAGE_FAULTS_MIN,
425 CONTEXT_PERF_COUNTER, 1),
426 PERF_SW("perf:context-switches", CONTEXT_SWITCHES,
427 CONTEXT_PERF_COUNTER, 1),
428 PERF_SW("perf:cs", CONTEXT_SWITCHES,
429 CONTEXT_PERF_COUNTER, 1),
430 PERF_SW("perf:cpu-migrations", CPU_MIGRATIONS,
431 CONTEXT_PERF_COUNTER, 1),
432 PERF_SW("perf:migrations", CPU_MIGRATIONS,
433 CONTEXT_PERF_COUNTER, 1),
434 PERF_SW("perf:alignment-faults", ALIGNMENT_FAULTS,
435 CONTEXT_PERF_COUNTER, 1),
436 PERF_SW("perf:emulation-faults", EMULATION_FAULTS,
437 CONTEXT_PERF_COUNTER, 1),
438
b13d56d7 439 { NULL, -1 }, /* Closure */
90b9a268
DG
440};
441
aa3514e9
MD
442#undef PERF_HW_CACHE
443#undef _PERF_HW_CACHE
b13d56d7
MD
444#undef PERF_SW
445#undef PERF_HW
446
90b9a268 447/*
b13d56d7 448 * Context type for command line option parsing.
90b9a268 449 */
b13d56d7
MD
450struct ctx_type {
451 const struct ctx_opts *opt;
452 struct cds_list_head list;
90b9a268
DG
453};
454
455/*
456 * List of context type. Use to enable multiple context on a single command
457 * line entry.
458 */
459struct ctx_type_list {
460 struct cds_list_head head;
461} ctx_type_list = {
462 .head = CDS_LIST_HEAD_INIT(ctx_type_list.head),
463};
464
90b9a268
DG
465/*
466 * Pretty print context type.
467 */
468static void print_ctx_type(FILE *ofp)
469{
b13d56d7
MD
470 const char *indent = " ";
471 int indent_len = strlen(indent);
472 int len, i = 0;
90b9a268 473
76e3c5dd 474 fprintf(ofp, "%s", indent);
b13d56d7 475 len = indent_len;
90b9a268 476 while (ctx_opts[i].symbol != NULL) {
aa3514e9
MD
477 if (!ctx_opts[i].hide_help) {
478 if (len > indent_len) {
479 if (len + strlen(ctx_opts[i].symbol) + 2
480 >= PRINT_LINE_LEN) {
481 fprintf(ofp, ",\n");
482 fprintf(ofp, "%s", indent);
483 len = indent_len;
484 } else {
485 len += fprintf(ofp, ", ");
486 }
90b9a268 487 }
aa3514e9 488 len += fprintf(ofp, "%s", ctx_opts[i].symbol);
90b9a268
DG
489 }
490 i++;
491 }
90b9a268
DG
492}
493
d65106b1
DG
494/*
495 * usage
496 */
497static void usage(FILE *ofp)
498{
32a6298d 499 fprintf(ofp, "usage: lttng add-context -t TYPE [-k|-u] [OPTIONS]\n");
d65106b1 500 fprintf(ofp, "\n");
601d5acf
DG
501 fprintf(ofp, "If no channel is given (-c), the context is added to\n");
502 fprintf(ofp, "all channels.\n");
32a6298d 503 fprintf(ofp, "\n");
601d5acf 504 fprintf(ofp, "Otherwise the context is added only to the channel (-c).\n");
32a6298d
DG
505 fprintf(ofp, "\n");
506 fprintf(ofp, "Exactly one domain (-k or -u) must be specified.\n");
3301e740 507 fprintf(ofp, "\n");
d65106b1
DG
508 fprintf(ofp, "Options:\n");
509 fprintf(ofp, " -h, --help Show this help\n");
679b4943 510 fprintf(ofp, " --list-options Simple listing of options\n");
5eb00805
TD
511 fprintf(ofp, " -s, --session NAME Apply to session name\n");
512 fprintf(ofp, " -c, --channel NAME Apply to channel\n");
af87c45a 513 fprintf(ofp, " -k, --kernel Apply to the kernel tracer\n");
af87c45a 514 fprintf(ofp, " -u, --userspace Apply to the user-space tracer\n");
32a6298d
DG
515 fprintf(ofp, "\n");
516 fprintf(ofp, "Context:\n");
b13d56d7 517 fprintf(ofp, " -t, --type TYPE Context type. You can repeat that option on\n");
af87c45a
DG
518 fprintf(ofp, " the command line to specify multiple contexts at once.\n");
519 fprintf(ofp, " (--kernel preempts --userspace)\n");
b13d56d7 520 fprintf(ofp, " TYPE can be one of the strings below:\n");
90b9a268 521 print_ctx_type(ofp);
d65106b1 522 fprintf(ofp, "\n");
c455d428
FD
523 fprintf(ofp, "Note that the vpid, vppid and vtid context types represent the virtual process id,\n"
524 "virtual parent process id and virtual thread id as seen from the current execution context\n"
525 "as opposed to the pid, ppid and tid which are kernel internal data structures.\n\n");
90b9a268 526 fprintf(ofp, "Example:\n");
aa3514e9
MD
527 fprintf(ofp, "This command will add the context information 'prio' and two per-cpu\n"
528 "perf counters (hardware branch misses and cache misses), to all channels\n"
b13d56d7 529 "in the trace data output:\n");
aa3514e9 530 fprintf(ofp, "# lttng add-context -k -t prio -t perf:cpu:branch-misses -t perf:cpu:cache-misses\n");
d65106b1
DG
531 fprintf(ofp, "\n");
532}
533
90b9a268
DG
534/*
535 * Find context numerical value from string.
536 */
537static int find_ctx_type_idx(const char *opt)
538{
539 int ret = -1, i = 0;
540
541 while (ctx_opts[i].symbol != NULL) {
542 if (strcmp(opt, ctx_opts[i].symbol) == 0) {
543 ret = i;
544 goto end;
545 }
546 i++;
547 }
548
549end:
550 return ret;
551}
552
90b9a268
DG
553/*
554 * Add context to channel or event.
d65106b1 555 */
cd80958d 556static int add_context(char *session_name)
d65106b1 557{
89b72577 558 int ret = CMD_SUCCESS, warn = 0, success = 0;
7d29a247
DG
559 struct lttng_event_context context;
560 struct lttng_domain dom;
3301e740 561 struct ctx_type *type;
b13d56d7 562 char *ptr;
d65106b1 563
441c16a7
MD
564 memset(&context, 0, sizeof(context));
565 memset(&dom, 0, sizeof(dom));
566
cd80958d
DG
567 if (opt_kernel) {
568 dom.type = LTTNG_DOMAIN_KERNEL;
d78d6610 569 } else if (opt_userspace) {
55cc08a6 570 dom.type = LTTNG_DOMAIN_UST;
55cc08a6 571 } else {
66c214cd 572 assert(0);
cd80958d
DG
573 }
574
575 handle = lttng_create_handle(session_name, &dom);
576 if (handle == NULL) {
af87c45a 577 ret = CMD_ERROR;
cd80958d
DG
578 goto error;
579 }
580
89b72577
JRJ
581 if (lttng_opt_mi) {
582 /* Open a contexts element */
583 ret = mi_lttng_writer_open_element(writer, config_element_contexts);
584 if (ret) {
585 goto error;
586 }
587 }
588
5eb00805 589 /* Iterate over all the context types given */
3301e740 590 cds_list_for_each_entry(type, &ctx_type_list.head, list) {
6775595e 591 context.ctx = (enum lttng_event_context_type) type->opt->ctx_type;
aa3514e9
MD
592 switch (context.ctx) {
593 case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
594 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
595 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
b13d56d7
MD
596 context.u.perf_counter.type = type->opt->u.perf.type;
597 context.u.perf_counter.config = type->opt->u.perf.config;
24546386
MD
598 strncpy(context.u.perf_counter.name, type->opt->symbol,
599 LTTNG_SYMBOL_NAME_LEN);
600 context.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
b13d56d7
MD
601 /* Replace : and - by _ */
602 while ((ptr = strchr(context.u.perf_counter.name, '-')) != NULL) {
603 *ptr = '_';
3301e740 604 }
b13d56d7
MD
605 while ((ptr = strchr(context.u.perf_counter.name, ':')) != NULL) {
606 *ptr = '_';
3301e740 607 }
aa3514e9
MD
608 break;
609 default:
610 break;
3301e740 611 }
55cc08a6
DG
612 DBG("Adding context...");
613
89b72577
JRJ
614 if (lttng_opt_mi) {
615 /* We leave context open the update the success of the command */
616 ret = mi_lttng_context(writer, &context, 1);
617 if (ret) {
618 ret = CMD_ERROR;
619 goto error;
620 }
621 }
622
601d5acf 623 ret = lttng_add_context(handle, &context, NULL, opt_channel_name);
55cc08a6 624 if (ret < 0) {
b58471ff 625 ERR("%s: %s", type->opt->symbol, lttng_strerror(ret));
d16c1a4c 626 warn = 1;
89b72577 627 success = 0;
d65106b1 628 } else {
601d5acf 629 if (opt_channel_name) {
b58471ff 630 MSG("%s context %s added to channel %s",
50b34a52 631 get_domain_str(dom.type), type->opt->symbol,
b58471ff 632 opt_channel_name);
b58471ff
DG
633 } else {
634 MSG("%s context %s added to all channels",
b75c559e 635 get_domain_str(dom.type), type->opt->symbol);
b58471ff 636 }
89b72577
JRJ
637 success = 1;
638 }
639
640 if (lttng_opt_mi) {
641 /* Is the single operation a success ? */
642 ret = mi_lttng_writer_write_element_bool(writer,
643 mi_lttng_element_success, success);
644 if (ret) {
645 ret = CMD_ERROR;
646 goto error;
647 }
648
649 /* Close the context element */
650 ret = mi_lttng_writer_close_element(writer);
651 if (ret) {
652 ret = CMD_ERROR;
653 goto error;
654 }
655 }
656 }
657
658 if (lttng_opt_mi) {
659 /* Close contexts element */
660 ret = mi_lttng_writer_close_element(writer);
661 if (ret) {
662 goto error;
d65106b1 663 }
d65106b1
DG
664 }
665
af87c45a
DG
666 ret = CMD_SUCCESS;
667
d65106b1 668error:
cd80958d
DG
669 lttng_destroy_handle(handle);
670
d16c1a4c
DG
671 /*
672 * This means that at least one add_context failed and tells the user to
673 * look on stderr for error(s).
674 */
89b72577 675 if (!ret && warn) {
d16c1a4c
DG
676 ret = CMD_WARNING;
677 }
d65106b1
DG
678 return ret;
679}
680
681/*
5eb00805 682 * Add context to channel or event.
d65106b1
DG
683 */
684int cmd_add_context(int argc, const char **argv)
685{
89b72577
JRJ
686 int index, opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
687 int success = 1;
d65106b1 688 static poptContext pc;
b13d56d7 689 struct ctx_type *type, *tmptype;
cd80958d 690 char *session_name = NULL;
d65106b1 691
636167b6
DG
692 if (argc < 2) {
693 usage(stderr);
5eb00805 694 ret = CMD_ERROR;
636167b6
DG
695 goto end;
696 }
697
d65106b1
DG
698 pc = poptGetContext(NULL, argc, argv, long_options, 0);
699 poptReadDefaultConfig(pc, 0);
700
701 while ((opt = poptGetNextOpt(pc)) != -1) {
702 switch (opt) {
703 case OPT_HELP:
5eb00805 704 usage(stdout);
d65106b1
DG
705 goto end;
706 case OPT_TYPE:
af87c45a
DG
707 /*
708 * Look up the index of opt_type in ctx_opts[] first, so we don't
709 * have to free(type) on failure.
710 */
6caa2bcc 711 index = find_ctx_type_idx(opt_type);
b13d56d7 712 if (index < 0) {
6caa2bcc 713 ERR("Unknown context type %s", opt_type);
5eb00805 714 ret = CMD_ERROR;
b13d56d7 715 goto end;
90b9a268 716 }
5eb00805 717
98cf2db1 718 type = zmalloc(sizeof(struct ctx_type));
5eb00805 719 if (type == NULL) {
6f04ed72 720 PERROR("malloc ctx_type");
5eb00805
TD
721 ret = CMD_FATAL;
722 goto end;
723 }
724
b13d56d7 725 type->opt = &ctx_opts[index];
109be0da 726 if (type->opt->symbol == NULL) {
6caa2bcc 727 ERR("Unknown context type %s", opt_type);
5eb00805
TD
728 free(type);
729 ret = CMD_ERROR;
730 goto end;
90b9a268 731 } else {
31746f93 732 cds_list_add_tail(&type->list, &ctx_type_list.head);
90b9a268 733 }
d65106b1 734 break;
eeac7d46
MD
735 case OPT_USERSPACE:
736 opt_userspace = 1;
d78d6610 737#if 0
eeac7d46 738 opt_cmd_name = poptGetOptArg(pc);
d78d6610 739#endif
eeac7d46 740 break;
679b4943
SM
741 case OPT_LIST_OPTIONS:
742 list_cmd_options(stdout, long_options);
679b4943 743 goto end;
d65106b1
DG
744 default:
745 usage(stderr);
746 ret = CMD_UNDEFINED;
747 goto end;
748 }
749 }
750
66c214cd
PP
751 ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace);
752
753 if (ret) {
754 ret = CMD_ERROR;
755 goto end;
756 }
757
ae856491
DG
758 if (!opt_type) {
759 ERR("Missing mandatory -t TYPE");
760 usage(stderr);
761 ret = CMD_ERROR;
762 goto end;
763 }
764
cd80958d
DG
765 if (!opt_session_name) {
766 session_name = get_session_name();
767 if (session_name == NULL) {
5eb00805 768 ret = CMD_ERROR;
cd80958d
DG
769 goto end;
770 }
771 } else {
772 session_name = opt_session_name;
773 }
774
89b72577
JRJ
775 /* Mi check */
776 if (lttng_opt_mi) {
777 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
778 if (!writer) {
779 ret = -LTTNG_ERR_NOMEM;
780 goto end;
781 }
782
783 /* Open command element */
784 ret = mi_lttng_writer_command_open(writer,
785 mi_lttng_element_command_add_context);
786 if (ret) {
787 ret = CMD_ERROR;
788 goto end;
789 }
790
791 /* Open output element */
792 ret = mi_lttng_writer_open_element(writer,
793 mi_lttng_element_command_output);
794 if (ret) {
795 ret = CMD_ERROR;
796 goto end;
797 }
798 }
799
800 command_ret = add_context(session_name);
801 if (command_ret) {
802 success = 0;
803 }
804
805 /* Mi closing */
806 if (lttng_opt_mi) {
807 /* Close output element */
808 ret = mi_lttng_writer_close_element(writer);
809 if (ret) {
810 ret = CMD_ERROR;
811 goto end;
812 }
3301e740 813
89b72577
JRJ
814 /* Success ? */
815 ret = mi_lttng_writer_write_element_bool(writer,
816 mi_lttng_element_command_success, success);
817 if (ret) {
818 ret = CMD_ERROR;
819 goto end;
820 }
821
822 /* Command element close */
823 ret = mi_lttng_writer_command_close(writer);
824 if (ret) {
825 ret = CMD_ERROR;
826 goto end;
827 }
828 }
829
830end:
1256f150
DT
831 if (!opt_session_name) {
832 free(session_name);
833 }
834
89b72577
JRJ
835 /* Mi clean-up */
836 if (writer && mi_lttng_writer_destroy(writer)) {
837 /* Preserve original error code */
838 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
839 }
840
3301e740 841 /* Cleanup allocated memory */
b13d56d7 842 cds_list_for_each_entry_safe(type, tmptype, &ctx_type_list.head, list) {
3301e740
DG
843 free(type);
844 }
845
89b72577
JRJ
846 /* Overwrite ret if an error occurred during add_context() */
847 ret = command_ret ? command_ret : ret;
848
ca1c3607 849 poptFreeContext(pc);
d65106b1
DG
850 return ret;
851}
This page took 0.078686 seconds and 4 git commands to generate.