1 #include <linux/types.h>
10 static const char *perf_event__names[] = {
32 if (!perf_event__names[
id])
34 return perf_event__names[
id];
46 static pid_t perf_event__get_comm_tgid(
pid_t pid,
char *comm,
size_t len)
54 snprintf(filename,
sizeof(filename),
"/proc/%d/status", pid);
56 fp = fopen(filename,
"r");
58 pr_debug(
"couldn't open %s\n", filename);
62 while (!comm[0] || (tgid < 0)) {
63 if (fgets(bf,
sizeof(bf), fp) ==
NULL) {
64 pr_warning(
"couldn't get COMM and pgid, malformed %s\n",
69 if (
memcmp(bf,
"Name:", 5) == 0) {
79 }
else if (
memcmp(bf,
"Tgid:", 5) == 0) {
81 while (*tgids &&
isspace(*tgids))
106 tgid = perf_event__get_comm_tgid(pid, event->
comm.comm,
107 sizeof(event->
comm.comm));
111 event->comm.pid = tgid;
117 event->comm.header.size = (
sizeof(
event->comm) -
121 event->comm.tid =
pid;
123 if (process(tool, event, &synth_sample, machine) != 0)
129 snprintf(filename,
sizeof(filename),
"/proc/%d/task", pid);
131 tasks = opendir(filename);
133 pr_debug(
"couldn't open %s\n", filename);
137 while (!readdir_r(tasks, &
dirent, &next) && next) {
139 pid = strtol(
dirent.d_name, &end, 10);
144 (
void) perf_event__get_comm_tgid(pid, event->
comm.comm,
145 sizeof(event->
comm.comm));
150 event->comm.header.size = (
sizeof(
event->comm) -
154 event->comm.tid =
pid;
156 if (process(tool, event, &synth_sample, machine) != 0) {
167 static int perf_event__synthesize_mmap_events(
struct perf_tool *tool,
171 struct machine *machine)
177 snprintf(filename,
sizeof(filename),
"/proc/%d/maps", pid);
179 fp = fopen(filename,
"r");
184 pr_debug(
"couldn't open %s\n", filename);
195 char bf[BUFSIZ], *pbf =
bf;
198 if (fgets(bf,
sizeof(bf), fp) ==
NULL)
211 char anonstr[] =
"//anon\n";
212 char *execname =
strchr(bf,
'/');
215 if (execname ==
NULL)
216 execname =
strstr(bf,
"[vdso]");
222 if (execname ==
NULL)
229 execname[size - 1] =
'\0';
232 event->mmap.len -=
event->mmap.start;
233 event->mmap.header.size = (
sizeof(
event->mmap) -
234 (
sizeof(event->
mmap.filename) -
size));
237 event->mmap.pid = tgid;
238 event->mmap.tid =
pid;
240 if (process(tool, event, &synth_sample, machine) != 0) {
253 struct machine *machine)
261 pr_debug(
"Not enough memory synthesizing mmap event "
262 "for kernel modules\n");
272 if (machine__is_host(machine))
282 if (pos->
dso->kernel)
287 event->mmap.header.size = (
sizeof(
event->mmap) -
288 (
sizeof(event->
mmap.filename) -
size));
291 event->mmap.start = pos->
start;
292 event->mmap.len = pos->
end - pos->
start;
293 event->mmap.pid = machine->
pid;
296 pos->
dso->long_name_len + 1);
297 if (process(tool, event, &synth_sample, machine) != 0) {
312 struct machine *machine)
314 pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, full,
318 return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
325 struct machine *machine)
331 if (comm_event ==
NULL)
335 if (mmap_event ==
NULL)
340 if (__event__synthesize_thread(comm_event, mmap_event,
342 process, tool, machine)) {
352 bool need_leader =
true;
355 for (j = 0; j < threads->
nr; ++
j) {
356 if ((
int) comm_event->
comm.pid == threads->
map[j]) {
364 __event__synthesize_thread(comm_event,
366 comm_event->
comm.pid, 0,
367 process, tool, machine)) {
382 struct machine *machine)
390 if (comm_event ==
NULL)
394 if (mmap_event ==
NULL)
397 proc = opendir(
"/proc");
401 while (!readdir_r(proc, &dirent, &next) && next) {
403 pid_t pid = strtol(dirent.d_name, &end, 10);
408 if (__event__synthesize_thread(comm_event, mmap_event, pid, 1,
409 process, tool, machine) != 0) {
431 static int find_symbol_cb(
void *
arg,
const char *name,
char type,
450 struct machine *machine,
451 const char *symbol_name)
468 pr_debug(
"Not enough memory synthesizing mmap event "
469 "for kernel modules\n");
474 if (machine__is_host(machine)) {
480 filename =
"/proc/kallsyms";
483 if (machine__is_default_guest(machine))
496 "%s%s", mmap_name, symbol_name) + 1;
499 event->mmap.header.size = (
sizeof(
event->mmap) -
501 event->mmap.pgoff =
args.start;
503 event->mmap.len =
map->
end -
event->mmap.start;
504 event->mmap.pid = machine->
pid;
506 err = process(tool, event, &synth_sample, machine);
520 struct machine *machine)
528 dump_printf(
"problem processing PERF_RECORD_COMM, skipping event.\n");
538 struct machine *machine __maybe_unused)
545 static void perf_event__set_kernel_mmap_len(
union perf_event *event,
558 static int perf_event__process_kernel_mmap(
struct perf_tool *tool
561 struct machine *machine)
569 if (machine__is_host(machine))
576 strlen(kmmap_prefix) - 1) == 0;
577 if (event->
mmap.filename[0] ==
'/' ||
578 (!is_kernel_mmap && event->
mmap.filename[0] ==
'[')) {
580 char short_module_name[1024];
583 if (event->
mmap.filename[0] ==
'/') {
592 snprintf(short_module_name,
sizeof(short_module_name),
593 "[%.*s]", (
int)(dot - name), name);
596 strcpy(short_module_name, event->
mmap.filename);
599 event->
mmap.filename);
603 name = strdup(short_module_name);
608 map->
dso->sname_alloc = 1;
609 map->
end = map->
start +
event->mmap.len;
610 }
else if (is_kernel_mmap) {
611 const char *symbol_name = (
event->mmap.filename +
622 kernel->
kernel = kernel_type;
626 perf_event__set_kernel_mmap_len(event, machine->
vmlinux_maps);
633 if (event->
mmap.pgoff != 0) {
639 if (machine__is_default_guest(machine)) {
656 event->
mmap.len, event->
mmap.pgoff, event->
mmap.filename);
662 struct machine *machine)
674 ret = perf_event__process_kernel_mmap(tool, event, machine);
685 event->
mmap.pid, event->
mmap.filename,
694 dump_printf(
"problem processing PERF_RECORD_MMAP, skipping event.\n");
700 return fprintf(fp,
"(%d:%d):(%d:%d)\n",
702 event->
fork.ppid, event->
fork.ptid);
708 struct machine *machine)
721 if (thread ==
NULL || parent ==
NULL ||
723 dump_printf(
"problem processing PERF_RECORD_FORK, skipping event.\n");
735 switch (event->
header.type) {
756 switch (event->
header.type) {
777 struct machine *machine,
u8 cpumode,
788 if (machine ==
NULL) {
795 mg = &machine->
kmaps;
800 mg = &machine->
kmaps;
824 al->
map = map_groups__find(mg, type, al->
addr);
835 if ((
long long)al->
addr < 0 &&
837 machine && mg != &machine->
kmaps) {
838 mg = &machine->
kmaps;
858 struct machine *machine,
888 al->
map ? al->
map->dso->long_name :
889 al->
level ==
'H' ?
"[hypervisor]" :
"<not found>");