1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../perf.h" 2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util.h" 3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/mman.h> 4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef BACKTRACE_SUPPORT 5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <execinfo.h> 6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif 7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h> 8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h> 9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * XXX We need to find a better place for these things... 12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned int page_size; 14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool test_attr__enabled; 16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool perf_host = true; 18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool perf_guest = false; 19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengchar tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events"; 21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid event_attr_init(struct perf_event_attr *attr) 23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!perf_host) 25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->exclude_host = 1; 26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!perf_guest) 27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->exclude_guest = 1; 28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* to capture ABI version */ 29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng attr->size = sizeof(*attr); 30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint mkdir_p(char *path, mode_t mode) 33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct stat st; 35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err; 36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *d = path; 37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (*d != '/') 39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (stat(path, &st) == 0) 42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (*++d == '/'); 45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while ((d = strchr(d, '/'))) { 47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *d = '\0'; 48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = stat(path, &st) && mkdir(path, mode); 49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *d++ = '/'; 50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (err) 51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (*d == '/') 53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++d; 54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int slow_copyfile(const char *from, const char *to) 59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err = 0; 61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *line = NULL; 62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t n; 63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng FILE *from_fp = fopen(from, "r"), *to_fp; 64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (from_fp == NULL) 66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out; 67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng to_fp = fopen(to, "w"); 69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (to_fp == NULL) 70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_fclose_from; 71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (getline(&line, &n, from_fp) > 0) 73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (fputs(line, to_fp) == EOF) 74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_fclose_to; 75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = 0; 76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_fclose_to: 77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fclose(to_fp); 78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(line); 79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_fclose_from: 80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fclose(from_fp); 81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout: 82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return err; 83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint copyfile(const char *from, const char *to) 86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int fromfd, tofd; 88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct stat st; 89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *addr; 90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int err = -1; 91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (stat(from, &st)) 93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out; 94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (st.st_size == 0) /* /proc? do it slowly... */ 96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return slow_copyfile(from, to); 97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fromfd = open(from, O_RDONLY); 99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (fromfd < 0) 100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out; 101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tofd = creat(to, 0755); 103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tofd < 0) 104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close_from; 105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0); 107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (addr == MAP_FAILED) 108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_close_to; 109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (write(tofd, addr, st.st_size) == st.st_size) 111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = 0; 112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng munmap(addr, st.st_size); 114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_close_to: 115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng close(tofd); 116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (err) 117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unlink(to); 118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_close_from: 119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng close(fromfd); 120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout: 121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return err; 122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long convert_unit(unsigned long value, char *unit) 125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *unit = ' '; 127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (value > 1000) { 129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng value /= 1000; 130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *unit = 'K'; 131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (value > 1000) { 134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng value /= 1000; 135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *unit = 'M'; 136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (value > 1000) { 139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng value /= 1000; 140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *unit = 'G'; 141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return value; 144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint readn(int fd, void *buf, size_t n) 147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *buf_start = buf; 149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (n) { 151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret = read(fd, buf, n); 152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret <= 0) 154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng n -= ret; 157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng buf += ret; 158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return buf - buf_start; 161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengsize_t hex_width(u64 v) 164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t n = 1; 166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while ((v >>= 4)) 168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ++n; 169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return n; 171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int hex(char ch) 174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if ((ch >= '0') && (ch <= '9')) 176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ch - '0'; 177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if ((ch >= 'a') && (ch <= 'f')) 178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ch - 'a' + 10; 179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if ((ch >= 'A') && (ch <= 'F')) 180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ch - 'A' + 10; 181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * While we find nice hex chars, build a long_val. 186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Return number of chars processed. 187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint hex2u64(const char *ptr, u64 *long_val) 189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *p = ptr; 191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *long_val = 0; 192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (*p) { 194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const int hex_val = hex(*p); 195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (hex_val < 0) 197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng break; 198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *long_val = (*long_val << 4) | hex_val; 200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng p++; 201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return p - ptr; 204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* Obtain a backtrace and print it to stdout. */ 207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef BACKTRACE_SUPPORT 208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid dump_stack(void) 209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng void *array[16]; 211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t size = backtrace(array, ARRAY_SIZE(array)); 212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char **strings = backtrace_symbols(array, size); 213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng size_t i; 214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("Obtained %zd stack frames.\n", size); 216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < size; i++) 218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printf("%s\n", strings[i]); 219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(strings); 221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#else 223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid dump_stack(void) {} 224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif 225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid get_term_dimensions(struct winsize *ws) 227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *s = getenv("LINES"); 229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (s != NULL) { 231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ws->ws_row = atoi(s); 232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s = getenv("COLUMNS"); 233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (s != NULL) { 234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ws->ws_col = atoi(s); 235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ws->ws_row && ws->ws_col) 236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef TIOCGWINSZ 240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ioctl(1, TIOCGWINSZ, ws) == 0 && 241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ws->ws_row && ws->ws_col) 242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif 244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ws->ws_row = 25; 245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ws->ws_col = 80; 246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void set_tracing_events_path(const char *mountpoint) 249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s", 251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mountpoint, "tracing/events"); 252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengconst char *perf_debugfs_mount(const char *mountpoint) 255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *mnt; 257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mnt = debugfs_mount(mountpoint); 259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!mnt) 260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng set_tracing_events_path(mnt); 263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return mnt; 265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_debugfs_set_path(const char *mntpt) 268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng snprintf(debugfs_mountpoint, strlen(debugfs_mountpoint), "%s", mntpt); 270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng set_tracing_events_path(mntpt); 271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const char *find_debugfs(void) 274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *path = perf_debugfs_mount(NULL); 276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!path) 278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fprintf(stderr, "Your kernel does not support the debugfs filesystem"); 279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return path; 281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Finds the path to the debugfs/tracing 285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Allocates the string and stores it. 286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengconst char *find_tracing_dir(void) 288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static char *tracing; 290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static int tracing_found; 291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *debugfs; 292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (tracing_found) 294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tracing; 295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng debugfs = find_debugfs(); 297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!debugfs) 298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tracing = malloc(strlen(debugfs) + 9); 301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!tracing) 302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sprintf(tracing, "%s/tracing", debugfs); 305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tracing_found = 1; 307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tracing; 308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengchar *get_tracing_file(const char *name) 311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *tracing; 313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *file; 314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tracing = find_tracing_dir(); 316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!tracing) 317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng file = malloc(strlen(tracing) + strlen(name) + 2); 320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!file) 321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sprintf(file, "%s/%s", tracing, name); 324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return file; 325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid put_tracing_file(char *file) 328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(file); 330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint parse_nsec_time(const char *str, u64 *ptime) 333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 time_sec, time_nsec; 335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *end; 336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng time_sec = strtoul(str, &end, 10); 338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (*end != '.' && *end != '\0') 339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (*end == '.') { 342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int i; 343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char nsec_buf[10]; 344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (strlen(++end) > 9) 346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng strncpy(nsec_buf, end, 9); 349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng nsec_buf[9] = '\0'; 350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* make it nsec precision */ 352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = strlen(nsec_buf); i < 9; i++) 353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng nsec_buf[i] = '0'; 354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng time_nsec = strtoul(nsec_buf, &end, 10); 356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (*end != '\0') 357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } else 359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng time_nsec = 0; 360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *ptime = time_sec * NSEC_PER_SEC + time_nsec; 362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 364