History

Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/urgent

Ingo Molnar committed 15 years ago

Commit f64fac82 parents 6221f22 1d46ea22 files · +113 −65Browse files

Unified · Split

2 files
  1. tools/perf/util/probe-event.c +8 −11
  2. tools/perf/util/probe-finder.c +105 −54
tools/perf/util/probe-event.c+8−11
@@ -234,7 +234,6 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, · 233 unmodified lines
234 234
235 /* Searching trace events corresponding to probe event */235 /* Searching trace events corresponding to probe event */
236 ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs);236 ntevs = find_probe_trace_events(fd, pev, tevs, max_tevs);
237 close(fd);
238 237
239 if (ntevs > 0) { /* Succeeded to find trace events */238 if (ntevs > 0) { /* Succeeded to find trace events */
240 pr_debug("find %d probe_trace_events.\n", ntevs);239 pr_debug("find %d probe_trace_events.\n", ntevs);
@@ -388,7 +387,6 @@ int show_line_range(struct line_range *lr, const char *module) · 147 unmodified lines
388 }387 }
389 388
390 ret = find_line_range(fd, lr);389 ret = find_line_range(fd, lr);
391 close(fd);
392 if (ret == 0) {390 if (ret == 0) {
393 pr_warning("Specified source line is not found.\n");391 pr_warning("Specified source line is not found.\n");
394 return -ENOENT;392 return -ENOENT;
@@ -512,19 +510,18 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, · 117 unmodified lines
512 if (ret < 0)510 if (ret < 0)
513 return ret;511 return ret;
514 512
515 fd = open_vmlinux(module);
516 if (fd < 0) {
517 pr_warning("Failed to open debug information file.\n");
518 return fd;
519 }
520
521 setup_pager();513 setup_pager();
522 514
523 for (i = 0; i < npevs && ret >= 0; i++)515 for (i = 0; i < npevs && ret >= 0; i++) {
516 fd = open_vmlinux(module);
517 if (fd < 0) {
518 pr_warning("Failed to open debug information file.\n");
519 ret = fd;
520 break;
521 }
524 ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter,522 ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter,
525 externs);523 externs);
526 524 }
527 close(fd);
528 return ret;525 return ret;
529}526}
530 527
tools/perf/util/probe-finder.c+105−54
@@ -273,6 +273,25 @@ static const char *cu_get_comp_dir(Dwarf_Die *cu_die) · 272 unmodified lines
273 return dwarf_formstring(&attr);273 return dwarf_formstring(&attr);
274}274}
275 275
276/* Get a line number and file name for given address */
277static int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
278 const char **fname, int *lineno)
279{
280 Dwarf_Line *line;
281 Dwarf_Addr laddr;
282
283 line = dwarf_getsrc_die(cudie, (Dwarf_Addr)addr);
284 if (line && dwarf_lineaddr(line, &laddr) == 0 &&
285 addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
286 *fname = dwarf_linesrc(line, NULL, NULL);
287 if (!*fname)
288 /* line number is useless without filename */
289 *lineno = 0;
290 }
291
292 return *lineno ?: -ENOENT;
293}
294
276/* Compare diename and tname */295/* Compare diename and tname */
277static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)296static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
278{297{
@@ -497,7 +516,20 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) · 218 unmodified lines
497static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,516static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
498 Dwarf_Die *die_mem)517 Dwarf_Die *die_mem)
499{518{
500 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);519 Dwarf_Die tmp_die;
520
521 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
522 if (!sp_die)
523 return NULL;
524
525 /* Inlined function could be recursive. Trace it until fail */
526 while (sp_die) {
527 memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
528 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
529 &tmp_die);
530 }
531
532 return die_mem;
501}533}
502 534
503/* Walker on lines (Note: line number will not be sorted) */535/* Walker on lines (Note: line number will not be sorted) */
@@ -1395,6 +1427,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) · 891 unmodified lines
1395 !die_compare_name(sp_die, pp->function))1427 !die_compare_name(sp_die, pp->function))
1396 return DWARF_CB_OK;1428 return DWARF_CB_OK;
1397 1429
1430 /* Check declared file */
1431 if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die)))
1432 return DWARF_CB_OK;
1433
1398 pf->fname = dwarf_decl_file(sp_die);1434 pf->fname = dwarf_decl_file(sp_die);
1399 if (pp->line) { /* Function relative line */1435 if (pp->line) { /* Function relative line */
1400 dwarf_decl_line(sp_die, &pf->lno);1436 dwarf_decl_line(sp_die, &pf->lno);
@@ -1451,6 +1487,7 @@ static int find_probes(int fd, struct probe_finder *pf) · 50 unmodified lines
1451 if (!dbg) {1487 if (!dbg) {
1452 pr_warning("No debug information found in the vmlinux - "1488 pr_warning("No debug information found in the vmlinux - "
1453 "please rebuild with CONFIG_DEBUG_INFO=y.\n");1489 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1490 close(fd); /* Without dwfl_end(), fd isn't closed. */
1454 return -EBADF;1491 return -EBADF;
1455 }1492 }
1456 1493
@@ -1686,11 +1723,9 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) · 229 unmodified lines
1686 Dwarf_Die cudie, spdie, indie;1723 Dwarf_Die cudie, spdie, indie;
1687 Dwarf *dbg = NULL;1724 Dwarf *dbg = NULL;
1688 Dwfl *dwfl = NULL;1725 Dwfl *dwfl = NULL;
1689 Dwarf_Line *line;1726 Dwarf_Addr _addr, baseaddr, bias = 0;
1690 Dwarf_Addr laddr, eaddr, bias = 0;1727 const char *fname = NULL, *func = NULL, *tmp;
1691 const char *tmp;1728 int baseline = 0, lineno = 0, ret = 0;
1692 int lineno, ret = 0;
1693 bool found = false;
1694 1729
1695 /* Open the live linux kernel */1730 /* Open the live linux kernel */
1696 dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias);1731 dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias);
@@ -1711,68 +1746,79 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) · 14 unmodified lines
1711 goto end;1746 goto end;
1712 }1747 }
1713 1748
1714 /* Find a corresponding line */1749 /* Find a corresponding line (filename and lineno) */
1715 line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr);1750 cu_find_lineinfo(&cudie, addr, &fname, &lineno);
1716 if (line) {1751 /* Don't care whether it failed or not */
1717 if (dwarf_lineaddr(line, &laddr) == 0 &&
1718 (Dwarf_Addr)addr == laddr &&
1719 dwarf_lineno(line, &lineno) == 0) {
1720 tmp = dwarf_linesrc(line, NULL, NULL);
1721 if (tmp) {
1722 ppt->line = lineno;
1723 ppt->file = strdup(tmp);
1724 if (ppt->file == NULL) {
1725 ret = -ENOMEM;
1726 goto end;
1727 }
1728 found = true;
1729 }
1730 }
1731 }
1732 1752
1733 /* Find a corresponding function */1753 /* Find a corresponding function (name, baseline and baseaddr) */
1734 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {1754 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
1755 /* Get function entry information */
1735 tmp = dwarf_diename(&spdie);1756 tmp = dwarf_diename(&spdie);
1736 if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0)1757 if (!tmp ||
1737 goto end;1758 dwarf_entrypc(&spdie, &baseaddr) != 0 ||
1738 1759 dwarf_decl_line(&spdie, &baseline) != 0)
1739 if (ppt->line) {1760 goto post;
1740 if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,1761 func = tmp;
1741 &indie)) {1762
1742 /* addr in an inline function */1763 if (addr == (unsigned long)baseaddr)
1764 /* Function entry - Relative line number is 0 */
1765 lineno = baseline;
1766 else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
1767 &indie)) {
1768 if (dwarf_entrypc(&indie, &_addr) == 0 &&
1769 _addr == addr)
1770 /*
1771 * addr is at an inline function entry.
1772 * In this case, lineno should be the call-site
1773 * line number.
1774 */
1775 lineno = die_get_call_lineno(&indie);
1776 else {
1777 /*
1778 * addr is in an inline function body.
1779 * Since lineno points one of the lines
1780 * of the inline function, baseline should
1781 * be the entry line of the inline function.
1782 */
1743 tmp = dwarf_diename(&indie);1783 tmp = dwarf_diename(&indie);
1744 if (!tmp)1784 if (tmp &&
1745 goto end;1785 dwarf_decl_line(&spdie, &baseline) == 0)
1746 ret = dwarf_decl_line(&indie, &lineno);1786 func = tmp;
1747 } else {
1748 if (eaddr == addr) { /* Function entry */
1749 lineno = ppt->line;
1750 ret = 0;
1751 } else
1752 ret = dwarf_decl_line(&spdie, &lineno);
1753 }
1754 if (ret == 0) {
1755 /* Make a relative line number */
1756 ppt->line -= lineno;
1757 goto found;
1758 }1787 }
1759 }1788 }
1760 /* We don't have a line number, let's use offset */1789 }
1761 ppt->offset = addr - (unsigned long)eaddr;1790
1762found:1791post:
1763 ppt->function = strdup(tmp);1792 /* Make a relative line number or an offset */
1793 if (lineno)
1794 ppt->line = lineno - baseline;
1795 else if (func)
1796 ppt->offset = addr - (unsigned long)baseaddr;
1797
1798 /* Duplicate strings */
1799 if (func) {
1800 ppt->function = strdup(func);
1764 if (ppt->function == NULL) {1801 if (ppt->function == NULL) {
1765 ret = -ENOMEM;1802 ret = -ENOMEM;
1766 goto end;1803 goto end;
1767 }1804 }
1768 found = true;
1769 }1805 }
1770 1806 if (fname) {
1807 ppt->file = strdup(fname);
1808 if (ppt->file == NULL) {
1809 if (ppt->function) {
1810 free(ppt->function);
1811 ppt->function = NULL;
1812 }
1813 ret = -ENOMEM;
1814 goto end;
1815 }
1816 }
1771end:1817end:
1772 if (dwfl)1818 if (dwfl)
1773 dwfl_end(dwfl);1819 dwfl_end(dwfl);
1774 if (ret >= 0)1820 if (ret == 0 && (fname || func))
1775 ret = found ? 1 : 0;1821 ret = 1; /* Found a point */
1776 return ret;1822 return ret;
1777}1823}
1778 1824
@@ -1840,6 +1886,10 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) · 61 unmodified lines
1840 struct line_finder *lf = param->data;1886 struct line_finder *lf = param->data;
1841 struct line_range *lr = lf->lr;1887 struct line_range *lr = lf->lr;
1842 1888
1889 /* Check declared file */
1890 if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
1891 return DWARF_CB_OK;
1892
1843 if (dwarf_tag(sp_die) == DW_TAG_subprogram &&1893 if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
1844 die_compare_name(sp_die, lr->function)) {1894 die_compare_name(sp_die, lr->function)) {
1845 lf->fname = dwarf_decl_file(sp_die);1895 lf->fname = dwarf_decl_file(sp_die);
@@ -1892,6 +1942,7 @@ int find_line_range(int fd, struct line_range *lr) · 46 unmodified lines
1892 if (!dbg) {1942 if (!dbg) {
1893 pr_warning("No debug information found in the vmlinux - "1943 pr_warning("No debug information found in the vmlinux - "
1894 "please rebuild with CONFIG_DEBUG_INFO=y.\n");1944 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1945 close(fd); /* Without dwfl_end(), fd isn't closed. */
1895 return -EBADF;1946 return -EBADF;
1896 }1947 }
1897 1948

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t