Blame view
tools/perf/builtin-inject.c
6.37 KB
454c407ec perf: add perf-in... |
1 2 3 4 5 6 7 8 9 10 11 |
/* * builtin-inject.c * * Builtin inject command: Examine the live mode (stdin) event stream * and repipe it to stdout while optionally injecting additional * events into it. */ #include "builtin.h" #include "perf.h" #include "util/session.h" |
45694aa77 perf tools: Renam... |
12 |
#include "util/tool.h" |
454c407ec perf: add perf-in... |
13 14 15 16 17 18 |
#include "util/debug.h" #include "util/parse-options.h" static char const *input_name = "-"; static bool inject_build_ids; |
45694aa77 perf tools: Renam... |
19 |
static int perf_event__repipe_synth(struct perf_tool *tool __used, |
d20deb64e perf tools: Pass ... |
20 |
union perf_event *event, |
743eb8686 perf tools: Resol... |
21 |
struct machine *machine __used) |
454c407ec perf: add perf-in... |
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
{ uint32_t size; void *buf = event; size = event->header.size; while (size) { int ret = write(STDOUT_FILENO, buf, size); if (ret < 0) return -errno; size -= ret; buf += ret; } return 0; } |
45694aa77 perf tools: Renam... |
39 |
static int perf_event__repipe_op2_synth(struct perf_tool *tool, |
743eb8686 perf tools: Resol... |
40 41 42 |
union perf_event *event, struct perf_session *session __used) { |
45694aa77 perf tools: Renam... |
43 |
return perf_event__repipe_synth(tool, event, NULL); |
743eb8686 perf tools: Resol... |
44 |
} |
45694aa77 perf tools: Renam... |
45 |
static int perf_event__repipe_event_type_synth(struct perf_tool *tool, |
743eb8686 perf tools: Resol... |
46 47 |
union perf_event *event) { |
45694aa77 perf tools: Renam... |
48 |
return perf_event__repipe_synth(tool, event, NULL); |
743eb8686 perf tools: Resol... |
49 |
} |
d20deb64e perf tools: Pass ... |
50 |
static int perf_event__repipe_tracing_data_synth(union perf_event *event, |
743eb8686 perf tools: Resol... |
51 |
struct perf_session *session __used) |
d20deb64e perf tools: Pass ... |
52 |
{ |
743eb8686 perf tools: Resol... |
53 |
return perf_event__repipe_synth(NULL, event, NULL); |
d20deb64e perf tools: Pass ... |
54 |
} |
10d0f086d perf event: perf_... |
55 56 57 |
static int perf_event__repipe_attr(union perf_event *event, struct perf_evlist **pevlist __used) { |
d20deb64e perf tools: Pass ... |
58 |
return perf_event__repipe_synth(NULL, event, NULL); |
10d0f086d perf event: perf_... |
59 |
} |
45694aa77 perf tools: Renam... |
60 |
static int perf_event__repipe(struct perf_tool *tool, |
d20deb64e perf tools: Pass ... |
61 |
union perf_event *event, |
8115d60c3 perf tools: Kill ... |
62 |
struct perf_sample *sample __used, |
743eb8686 perf tools: Resol... |
63 |
struct machine *machine) |
640c03ce8 perf session: Par... |
64 |
{ |
45694aa77 perf tools: Renam... |
65 |
return perf_event__repipe_synth(tool, event, machine); |
640c03ce8 perf session: Par... |
66 |
} |
45694aa77 perf tools: Renam... |
67 |
static int perf_event__repipe_sample(struct perf_tool *tool, |
d20deb64e perf tools: Pass ... |
68 |
union perf_event *event, |
9e69c2108 perf session: Pas... |
69 70 |
struct perf_sample *sample __used, struct perf_evsel *evsel __used, |
743eb8686 perf tools: Resol... |
71 |
struct machine *machine) |
9e69c2108 perf session: Pas... |
72 |
{ |
45694aa77 perf tools: Renam... |
73 |
return perf_event__repipe_synth(tool, event, machine); |
9e69c2108 perf session: Pas... |
74 |
} |
45694aa77 perf tools: Renam... |
75 |
static int perf_event__repipe_mmap(struct perf_tool *tool, |
d20deb64e perf tools: Pass ... |
76 |
union perf_event *event, |
8115d60c3 perf tools: Kill ... |
77 |
struct perf_sample *sample, |
743eb8686 perf tools: Resol... |
78 |
struct machine *machine) |
454c407ec perf: add perf-in... |
79 80 |
{ int err; |
45694aa77 perf tools: Renam... |
81 82 |
err = perf_event__process_mmap(tool, event, sample, machine); perf_event__repipe(tool, event, sample, machine); |
454c407ec perf: add perf-in... |
83 84 85 |
return err; } |
45694aa77 perf tools: Renam... |
86 |
static int perf_event__repipe_task(struct perf_tool *tool, |
d20deb64e perf tools: Pass ... |
87 |
union perf_event *event, |
8115d60c3 perf tools: Kill ... |
88 |
struct perf_sample *sample, |
743eb8686 perf tools: Resol... |
89 |
struct machine *machine) |
454c407ec perf: add perf-in... |
90 91 |
{ int err; |
45694aa77 perf tools: Renam... |
92 93 |
err = perf_event__process_task(tool, event, sample, machine); perf_event__repipe(tool, event, sample, machine); |
454c407ec perf: add perf-in... |
94 95 96 |
return err; } |
8115d60c3 perf tools: Kill ... |
97 98 |
static int perf_event__repipe_tracing_data(union perf_event *event, struct perf_session *session) |
454c407ec perf: add perf-in... |
99 100 |
{ int err; |
743eb8686 perf tools: Resol... |
101 |
perf_event__repipe_synth(NULL, event, NULL); |
8115d60c3 perf tools: Kill ... |
102 |
err = perf_event__process_tracing_data(event, session); |
454c407ec perf: add perf-in... |
103 104 105 |
return err; } |
090f7204d perf inject: Refa... |
106 |
static int dso__read_build_id(struct dso *self) |
454c407ec perf: add perf-in... |
107 |
{ |
090f7204d perf inject: Refa... |
108 109 |
if (self->has_build_id) return 0; |
454c407ec perf: add perf-in... |
110 |
|
090f7204d perf inject: Refa... |
111 112 113 114 115 |
if (filename__read_build_id(self->long_name, self->build_id, sizeof(self->build_id)) > 0) { self->has_build_id = true; return 0; } |
454c407ec perf: add perf-in... |
116 |
|
090f7204d perf inject: Refa... |
117 118 |
return -1; } |
454c407ec perf: add perf-in... |
119 |
|
45694aa77 perf tools: Renam... |
120 |
static int dso__inject_build_id(struct dso *self, struct perf_tool *tool, |
743eb8686 perf tools: Resol... |
121 |
struct machine *machine) |
090f7204d perf inject: Refa... |
122 123 |
{ u16 misc = PERF_RECORD_MISC_USER; |
090f7204d perf inject: Refa... |
124 |
int err; |
454c407ec perf: add perf-in... |
125 |
|
090f7204d perf inject: Refa... |
126 127 128 129 130 |
if (dso__read_build_id(self) < 0) { pr_debug("no build_id found for %s ", self->long_name); return -1; } |
454c407ec perf: add perf-in... |
131 |
|
090f7204d perf inject: Refa... |
132 133 |
if (self->kernel) misc = PERF_RECORD_MISC_KERNEL; |
454c407ec perf: add perf-in... |
134 |
|
45694aa77 perf tools: Renam... |
135 |
err = perf_event__synthesize_build_id(tool, self, misc, perf_event__repipe, |
743eb8686 perf tools: Resol... |
136 |
machine); |
090f7204d perf inject: Refa... |
137 138 139 |
if (err) { pr_err("Can't synthesize build_id event for %s ", self->long_name); |
454c407ec perf: add perf-in... |
140 141 142 143 144 |
return -1; } return 0; } |
45694aa77 perf tools: Renam... |
145 |
static int perf_event__inject_buildid(struct perf_tool *tool, |
d20deb64e perf tools: Pass ... |
146 |
union perf_event *event, |
8115d60c3 perf tools: Kill ... |
147 |
struct perf_sample *sample, |
9e69c2108 perf session: Pas... |
148 |
struct perf_evsel *evsel __used, |
743eb8686 perf tools: Resol... |
149 |
struct machine *machine) |
454c407ec perf: add perf-in... |
150 151 152 153 |
{ struct addr_location al; struct thread *thread; u8 cpumode; |
454c407ec perf: add perf-in... |
154 155 |
cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
743eb8686 perf tools: Resol... |
156 |
thread = machine__findnew_thread(machine, event->ip.pid); |
454c407ec perf: add perf-in... |
157 158 159 160 |
if (thread == NULL) { pr_err("problem processing %d event, skipping it. ", event->header.type); |
454c407ec perf: add perf-in... |
161 162 |
goto repipe; } |
743eb8686 perf tools: Resol... |
163 164 |
thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, event->ip.ip, &al); |
454c407ec perf: add perf-in... |
165 166 167 168 |
if (al.map != NULL) { if (!al.map->dso->hit) { al.map->dso->hit = 1; |
090f7204d perf inject: Refa... |
169 |
if (map__load(al.map, NULL) >= 0) { |
45694aa77 perf tools: Renam... |
170 |
dso__inject_build_id(al.map->dso, tool, machine); |
090f7204d perf inject: Refa... |
171 172 173 174 175 |
/* * If this fails, too bad, let the other side * account this as unresolved. */ } else |
454c407ec perf: add perf-in... |
176 177 178 179 180 181 182 183 |
pr_warning("no symbols found in %s, maybe " "install a debug package? ", al.map->dso->long_name); } } repipe: |
45694aa77 perf tools: Renam... |
184 |
perf_event__repipe(tool, event, sample, machine); |
090f7204d perf inject: Refa... |
185 |
return 0; |
454c407ec perf: add perf-in... |
186 |
} |
45694aa77 perf tools: Renam... |
187 |
struct perf_tool perf_inject = { |
9e69c2108 perf session: Pas... |
188 |
.sample = perf_event__repipe_sample, |
8115d60c3 perf tools: Kill ... |
189 190 191 192 193 |
.mmap = perf_event__repipe, .comm = perf_event__repipe, .fork = perf_event__repipe, .exit = perf_event__repipe, .lost = perf_event__repipe, |
743eb8686 perf tools: Resol... |
194 |
.read = perf_event__repipe_sample, |
8115d60c3 perf tools: Kill ... |
195 196 |
.throttle = perf_event__repipe, .unthrottle = perf_event__repipe, |
10d0f086d perf event: perf_... |
197 |
.attr = perf_event__repipe_attr, |
743eb8686 perf tools: Resol... |
198 |
.event_type = perf_event__repipe_event_type_synth, |
d20deb64e perf tools: Pass ... |
199 |
.tracing_data = perf_event__repipe_tracing_data_synth, |
743eb8686 perf tools: Resol... |
200 |
.build_id = perf_event__repipe_op2_synth, |
454c407ec perf: add perf-in... |
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
}; extern volatile int session_done; static void sig_handler(int sig __attribute__((__unused__))) { session_done = 1; } static int __cmd_inject(void) { struct perf_session *session; int ret = -EINVAL; signal(SIGINT, sig_handler); if (inject_build_ids) { |
45694aa77 perf tools: Renam... |
218 219 220 221 |
perf_inject.sample = perf_event__inject_buildid; perf_inject.mmap = perf_event__repipe_mmap; perf_inject.fork = perf_event__repipe_task; perf_inject.tracing_data = perf_event__repipe_tracing_data; |
454c407ec perf: add perf-in... |
222 |
} |
45694aa77 perf tools: Renam... |
223 |
session = perf_session__new(input_name, O_RDONLY, false, true, &perf_inject); |
454c407ec perf: add perf-in... |
224 225 |
if (session == NULL) return -ENOMEM; |
45694aa77 perf tools: Renam... |
226 |
ret = perf_session__process_events(session, &perf_inject); |
454c407ec perf: add perf-in... |
227 228 229 230 231 232 233 234 235 236 237 238 |
perf_session__delete(session); return ret; } static const char * const report_usage[] = { "perf inject [<options>]", NULL }; static const struct option options[] = { |
11d232ec2 perf inject: Add ... |
239 |
OPT_BOOLEAN('b', "build-ids", &inject_build_ids, |
454c407ec perf: add perf-in... |
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
"Inject build-ids into the output stream"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show build ids, etc)"), OPT_END() }; int cmd_inject(int argc, const char **argv, const char *prefix __used) { argc = parse_options(argc, argv, options, report_usage, 0); /* * Any (unrecognized) arguments left? */ if (argc) usage_with_options(report_usage, options); if (symbol__init() < 0) return -1; return __cmd_inject(); } |