builtin-annotate.c 23 KB

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