Re: [PATCH v2 2/3] perf unwind: fix libunwind when tid != pid

2019-08-16 Thread Arnaldo Carvalho de Melo
Em Thu, Aug 15, 2019 at 04:10:35PM +0200, Jiri Olsa escreveu:
> On Thu, Aug 15, 2019 at 11:01:45AM +0100, John Keeping wrote:
> > Commit e5adfc3e7e77 ("perf map: Synthesize maps only for thread group
> > leader") changed the recording side so that we no longer get mmap events
> > for threads other than the thread group leader (when synthesising these
> > events for threads which exist before perf is started).
> > 
> > When a file recorded after this change is loaded, the lack of mmap
> > records mean that unwinding is not set up for any other threads.
> > 
> > This can be seen in a simple record/report scenario:
> > 
> > perf record --call-graph=dwarf -t $TID
> > perf report
> > 
> > If $TID is a process ID then the report will show call graphs, but if
> > $TID is a secondary thread the output is as if --call-graph=none was
> > specified.
> 
> great, mucch clearler now
> 
> > 
> > Following the rationale in that commit, move the libunwind fields into
> > struct map_groups and update the libunwind functions to take this
> > instead of the struct thread.  This is only required for
> > unwind__finish_access which must now be called from map_groups__delete
> > and the others are changed for symmetry.
> > 
> > Note that unwind__get_entries keeps the thread argument since it is
> > required for symbol lookup and the libdw unwind provider uses the thread
> > ID.
> > 
> > Fixes: e5adfc3e7e77 ("perf map: Synthesize maps only for thread group 
> > leader")
> 
> for all 3 patches
> 
> Reviewed-by: Jiri Olsa 


Thanks, applied.

- Arnaldo


Re: [PATCH v2 2/3] perf unwind: fix libunwind when tid != pid

2019-08-15 Thread Jiri Olsa
On Thu, Aug 15, 2019 at 11:01:45AM +0100, John Keeping wrote:
> Commit e5adfc3e7e77 ("perf map: Synthesize maps only for thread group
> leader") changed the recording side so that we no longer get mmap events
> for threads other than the thread group leader (when synthesising these
> events for threads which exist before perf is started).
> 
> When a file recorded after this change is loaded, the lack of mmap
> records mean that unwinding is not set up for any other threads.
> 
> This can be seen in a simple record/report scenario:
> 
>   perf record --call-graph=dwarf -t $TID
>   perf report
> 
> If $TID is a process ID then the report will show call graphs, but if
> $TID is a secondary thread the output is as if --call-graph=none was
> specified.

great, mucch clearler now

> 
> Following the rationale in that commit, move the libunwind fields into
> struct map_groups and update the libunwind functions to take this
> instead of the struct thread.  This is only required for
> unwind__finish_access which must now be called from map_groups__delete
> and the others are changed for symmetry.
> 
> Note that unwind__get_entries keeps the thread argument since it is
> required for symbol lookup and the libdw unwind provider uses the thread
> ID.
> 
> Fixes: e5adfc3e7e77 ("perf map: Synthesize maps only for thread group leader")

for all 3 patches

Reviewed-by: Jiri Olsa 

thanks,
jirka


[PATCH v2 2/3] perf unwind: fix libunwind when tid != pid

2019-08-15 Thread John Keeping
Commit e5adfc3e7e77 ("perf map: Synthesize maps only for thread group
leader") changed the recording side so that we no longer get mmap events
for threads other than the thread group leader (when synthesising these
events for threads which exist before perf is started).

When a file recorded after this change is loaded, the lack of mmap
records mean that unwinding is not set up for any other threads.

This can be seen in a simple record/report scenario:

perf record --call-graph=dwarf -t $TID
perf report

If $TID is a process ID then the report will show call graphs, but if
$TID is a secondary thread the output is as if --call-graph=none was
specified.

Following the rationale in that commit, move the libunwind fields into
struct map_groups and update the libunwind functions to take this
instead of the struct thread.  This is only required for
unwind__finish_access which must now be called from map_groups__delete
and the others are changed for symmetry.

Note that unwind__get_entries keeps the thread argument since it is
required for symbol lookup and the libdw unwind provider uses the thread
ID.

Fixes: e5adfc3e7e77 ("perf map: Synthesize maps only for thread group leader")
Cc: Konstantin Khlebnikov 
Signed-off-by: John Keeping 
---
v2:
- Remove unrelated change that has moved to the next patch
- Improve commit message to describe a scenario that shows the bug
---
 tools/perf/util/map.c|  3 ++-
 tools/perf/util/map_groups.h |  4 +++
 tools/perf/util/thread.c |  7 +++--
 tools/perf/util/thread.h |  4 ---
 tools/perf/util/unwind-libunwind-local.c | 18 ++---
 tools/perf/util/unwind-libunwind.c   | 34 
 tools/perf/util/unwind.h | 25 -
 7 files changed, 48 insertions(+), 47 deletions(-)

diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 44b556812e4b..27b7b102e4a2 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -647,6 +647,7 @@ struct map_groups *map_groups__new(struct machine *machine)
 void map_groups__delete(struct map_groups *mg)
 {
map_groups__exit(mg);
+   unwind__finish_access(mg);
free(mg);
 }
 
@@ -887,7 +888,7 @@ int map_groups__clone(struct thread *thread, struct 
map_groups *parent)
if (new == NULL)
goto out_unlock;
 
-   err = unwind__prepare_access(thread, new, NULL);
+   err = unwind__prepare_access(mg, new, NULL);
if (err)
goto out_unlock;
 
diff --git a/tools/perf/util/map_groups.h b/tools/perf/util/map_groups.h
index 5f25efa6d6bc..77252e14008f 100644
--- a/tools/perf/util/map_groups.h
+++ b/tools/perf/util/map_groups.h
@@ -31,6 +31,10 @@ struct map_groups {
struct maps  maps;
struct machine   *machine;
refcount_t   refcnt;
+#ifdef HAVE_LIBUNWIND_SUPPORT
+   void*addr_space;
+   struct unwind_libunwind_ops *unwind_libunwind_ops;
+#endif
 };
 
 #define KMAP_NAME_LEN 256
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 590793cc5142..bbf7816cba31 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -105,7 +105,6 @@ void thread__delete(struct thread *thread)
}
up_write(&thread->comm_lock);
 
-   unwind__finish_access(thread);
nsinfo__zput(thread->nsinfo);
srccode_state_free(&thread->srccode_state);
 
@@ -252,7 +251,7 @@ static int thread__set_comm(struct thread *thread, 
const char *str,
list_add(&new->list, &thread->comm_list);
 
if (exec)
-   unwind__flush_access(thread);
+   unwind__flush_access(thread->mg);
}
 
thread->comm_set = true;
@@ -332,7 +331,7 @@ int thread__insert_map(struct thread *thread, struct map 
*map)
 {
int ret;
 
-   ret = unwind__prepare_access(thread, map, NULL);
+   ret = unwind__prepare_access(thread->mg, map, NULL);
if (ret)
return ret;
 
@@ -352,7 +351,7 @@ static int __thread__prepare_access(struct thread *thread)
down_read(&maps->lock);
 
for (map = maps__first(maps); map; map = map__next(map)) {
-   err = unwind__prepare_access(thread, map, &initialized);
+   err = unwind__prepare_access(thread->mg, map, &initialized);
if (err || initialized)
break;
}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index e97ef6977eb9..bf06113be4f3 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -44,10 +44,6 @@ struct thread {
struct thread_stack *ts;
struct nsinfo   *nsinfo;
struct srccode_statesrccode_state;
-#ifdef HAVE_LIBUNWIND_SUPPORT
-   void*addr_space;
-   struct unwind_libunwind_ops *unwind_libu