Commit 1651d120 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-urgent-for-mingo' of...

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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents d8b11a0c b314e5cf
...@@ -770,6 +770,7 @@ check: $(OUTPUT)common-cmds.h ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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)
...@@ -453,16 +453,33 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) ...@@ -453,16 +453,33 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
return DIE_FIND_CB_CONTINUE; return DIE_FIND_CB_CONTINUE;
} }
/**
* die_find_top_inlinefunc - Search the top 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.
* 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 * die_find_inlinefunc - Search an 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.
* 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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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);
&indie)) { goto post;
}
/* Track down the inline functions step by step */
while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
&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, ...@@ -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)
func = tmp; break;
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) ...@@ -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, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment