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