Created
November 2, 2016 14:31
-
-
Save thejh/071e5c24ec02fabfef258eea2df622e0 to your computer and use it in GitHub Desktop.
PERF_SAMPLE_REGS_INTR demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ./perf_sample_regs_intr_demo | |
data_head is at ff0 | |
rax=0xffffffffffffffff rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0x4005b0 | |
rax=0xfffffffffffffff7 rbp=0xffffa5fc43efff48 rsp=0xffffa5fc43efff28 rip=0xffffffff97c55f1d | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce18 | |
rax=0xffff8fc3ba3b79c0 rbp=0xffffa5fc43efff00 rsp=0xffffa5fc43effef0 rip=0xffffffff97c745c9 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce18 | |
rax=0x0 rbp=0xffffa5fc43efff00 rsp=0xffffa5fc43effef8 rip=0xffffffff97c75049 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce15 | |
rax=0xffffffffffffffff rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040c0 rip=0x4007d5 | |
rax=0xfffffffffffffff7 rbp=0xffffa5fc43efff48 rsp=0xffffa5fc43efff10 rip=0xffffffff97c55f43 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce18 | |
rax=0xffff8fc3ba3b79c0 rbp=0xffffa5fc43efff00 rsp=0xffffa5fc43effef0 rip=0xffffffff97c745c9 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce18 | |
rax=0x0 rbp=0xffffa5fc43efff00 rsp=0xffffa5fc43effef8 rip=0xffffffff97c75049 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce15 | |
rax=0xffffffffffffffff rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040c0 rip=0x4007d5 | |
rax=0xfffffffffffffff7 rbp=0xffffa5fc43efff48 rsp=0xffffa5fc43efff10 rip=0xffffffff97c55f43 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce18 | |
rax=0x0 rbp=0xffffa5fc43efff00 rsp=0xffffa5fc43effef8 rip=0xffffffff97c75049 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce15 | |
rax=0xffffffffffffffff rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040c0 rip=0x4007d5 | |
rax=0xfffffffffffffff7 rbp=0xffffa5fc43efff48 rsp=0xffffa5fc43efff10 rip=0xffffffff97c55f43 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce18 | |
rax=0x0 rbp=0xffffa5fc43efff00 rsp=0xffffa5fc43effef8 rip=0xffffffff97c75049 | |
rax=0xfffffffffffffff7 rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0xffffffff9862ce15 | |
rax=0xffffffffffffffff rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040c0 rip=0x4007d5 | |
rax=0xfffffffffffffff7 rbp=0xffffa5fc43efff48 rsp=0xffffa5fc43efff10 rip=0xffffffff97c55f43 | |
rax=0xffffffffffffffff rbp=0x7ffc9ec04170 rsp=0x7ffc9ec040b8 rip=0x4005b0 | |
[...] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// compile with: | |
// gcc -Wall -std=gnu99 -o perf_sample_regs_intr_demo perf_sample_regs_intr_demo.c | |
#define _GNU_SOURCE | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <err.h> | |
#include <inttypes.h> | |
#include <assert.h> | |
#include <errno.h> | |
#include <time.h> | |
#include <stdlib.h> | |
#include <sys/syscall.h> | |
#include <sys/types.h> | |
#include <sys/mman.h> | |
#include <sys/wait.h> | |
#include <linux/perf_event.h> | |
#include <asm/perf_regs.h> | |
struct my_event { | |
struct perf_event_header header; | |
uint64_t abi; | |
uint64_t regs[4]; | |
}; | |
long perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags) { | |
return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); | |
} | |
int main(void) { | |
int status; | |
pid_t child = fork(); | |
if (child == -1) | |
err(1, "fork"); | |
if (child == 0) { | |
sleep(1); /* quick-and-dirty way to wait for the parent to attach */ | |
for (int i=0; i<1000000; i++) { | |
write(100000, NULL, 1); | |
} | |
return 0; | |
} | |
struct perf_event_attr attr = { | |
.type = PERF_TYPE_HARDWARE, | |
.config = PERF_COUNT_HW_INSTRUCTIONS, | |
.size = sizeof(struct perf_event_attr), | |
.sample_period = 100000, | |
.sample_type = PERF_SAMPLE_REGS_INTR, | |
.precise_ip = 2, | |
.sample_regs_intr = | |
(1<<PERF_REG_X86_AX) | | |
(1<<PERF_REG_X86_BP) | | |
(1<<PERF_REG_X86_SP) | | |
(1<<PERF_REG_X86_IP) | |
}; | |
int perf_fd = perf_event_open(&attr, child, -1, -1, 0); | |
if (perf_fd == -1) | |
err(1, "perf_event_open"); | |
struct perf_event_mmap_page *meta_page = mmap(NULL, 2*4096, PROT_READ|PROT_WRITE, MAP_SHARED, perf_fd, 0); | |
if (meta_page == MAP_FAILED) | |
err(1, "mmap"); | |
if (waitpid(child, &status, 0) != child) | |
err(1, "waitpid"); | |
uint64_t data_head = meta_page->data_head; | |
if (data_head == 0) { | |
puts("no data!"); | |
return 0; | |
} | |
printf("data_head is at %lx\n", (unsigned long)data_head); | |
struct perf_event_header *head = (void*)((char*)meta_page + 4096); | |
while ((char*)head + head->size < (char*)meta_page + 4096 + data_head) { | |
if (head->type == PERF_RECORD_SAMPLE) { | |
struct my_event *ev = (void*)head; | |
printf("rax=0x%lx rbp=0x%lx rsp=0x%lx rip=0x%lx\n", | |
ev->regs[0], ev->regs[1], ev->regs[2], ev->regs[3]); | |
} | |
head = (void*)((char*)head + head->size); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment