builtin-annotate.c 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. /*
  2. * builtin-annotate.c
  3. *
  4. * Builtin annotate command: Analyze the perf.data input file,
  5. * look up and read DSOs and symbol information and display
  6. * a histogram of results, along various sorting keys.
  7. */
  8. #include "builtin.h"
  9. #include "util/util.h"
  10. #include "util/color.h"
  11. #include <linux/list.h>
  12. #include "util/cache.h"
  13. #include <linux/rbtree.h>
  14. #include "util/symbol.h"
  15. #include "util/string.h"
  16. #include "perf.h"
  17. #include "util/debug.h"
  18. #include "util/parse-options.h"
  19. #include "util/parse-events.h"
  20. #include "util/thread.h"
  21. static char const *input_name = "perf.data";
  22. static char default_sort_order[] = "comm,symbol";
  23. static char *sort_order = default_sort_order;
  24. static int force;
  25. static int input;
  26. static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
  27. static int full_paths;
  28. static int print_line;
  29. static unsigned long page_size;
  30. static unsigned long mmap_window = 32;
  31. static struct rb_root threads;
  32. static struct thread *last_match;
  33. struct sym_ext {
  34. struct rb_node node;
  35. double percent;
  36. char *path;
  37. };
  38. /*
  39. * histogram, sorted on item, collects counts
  40. */
  41. static struct rb_root hist;
  42. struct hist_entry {
  43. struct rb_node rb_node;
  44. struct thread *thread;
  45. struct map *map;
  46. struct dso *dso;
  47. struct symbol *sym;
  48. u64 ip;
  49. char level;
  50. uint32_t count;
  51. };
  52. /*
  53. * configurable sorting bits
  54. */
  55. struct sort_entry {
  56. struct list_head list;
  57. const char *header;
  58. int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
  59. int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
  60. size_t (*print)(FILE *fp, struct hist_entry *);
  61. };
  62. static int64_t cmp_null(void *l, void *r)
  63. {
  64. if (!l && !r)
  65. return 0;
  66. else if (!l)
  67. return -1;
  68. else
  69. return 1;
  70. }
  71. /* --sort pid */
  72. static int64_t
  73. sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
  74. {
  75. return right->thread->pid - left->thread->pid;
  76. }
  77. static size_t
  78. sort__thread_print(FILE *fp, struct hist_entry *self)
  79. {
  80. return fprintf(fp, "%16s:%5d", self->thread->comm ?: "", self->thread->pid);
  81. }
  82. static struct sort_entry sort_thread = {
  83. .header = " Command: Pid",
  84. .cmp = sort__thread_cmp,
  85. .print = sort__thread_print,
  86. };
  87. /* --sort comm */
  88. static int64_t
  89. sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
  90. {
  91. return right->thread->pid - left->thread->pid;
  92. }
  93. static int64_t
  94. sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
  95. {
  96. char *comm_l = left->thread->comm;
  97. char *comm_r = right->thread->comm;
  98. if (!comm_l || !comm_r)
  99. return cmp_null(comm_l, comm_r);
  100. return strcmp(comm_l, comm_r);
  101. }
  102. static size_t
  103. sort__comm_print(FILE *fp, struct hist_entry *self)
  104. {
  105. return fprintf(fp, "%16s", self->thread->comm);
  106. }
  107. static struct sort_entry sort_comm = {
  108. .header = " Command",
  109. .cmp = sort__comm_cmp,
  110. .collapse = sort__comm_collapse,
  111. .print = sort__comm_print,
  112. };
  113. /* --sort dso */
  114. static int64_t
  115. sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
  116. {
  117. struct dso *dso_l = left->dso;
  118. struct dso *dso_r = right->dso;
  119. if (!dso_l || !dso_r)
  120. return cmp_null(dso_l, dso_r);
  121. return strcmp(dso_l->name, dso_r->name);
  122. }
  123. static size_t
  124. sort__dso_print(FILE *fp, struct hist_entry *self)
  125. {
  126. if (self->dso)
  127. return fprintf(fp, "%-25s", self->dso->name);
  128. return fprintf(fp, "%016llx ", (u64)self->ip);
  129. }
  130. static struct sort_entry sort_dso = {
  131. .header = "Shared Object ",
  132. .cmp = sort__dso_cmp,
  133. .print = sort__dso_print,
  134. };
  135. /* --sort symbol */
  136. static int64_t
  137. sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
  138. {
  139. u64 ip_l, ip_r;
  140. if (left->sym == right->sym)
  141. return 0;
  142. ip_l = left->sym ? left->sym->start : left->ip;
  143. ip_r = right->sym ? right->sym->start : right->ip;
  144. return (int64_t)(ip_r - ip_l);
  145. }
  146. static size_t
  147. sort__sym_print(FILE *fp, struct hist_entry *self)
  148. {
  149. size_t ret = 0;
  150. if (verbose)
  151. ret += fprintf(fp, "%#018llx ", (u64)self->ip);
  152. if (self->sym) {
  153. ret += fprintf(fp, "[%c] %s",
  154. self->dso == kernel_dso ? 'k' : '.', self->sym->name);
  155. } else {
  156. ret += fprintf(fp, "%#016llx", (u64)self->ip);
  157. }
  158. return ret;
  159. }
  160. static struct sort_entry sort_sym = {
  161. .header = "Symbol",
  162. .cmp = sort__sym_cmp,
  163. .print = sort__sym_print,
  164. };
  165. static int sort__need_collapse = 0;
  166. struct sort_dimension {
  167. const char *name;
  168. struct sort_entry *entry;
  169. int taken;
  170. };
  171. static struct sort_dimension sort_dimensions[] = {
  172. { .name = "pid", .entry = &sort_thread, },
  173. { .name = "comm", .entry = &sort_comm, },
  174. { .name = "dso", .entry = &sort_dso, },
  175. { .name = "symbol", .entry = &sort_sym, },
  176. };
  177. static LIST_HEAD(hist_entry__sort_list);
  178. static int sort_dimension__add(char *tok)
  179. {
  180. unsigned int i;
  181. for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
  182. struct sort_dimension *sd = &sort_dimensions[i];
  183. if (sd->taken)
  184. continue;
  185. if (strncasecmp(tok, sd->name, strlen(tok)))
  186. continue;
  187. if (sd->entry->collapse)
  188. sort__need_collapse = 1;
  189. list_add_tail(&sd->entry->list, &hist_entry__sort_list);
  190. sd->taken = 1;
  191. return 0;
  192. }
  193. return -ESRCH;
  194. }
  195. static int64_t
  196. hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
  197. {
  198. struct sort_entry *se;
  199. int64_t cmp = 0;
  200. list_for_each_entry(se, &hist_entry__sort_list, list) {
  201. cmp = se->cmp(left, right);
  202. if (cmp)
  203. break;
  204. }
  205. return cmp;
  206. }
  207. static int64_t
  208. hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
  209. {
  210. struct sort_entry *se;
  211. int64_t cmp = 0;
  212. list_for_each_entry(se, &hist_entry__sort_list, list) {
  213. int64_t (*f)(struct hist_entry *, struct hist_entry *);
  214. f = se->collapse ?: se->cmp;
  215. cmp = f(left, right);
  216. if (cmp)
  217. break;
  218. }
  219. return cmp;
  220. }
  221. /*
  222. * collect histogram counts
  223. */
  224. static void hist_hit(struct hist_entry *he, u64 ip)
  225. {
  226. unsigned int sym_size, offset;
  227. struct symbol *sym = he->sym;
  228. he->count++;
  229. if (!sym || !sym->hist)
  230. return;
  231. sym_size = sym->end - sym->start;
  232. offset = ip - sym->start;
  233. if (offset >= sym_size)
  234. return;
  235. sym->hist_sum++;
  236. sym->hist[offset]++;
  237. if (verbose >= 3)
  238. printf("%p %s: count++ [ip: %p, %08Lx] => %Ld\n",
  239. (void *)(unsigned long)he->sym->start,
  240. he->sym->name,
  241. (void *)(unsigned long)ip, ip - he->sym->start,
  242. sym->hist[offset]);
  243. }
  244. static int
  245. hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
  246. struct symbol *sym, u64 ip, char level)
  247. {
  248. struct rb_node **p = &hist.rb_node;
  249. struct rb_node *parent = NULL;
  250. struct hist_entry *he;
  251. struct hist_entry entry = {
  252. .thread = thread,
  253. .map = map,
  254. .dso = dso,
  255. .sym = sym,
  256. .ip = ip,
  257. .level = level,
  258. .count = 1,
  259. };
  260. int cmp;
  261. while (*p != NULL) {
  262. parent = *p;
  263. he = rb_entry(parent, struct hist_entry, rb_node);
  264. cmp = hist_entry__cmp(&entry, he);
  265. if (!cmp) {
  266. hist_hit(he, ip);
  267. return 0;
  268. }
  269. if (cmp < 0)
  270. p = &(*p)->rb_left;
  271. else
  272. p = &(*p)->rb_right;
  273. }
  274. he = malloc(sizeof(*he));
  275. if (!he)
  276. return -ENOMEM;
  277. *he = entry;
  278. rb_link_node(&he->rb_node, parent, p);
  279. rb_insert_color(&he->rb_node, &hist);
  280. return 0;
  281. }
  282. static void hist_entry__free(struct hist_entry *he)
  283. {
  284. free(he);
  285. }
  286. /*
  287. * collapse the histogram
  288. */
  289. static struct rb_root collapse_hists;
  290. static void collapse__insert_entry(struct hist_entry *he)
  291. {
  292. struct rb_node **p = &collapse_hists.rb_node;
  293. struct rb_node *parent = NULL;
  294. struct hist_entry *iter;
  295. int64_t cmp;
  296. while (*p != NULL) {
  297. parent = *p;
  298. iter = rb_entry(parent, struct hist_entry, rb_node);
  299. cmp = hist_entry__collapse(iter, he);
  300. if (!cmp) {
  301. iter->count += he->count;
  302. hist_entry__free(he);
  303. return;
  304. }
  305. if (cmp < 0)
  306. p = &(*p)->rb_left;
  307. else
  308. p = &(*p)->rb_right;
  309. }
  310. rb_link_node(&he->rb_node, parent, p);
  311. rb_insert_color(&he->rb_node, &collapse_hists);
  312. }
  313. static void collapse__resort(void)
  314. {
  315. struct rb_node *next;
  316. struct hist_entry *n;
  317. if (!sort__need_collapse)
  318. return;
  319. next = rb_first(&hist);
  320. while (next) {
  321. n = rb_entry(next, struct hist_entry, rb_node);
  322. next = rb_next(&n->rb_node);
  323. rb_erase(&n->rb_node, &hist);
  324. collapse__insert_entry(n);
  325. }
  326. }
  327. /*
  328. * reverse the map, sort on count.
  329. */
  330. static struct rb_root output_hists;
  331. static void output__insert_entry(struct hist_entry *he)
  332. {
  333. struct rb_node **p = &output_hists.rb_node;
  334. struct rb_node *parent = NULL;
  335. struct hist_entry *iter;
  336. while (*p != NULL) {
  337. parent = *p;
  338. iter = rb_entry(parent, struct hist_entry, rb_node);
  339. if (he->count > iter->count)
  340. p = &(*p)->rb_left;
  341. else
  342. p = &(*p)->rb_right;
  343. }
  344. rb_link_node(&he->rb_node, parent, p);
  345. rb_insert_color(&he->rb_node, &output_hists);
  346. }
  347. static void output__resort(void)
  348. {
  349. struct rb_node *next;
  350. struct hist_entry *n;
  351. struct rb_root *tree = &hist;
  352. if (sort__need_collapse)
  353. tree = &collapse_hists;
  354. next = rb_first(tree);
  355. while (next) {
  356. n = rb_entry(next, struct hist_entry, rb_node);
  357. next = rb_next(&n->rb_node);
  358. rb_erase(&n->rb_node, tree);
  359. output__insert_entry(n);
  360. }
  361. }
  362. static unsigned long total = 0,
  363. total_mmap = 0,
  364. total_comm = 0,
  365. total_fork = 0,
  366. total_unknown = 0;
  367. static int
  368. process_sample_event(event_t *event, unsigned long offset, unsigned long head)
  369. {
  370. char level;
  371. int show = 0;
  372. struct dso *dso = NULL;
  373. struct thread *thread;
  374. u64 ip = event->ip.ip;
  375. struct map *map = NULL;
  376. thread = threads__findnew(event->ip.pid, &threads, &last_match);
  377. dump_printf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n",
  378. (void *)(offset + head),
  379. (void *)(long)(event->header.size),
  380. event->header.misc,
  381. event->ip.pid,
  382. (void *)(long)ip);
  383. dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
  384. if (thread == NULL) {
  385. fprintf(stderr, "problem processing %d event, skipping it.\n",
  386. event->header.type);
  387. return -1;
  388. }
  389. if (event->header.misc & PERF_RECORD_MISC_KERNEL) {
  390. show = SHOW_KERNEL;
  391. level = 'k';
  392. dso = kernel_dso;
  393. dump_printf(" ...... dso: %s\n", dso->name);
  394. } else if (event->header.misc & PERF_RECORD_MISC_USER) {
  395. show = SHOW_USER;
  396. level = '.';
  397. map = thread__find_map(thread, ip);
  398. if (map != NULL) {
  399. ip = map->map_ip(map, ip);
  400. dso = map->dso;
  401. } else {
  402. /*
  403. * If this is outside of all known maps,
  404. * and is a negative address, try to look it
  405. * up in the kernel dso, as it might be a
  406. * vsyscall (which executes in user-mode):
  407. */
  408. if ((long long)ip < 0)
  409. dso = kernel_dso;
  410. }
  411. dump_printf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
  412. } else {
  413. show = SHOW_HV;
  414. level = 'H';
  415. dump_printf(" ...... dso: [hypervisor]\n");
  416. }
  417. if (show & show_mask) {
  418. struct symbol *sym = NULL;
  419. if (dso)
  420. sym = dso->find_symbol(dso, ip);
  421. if (hist_entry__add(thread, map, dso, sym, ip, level)) {
  422. fprintf(stderr,
  423. "problem incrementing symbol count, skipping event\n");
  424. return -1;
  425. }
  426. }
  427. total++;
  428. return 0;
  429. }
  430. static int
  431. process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
  432. {
  433. struct thread *thread;
  434. struct map *map = map__new(&event->mmap, NULL, 0);
  435. thread = threads__findnew(event->mmap.pid, &threads, &last_match);
  436. dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n",
  437. (void *)(offset + head),
  438. (void *)(long)(event->header.size),
  439. event->mmap.pid,
  440. (void *)(long)event->mmap.start,
  441. (void *)(long)event->mmap.len,
  442. (void *)(long)event->mmap.pgoff,
  443. event->mmap.filename);
  444. if (thread == NULL || map == NULL) {
  445. dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
  446. return 0;
  447. }
  448. thread__insert_map(thread, map);
  449. total_mmap++;
  450. return 0;
  451. }
  452. static int
  453. process_comm_event(event_t *event, unsigned long offset, unsigned long head)
  454. {
  455. struct thread *thread;
  456. thread = threads__findnew(event->comm.pid, &threads, &last_match);
  457. dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
  458. (void *)(offset + head),
  459. (void *)(long)(event->header.size),
  460. event->comm.comm, event->comm.pid);
  461. if (thread == NULL ||
  462. thread__set_comm(thread, event->comm.comm)) {
  463. dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
  464. return -1;
  465. }
  466. total_comm++;
  467. return 0;
  468. }
  469. static int
  470. process_fork_event(event_t *event, unsigned long offset, unsigned long head)
  471. {
  472. struct thread *thread;
  473. struct thread *parent;
  474. thread = threads__findnew(event->fork.pid, &threads, &last_match);
  475. parent = threads__findnew(event->fork.ppid, &threads, &last_match);
  476. dump_printf("%p [%p]: PERF_RECORD_FORK: %d:%d\n",
  477. (void *)(offset + head),
  478. (void *)(long)(event->header.size),
  479. event->fork.pid, event->fork.ppid);
  480. /*
  481. * A thread clone will have the same PID for both
  482. * parent and child.
  483. */
  484. if (thread == parent)
  485. return 0;
  486. if (!thread || !parent || thread__fork(thread, parent)) {
  487. dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
  488. return -1;
  489. }
  490. total_fork++;
  491. return 0;
  492. }
  493. static int
  494. process_event(event_t *event, unsigned long offset, unsigned long head)
  495. {
  496. switch (event->header.type) {
  497. case PERF_RECORD_SAMPLE:
  498. return process_sample_event(event, offset, head);
  499. case PERF_RECORD_MMAP:
  500. return process_mmap_event(event, offset, head);
  501. case PERF_RECORD_COMM:
  502. return process_comm_event(event, offset, head);
  503. case PERF_RECORD_FORK:
  504. return process_fork_event(event, offset, head);
  505. /*
  506. * We dont process them right now but they are fine:
  507. */
  508. case PERF_RECORD_THROTTLE:
  509. case PERF_RECORD_UNTHROTTLE:
  510. return 0;
  511. default:
  512. return -1;
  513. }
  514. return 0;
  515. }
  516. static int
  517. parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
  518. {
  519. char *line = NULL, *tmp, *tmp2;
  520. static const char *prev_line;
  521. static const char *prev_color;
  522. unsigned int offset;
  523. size_t line_len;
  524. s64 line_ip;
  525. int ret;
  526. char *c;
  527. if (getline(&line, &line_len, file) < 0)
  528. return -1;
  529. if (!line)
  530. return -1;
  531. c = strchr(line, '\n');
  532. if (c)
  533. *c = 0;
  534. line_ip = -1;
  535. offset = 0;
  536. ret = -2;
  537. /*
  538. * Strip leading spaces:
  539. */
  540. tmp = line;
  541. while (*tmp) {
  542. if (*tmp != ' ')
  543. break;
  544. tmp++;
  545. }
  546. if (*tmp) {
  547. /*
  548. * Parse hexa addresses followed by ':'
  549. */
  550. line_ip = strtoull(tmp, &tmp2, 16);
  551. if (*tmp2 != ':')
  552. line_ip = -1;
  553. }
  554. if (line_ip != -1) {
  555. const char *path = NULL;
  556. unsigned int hits = 0;
  557. double percent = 0.0;
  558. const char *color;
  559. struct sym_ext *sym_ext = sym->priv;
  560. offset = line_ip - start;
  561. if (offset < len)
  562. hits = sym->hist[offset];
  563. if (offset < len && sym_ext) {
  564. path = sym_ext[offset].path;
  565. percent = sym_ext[offset].percent;
  566. } else if (sym->hist_sum)
  567. percent = 100.0 * hits / sym->hist_sum;
  568. color = get_percent_color(percent);
  569. /*
  570. * Also color the filename and line if needed, with
  571. * the same color than the percentage. Don't print it
  572. * twice for close colored ip with the same filename:line
  573. */
  574. if (path) {
  575. if (!prev_line || strcmp(prev_line, path)
  576. || color != prev_color) {
  577. color_fprintf(stdout, color, " %s", path);
  578. prev_line = path;
  579. prev_color = color;
  580. }
  581. }
  582. color_fprintf(stdout, color, " %7.2f", percent);
  583. printf(" : ");
  584. color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", line);
  585. } else {
  586. if (!*line)
  587. printf(" :\n");
  588. else
  589. printf(" : %s\n", line);
  590. }
  591. return 0;
  592. }
  593. static struct rb_root root_sym_ext;
  594. static void insert_source_line(struct sym_ext *sym_ext)
  595. {
  596. struct sym_ext *iter;
  597. struct rb_node **p = &root_sym_ext.rb_node;
  598. struct rb_node *parent = NULL;
  599. while (*p != NULL) {
  600. parent = *p;
  601. iter = rb_entry(parent, struct sym_ext, node);
  602. if (sym_ext->percent > iter->percent)
  603. p = &(*p)->rb_left;
  604. else
  605. p = &(*p)->rb_right;
  606. }
  607. rb_link_node(&sym_ext->node, parent, p);
  608. rb_insert_color(&sym_ext->node, &root_sym_ext);
  609. }
  610. static void free_source_line(struct symbol *sym, int len)
  611. {
  612. struct sym_ext *sym_ext = sym->priv;
  613. int i;
  614. if (!sym_ext)
  615. return;
  616. for (i = 0; i < len; i++)
  617. free(sym_ext[i].path);
  618. free(sym_ext);
  619. sym->priv = NULL;
  620. root_sym_ext = RB_ROOT;
  621. }
  622. /* Get the filename:line for the colored entries */
  623. static void
  624. get_source_line(struct symbol *sym, u64 start, int len, const char *filename)
  625. {
  626. int i;
  627. char cmd[PATH_MAX * 2];
  628. struct sym_ext *sym_ext;
  629. if (!sym->hist_sum)
  630. return;
  631. sym->priv = calloc(len, sizeof(struct sym_ext));
  632. if (!sym->priv)
  633. return;
  634. sym_ext = sym->priv;
  635. for (i = 0; i < len; i++) {
  636. char *path = NULL;
  637. size_t line_len;
  638. u64 offset;
  639. FILE *fp;
  640. sym_ext[i].percent = 100.0 * sym->hist[i] / sym->hist_sum;
  641. if (sym_ext[i].percent <= 0.5)
  642. continue;
  643. offset = start + i;
  644. sprintf(cmd, "addr2line -e %s %016llx", filename, offset);
  645. fp = popen(cmd, "r");
  646. if (!fp)
  647. continue;
  648. if (getline(&path, &line_len, fp) < 0 || !line_len)
  649. goto next;
  650. sym_ext[i].path = malloc(sizeof(char) * line_len + 1);
  651. if (!sym_ext[i].path)
  652. goto next;
  653. strcpy(sym_ext[i].path, path);
  654. insert_source_line(&sym_ext[i]);
  655. next:
  656. pclose(fp);
  657. }
  658. }
  659. static void print_summary(const char *filename)
  660. {
  661. struct sym_ext *sym_ext;
  662. struct rb_node *node;
  663. printf("\nSorted summary for file %s\n", filename);
  664. printf("----------------------------------------------\n\n");
  665. if (RB_EMPTY_ROOT(&root_sym_ext)) {
  666. printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
  667. return;
  668. }
  669. node = rb_first(&root_sym_ext);
  670. while (node) {
  671. double percent;
  672. const char *color;
  673. char *path;
  674. sym_ext = rb_entry(node, struct sym_ext, node);
  675. percent = sym_ext->percent;
  676. color = get_percent_color(percent);
  677. path = sym_ext->path;
  678. color_fprintf(stdout, color, " %7.2f %s", percent, path);
  679. node = rb_next(node);
  680. }
  681. }
  682. static void annotate_sym(struct dso *dso, struct symbol *sym)
  683. {
  684. const char *filename = dso->name, *d_filename;
  685. u64 start, end, len;
  686. char command[PATH_MAX*2];
  687. FILE *file;
  688. if (!filename)
  689. return;
  690. if (sym->module)
  691. filename = sym->module->path;
  692. else if (dso == kernel_dso)
  693. filename = vmlinux_name;
  694. start = sym->obj_start;
  695. if (!start)
  696. start = sym->start;
  697. if (full_paths)
  698. d_filename = filename;
  699. else
  700. d_filename = basename(filename);
  701. end = start + sym->end - sym->start + 1;
  702. len = sym->end - sym->start;
  703. if (print_line) {
  704. get_source_line(sym, start, len, filename);
  705. print_summary(filename);
  706. }
  707. printf("\n\n------------------------------------------------\n");
  708. printf(" Percent | Source code & Disassembly of %s\n", d_filename);
  709. printf("------------------------------------------------\n");
  710. if (verbose >= 2)
  711. printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
  712. sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
  713. (u64)start, (u64)end, filename, filename);
  714. if (verbose >= 3)
  715. printf("doing: %s\n", command);
  716. file = popen(command, "r");
  717. if (!file)
  718. return;
  719. while (!feof(file)) {
  720. if (parse_line(file, sym, start, len) < 0)
  721. break;
  722. }
  723. pclose(file);
  724. if (print_line)
  725. free_source_line(sym, len);
  726. }
  727. static void find_annotations(void)
  728. {
  729. struct rb_node *nd;
  730. struct dso *dso;
  731. int count = 0;
  732. list_for_each_entry(dso, &dsos, node) {
  733. for (nd = rb_first(&dso->syms); nd; nd = rb_next(nd)) {
  734. struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
  735. if (sym->hist) {
  736. annotate_sym(dso, sym);
  737. count++;
  738. }
  739. }
  740. }
  741. if (!count)
  742. printf(" Error: symbol '%s' not present amongst the samples.\n", sym_hist_filter);
  743. }
  744. static int __cmd_annotate(void)
  745. {
  746. int ret, rc = EXIT_FAILURE;
  747. unsigned long offset = 0;
  748. unsigned long head = 0;
  749. struct stat input_stat;
  750. event_t *event;
  751. uint32_t size;
  752. char *buf;
  753. register_idle_thread(&threads, &last_match);
  754. input = open(input_name, O_RDONLY);
  755. if (input < 0) {
  756. perror("failed to open file");
  757. exit(-1);
  758. }
  759. ret = fstat(input, &input_stat);
  760. if (ret < 0) {
  761. perror("failed to stat file");
  762. exit(-1);
  763. }
  764. if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
  765. fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
  766. exit(-1);
  767. }
  768. if (!input_stat.st_size) {
  769. fprintf(stderr, "zero-sized file, nothing to do!\n");
  770. exit(0);
  771. }
  772. if (load_kernel() < 0) {
  773. perror("failed to load kernel symbols");
  774. return EXIT_FAILURE;
  775. }
  776. remap:
  777. buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
  778. MAP_SHARED, input, offset);
  779. if (buf == MAP_FAILED) {
  780. perror("failed to mmap file");
  781. exit(-1);
  782. }
  783. more:
  784. event = (event_t *)(buf + head);
  785. size = event->header.size;
  786. if (!size)
  787. size = 8;
  788. if (head + event->header.size >= page_size * mmap_window) {
  789. unsigned long shift = page_size * (head / page_size);
  790. int munmap_ret;
  791. munmap_ret = munmap(buf, page_size * mmap_window);
  792. assert(munmap_ret == 0);
  793. offset += shift;
  794. head -= shift;
  795. goto remap;
  796. }
  797. size = event->header.size;
  798. dump_printf("%p [%p]: event: %d\n",
  799. (void *)(offset + head),
  800. (void *)(long)event->header.size,
  801. event->header.type);
  802. if (!size || process_event(event, offset, head) < 0) {
  803. dump_printf("%p [%p]: skipping unknown header type: %d\n",
  804. (void *)(offset + head),
  805. (void *)(long)(event->header.size),
  806. event->header.type);
  807. total_unknown++;
  808. /*
  809. * assume we lost track of the stream, check alignment, and
  810. * increment a single u64 in the hope to catch on again 'soon'.
  811. */
  812. if (unlikely(head & 7))
  813. head &= ~7ULL;
  814. size = 8;
  815. }
  816. head += size;
  817. if (offset + head < (unsigned long)input_stat.st_size)
  818. goto more;
  819. rc = EXIT_SUCCESS;
  820. close(input);
  821. dump_printf(" IP events: %10ld\n", total);
  822. dump_printf(" mmap events: %10ld\n", total_mmap);
  823. dump_printf(" comm events: %10ld\n", total_comm);
  824. dump_printf(" fork events: %10ld\n", total_fork);
  825. dump_printf(" unknown events: %10ld\n", total_unknown);
  826. if (dump_trace)
  827. return 0;
  828. if (verbose >= 3)
  829. threads__fprintf(stdout, &threads);
  830. if (verbose >= 2)
  831. dsos__fprintf(stdout);
  832. collapse__resort();
  833. output__resort();
  834. find_annotations();
  835. return rc;
  836. }
  837. static const char * const annotate_usage[] = {
  838. "perf annotate [<options>] <command>",
  839. NULL
  840. };
  841. static const struct option options[] = {
  842. OPT_STRING('i', "input", &input_name, "file",
  843. "input file name"),
  844. OPT_STRING('s', "symbol", &sym_hist_filter, "symbol",
  845. "symbol to annotate"),
  846. OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
  847. OPT_BOOLEAN('v', "verbose", &verbose,
  848. "be more verbose (show symbol address, etc)"),
  849. OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
  850. "dump raw trace in ASCII"),
  851. OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"),
  852. OPT_BOOLEAN('m', "modules", &modules,
  853. "load module symbols - WARNING: use only with -k and LIVE kernel"),
  854. OPT_BOOLEAN('l', "print-line", &print_line,
  855. "print matching source lines (may be slow)"),
  856. OPT_BOOLEAN('P', "full-paths", &full_paths,
  857. "Don't shorten the displayed pathnames"),
  858. OPT_END()
  859. };
  860. static void setup_sorting(void)
  861. {
  862. char *tmp, *tok, *str = strdup(sort_order);
  863. for (tok = strtok_r(str, ", ", &tmp);
  864. tok; tok = strtok_r(NULL, ", ", &tmp)) {
  865. if (sort_dimension__add(tok) < 0) {
  866. error("Unknown --sort key: `%s'", tok);
  867. usage_with_options(annotate_usage, options);
  868. }
  869. }
  870. free(str);
  871. }
  872. int cmd_annotate(int argc, const char **argv, const char *prefix __used)
  873. {
  874. symbol__init();
  875. page_size = getpagesize();
  876. argc = parse_options(argc, argv, options, annotate_usage, 0);
  877. setup_sorting();
  878. if (argc) {
  879. /*
  880. * Special case: if there's an argument left then assume tha
  881. * it's a symbol filter:
  882. */
  883. if (argc > 1)
  884. usage_with_options(annotate_usage, options);
  885. sym_hist_filter = argv[0];
  886. }
  887. if (!sym_hist_filter)
  888. usage_with_options(annotate_usage, options);
  889. setup_pager();
  890. return __cmd_annotate();
  891. }