perf/urgent fixes:
. The libaudit test was failing in some systems due to a unescaped newline, fix it so that the 'trace' tool can be built in such systems. . Fix installation of libexec components. . Add default handler for mmap2 events so that tools that don't explicitely define an MMAP2 handler don't crash, fix from David Ahern. . Fix to find line information for probe list, from Masami Hiramatsu. . Set child_pid after perf_evlist__prepare_workload(), fix from Namhyung Kim. . Fix infinite loop on invalid perf.data file, from Namhyung Kim. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSUwS+AAoJENZQFvNTUqpAib8P/0p5AXYrO+hBp9OOeFWleJYY Nj0o6BOOJU3CvJJP140S4/fEHZ42lSbzivR6ounF4+DCCYmX/R24So3iyFxE7EQ5 i9WXpsIv7kOHUkigSMPocBa7+bLnR7OFhDQ1KKiCpQKq6LArRdioc4GJ9NQ/ERev n26ArP1hzAM64vXI4xyT22AyuPmZiRFnmhUMwVIXiSLGezIWyPIzV6gdrEjwmPeA 2YFFTigFyfDC+w4/pLN/nOGKHY1kHiZo3LaFpTiqitgXSEqZJTugZJh1CPtZPMXU pASxjvs/WnA8l5hpC7xX1pCMAjOLqvQ84BprglfuA2KVJ2CzacrJSMWEmJ5rnDCm 48YdAf5n+90Hjtg5Nue3GIjJErAhRLl32bAy2Oegrmp9eQF+dNQH/oTTGKqoFg8Q QbMhqEUx4L6Dohw+8AfgM/NEmkL5V4va/vs0x3EDWJIdQOCl5woXqnvqvZ+eretb rYdpTn53oLiW/WlESmcU3XkUbVJ9hvjdYPG9z9PtmpPrmOH1XQo+5QVnyrhaAl8x 7e9IPAZDXm4WnY3zUJHjmz36kBm9Aqq0hotiNUzSMX1zkOf39P3SAKWGgPUDGVrh 2Sz4oZVwzzogDlaRUE2XXa24bNt04jgDI/7KFVuhCwvn9WhHUPrllFXpTy+xQHpn KzlbEvULc1pEFjFyBbiM =OgDk -----END PGP SIGNATURE----- Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent Pull perf/urgent fixes from Arnaldo Carvalho de Melo: * The libaudit test was failing in some systems due to a unescaped newline, fix it so that the 'trace' tool can be built in such systems. * Fix installation of libexec components. * Add default handler for mmap2 events so that tools that don't explicitely define an MMAP2 handler don't crash, fix from David Ahern. * Fix to find line information for probe list, from Masami Hiramatsu. * Set child_pid after perf_evlist__prepare_workload(), fix from Namhyung Kim. * Fix infinite loop on invalid perf.data file, from Namhyung Kim. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
1651d120ba
|
@ -770,6 +770,7 @@ check: $(OUTPUT)common-cmds.h
|
||||||
install-bin: all
|
install-bin: all
|
||||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
|
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||||
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
|
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||||
|
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
|
||||||
$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
|
$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
|
||||||
ifndef NO_LIBPERL
|
ifndef NO_LIBPERL
|
||||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
|
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
|
||||||
|
|
|
@ -457,6 +457,7 @@ static int __run_perf_stat(int argc, const char **argv)
|
||||||
perror("failed to prepare workload");
|
perror("failed to prepare workload");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
child_pid = evsel_list->workload.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group)
|
if (group)
|
||||||
|
|
|
@ -219,7 +219,7 @@ define SOURCE_LIBAUDIT
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
printf(\"error message: %s\n\", audit_errno_to_name(0));
|
printf(\"error message: %s\", audit_errno_to_name(0));
|
||||||
return audit_open();
|
return audit_open();
|
||||||
}
|
}
|
||||||
endef
|
endef
|
||||||
|
|
|
@ -426,7 +426,7 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
|
||||||
* @die_mem: a buffer for result DIE
|
* @die_mem: a buffer for result DIE
|
||||||
*
|
*
|
||||||
* Search a non-inlined function DIE which includes @addr. Stores the
|
* Search a non-inlined function DIE which includes @addr. Stores the
|
||||||
* DIE to @die_mem and returns it if found. Returns NULl if failed.
|
* DIE to @die_mem and returns it if found. Returns NULL if failed.
|
||||||
*/
|
*/
|
||||||
Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
||||||
Dwarf_Die *die_mem)
|
Dwarf_Die *die_mem)
|
||||||
|
@ -454,15 +454,32 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* die_find_inlinefunc - Search an inlined function at given address
|
* die_find_top_inlinefunc - Search the top inlined function at given address
|
||||||
* @cu_die: a CU DIE which including @addr
|
* @sp_die: a subprogram DIE which including @addr
|
||||||
* @addr: target address
|
* @addr: target address
|
||||||
* @die_mem: a buffer for result DIE
|
* @die_mem: a buffer for result DIE
|
||||||
*
|
*
|
||||||
* Search an inlined function DIE which includes @addr. Stores the
|
* Search an inlined function DIE which includes @addr. Stores the
|
||||||
* DIE to @die_mem and returns it if found. Returns NULl if failed.
|
* DIE to @die_mem and returns it if found. Returns NULL if failed.
|
||||||
|
* Even if several inlined functions are expanded recursively, this
|
||||||
|
* doesn't trace it down, and returns the topmost one.
|
||||||
|
*/
|
||||||
|
Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
||||||
|
Dwarf_Die *die_mem)
|
||||||
|
{
|
||||||
|
return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* die_find_inlinefunc - Search an inlined function at given address
|
||||||
|
* @sp_die: a subprogram DIE which including @addr
|
||||||
|
* @addr: target address
|
||||||
|
* @die_mem: a buffer for result DIE
|
||||||
|
*
|
||||||
|
* Search an inlined function DIE which includes @addr. Stores the
|
||||||
|
* DIE to @die_mem and returns it if found. Returns NULL if failed.
|
||||||
* If several inlined functions are expanded recursively, this trace
|
* If several inlined functions are expanded recursively, this trace
|
||||||
* it and returns deepest one.
|
* it down and returns deepest one.
|
||||||
*/
|
*/
|
||||||
Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
||||||
Dwarf_Die *die_mem)
|
Dwarf_Die *die_mem)
|
||||||
|
|
|
@ -79,7 +79,11 @@ extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
|
||||||
extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
||||||
Dwarf_Die *die_mem);
|
Dwarf_Die *die_mem);
|
||||||
|
|
||||||
/* Search an inlined function including given address */
|
/* Search the top inlined function including given address */
|
||||||
|
extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
||||||
|
Dwarf_Die *die_mem);
|
||||||
|
|
||||||
|
/* Search the deepest inlined function including given address */
|
||||||
extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
|
||||||
Dwarf_Die *die_mem);
|
Dwarf_Die *die_mem);
|
||||||
|
|
||||||
|
|
|
@ -2768,6 +2768,18 @@ int perf_session__read_header(struct perf_session *session)
|
||||||
if (perf_file_header__read(&f_header, header, fd) < 0)
|
if (perf_file_header__read(&f_header, header, fd) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sanity check that perf.data was written cleanly; data size is
|
||||||
|
* initialized to 0 and updated only if the on_exit function is run.
|
||||||
|
* If data size is still 0 then the file contains only partial
|
||||||
|
* information. Just warn user and process it as much as it can.
|
||||||
|
*/
|
||||||
|
if (f_header.data.size == 0) {
|
||||||
|
pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n"
|
||||||
|
"Was the 'perf record' command properly terminated?\n",
|
||||||
|
session->filename);
|
||||||
|
}
|
||||||
|
|
||||||
nr_attrs = f_header.attrs.size / f_header.attr_size;
|
nr_attrs = f_header.attrs.size / f_header.attr_size;
|
||||||
lseek(fd, f_header.attrs.offset, SEEK_SET);
|
lseek(fd, f_header.attrs.offset, SEEK_SET);
|
||||||
|
|
||||||
|
|
|
@ -1327,8 +1327,8 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
|
||||||
struct perf_probe_point *ppt)
|
struct perf_probe_point *ppt)
|
||||||
{
|
{
|
||||||
Dwarf_Die cudie, spdie, indie;
|
Dwarf_Die cudie, spdie, indie;
|
||||||
Dwarf_Addr _addr, baseaddr;
|
Dwarf_Addr _addr = 0, baseaddr = 0;
|
||||||
const char *fname = NULL, *func = NULL, *tmp;
|
const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
|
||||||
int baseline = 0, lineno = 0, ret = 0;
|
int baseline = 0, lineno = 0, ret = 0;
|
||||||
|
|
||||||
/* Adjust address with bias */
|
/* Adjust address with bias */
|
||||||
|
@ -1349,27 +1349,36 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
|
||||||
/* Find a corresponding function (name, baseline and baseaddr) */
|
/* Find a corresponding function (name, baseline and baseaddr) */
|
||||||
if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
|
if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
|
||||||
/* Get function entry information */
|
/* Get function entry information */
|
||||||
tmp = dwarf_diename(&spdie);
|
func = basefunc = dwarf_diename(&spdie);
|
||||||
if (!tmp ||
|
if (!func ||
|
||||||
dwarf_entrypc(&spdie, &baseaddr) != 0 ||
|
dwarf_entrypc(&spdie, &baseaddr) != 0 ||
|
||||||
dwarf_decl_line(&spdie, &baseline) != 0)
|
dwarf_decl_line(&spdie, &baseline) != 0) {
|
||||||
|
lineno = 0;
|
||||||
goto post;
|
goto post;
|
||||||
func = tmp;
|
}
|
||||||
|
|
||||||
if (addr == (unsigned long)baseaddr)
|
if (addr == (unsigned long)baseaddr) {
|
||||||
/* Function entry - Relative line number is 0 */
|
/* Function entry - Relative line number is 0 */
|
||||||
lineno = baseline;
|
lineno = baseline;
|
||||||
else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
|
fname = dwarf_decl_file(&spdie);
|
||||||
|
goto post;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track down the inline functions step by step */
|
||||||
|
while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
|
||||||
&indie)) {
|
&indie)) {
|
||||||
|
/* There is an inline function */
|
||||||
if (dwarf_entrypc(&indie, &_addr) == 0 &&
|
if (dwarf_entrypc(&indie, &_addr) == 0 &&
|
||||||
_addr == addr)
|
_addr == addr) {
|
||||||
/*
|
/*
|
||||||
* addr is at an inline function entry.
|
* addr is at an inline function entry.
|
||||||
* In this case, lineno should be the call-site
|
* In this case, lineno should be the call-site
|
||||||
* line number.
|
* line number. (overwrite lineinfo)
|
||||||
*/
|
*/
|
||||||
lineno = die_get_call_lineno(&indie);
|
lineno = die_get_call_lineno(&indie);
|
||||||
else {
|
fname = die_get_call_file(&indie);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* addr is in an inline function body.
|
* addr is in an inline function body.
|
||||||
* Since lineno points one of the lines
|
* Since lineno points one of the lines
|
||||||
|
@ -1377,19 +1386,27 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
|
||||||
* be the entry line of the inline function.
|
* be the entry line of the inline function.
|
||||||
*/
|
*/
|
||||||
tmp = dwarf_diename(&indie);
|
tmp = dwarf_diename(&indie);
|
||||||
if (tmp &&
|
if (!tmp ||
|
||||||
dwarf_decl_line(&spdie, &baseline) == 0)
|
dwarf_decl_line(&indie, &baseline) != 0)
|
||||||
|
break;
|
||||||
func = tmp;
|
func = tmp;
|
||||||
|
spdie = indie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Verify the lineno and baseline are in a same file */
|
||||||
|
tmp = dwarf_decl_file(&spdie);
|
||||||
|
if (!tmp || strcmp(tmp, fname) != 0)
|
||||||
|
lineno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
post:
|
post:
|
||||||
/* Make a relative line number or an offset */
|
/* Make a relative line number or an offset */
|
||||||
if (lineno)
|
if (lineno)
|
||||||
ppt->line = lineno - baseline;
|
ppt->line = lineno - baseline;
|
||||||
else if (func)
|
else if (basefunc) {
|
||||||
ppt->offset = addr - (unsigned long)baseaddr;
|
ppt->offset = addr - (unsigned long)baseaddr;
|
||||||
|
func = basefunc;
|
||||||
|
}
|
||||||
|
|
||||||
/* Duplicate strings */
|
/* Duplicate strings */
|
||||||
if (func) {
|
if (func) {
|
||||||
|
|
|
@ -256,6 +256,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
|
||||||
tool->sample = process_event_sample_stub;
|
tool->sample = process_event_sample_stub;
|
||||||
if (tool->mmap == NULL)
|
if (tool->mmap == NULL)
|
||||||
tool->mmap = process_event_stub;
|
tool->mmap = process_event_stub;
|
||||||
|
if (tool->mmap2 == NULL)
|
||||||
|
tool->mmap2 = process_event_stub;
|
||||||
if (tool->comm == NULL)
|
if (tool->comm == NULL)
|
||||||
tool->comm = process_event_stub;
|
tool->comm = process_event_stub;
|
||||||
if (tool->fork == NULL)
|
if (tool->fork == NULL)
|
||||||
|
@ -1310,7 +1312,7 @@ int __perf_session__process_events(struct perf_session *session,
|
||||||
file_offset = page_offset;
|
file_offset = page_offset;
|
||||||
head = data_offset - page_offset;
|
head = data_offset - page_offset;
|
||||||
|
|
||||||
if (data_offset + data_size < file_size)
|
if (data_size && (data_offset + data_size < file_size))
|
||||||
file_size = data_offset + data_size;
|
file_size = data_offset + data_size;
|
||||||
|
|
||||||
progress_next = file_size / 16;
|
progress_next = file_size / 16;
|
||||||
|
|
Loading…
Reference in New Issue