2013-08-06 05:14:45

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH/RFC 0/4] perf ui/gtk: Separate out GTK code to a shared object (v2)

Hi,

This is v2 of gtk code separation patchset to reduce library
dependencies of the perf executable.

I only built libperf-gtk.so with -fPIC, and it's not linked to libperf
at build time. All unresolved symbols used for perf should be
resolved at runtime via perf executable (so libperf.a) - I didn't know
that the linker permits unresolved symbols in a shared library at
build time.

Tested on my x86-64 machine only. It seems work well for me.

The patch 1 is a bug fix and can be applied independently.

You can find it on my 'perf/separate-v2' branch in my tree at:

git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git


Any comments are welcome, thanks
Namhyung


Cc: Pekka Enberg <[email protected]>
Cc: Andi Kleen <[email protected]>

Namhyung Kim (4):
perf ui/gtk: Fix segmentation fault on perf_hpp__for_each_format loop
perf tools: Separate out GTK codes to libperf-gtk.so
perf tools: Setup GTK browser dynamically
perf tools: Run dynamic loaded GTK browser

tools/perf/Makefile | 39 +++++++++++++++++++++++----------
tools/perf/builtin-annotate.c | 26 +++++++++++++++++++---
tools/perf/builtin-report.c | 16 ++++++++++++--
tools/perf/config/Makefile | 12 +++++++---
tools/perf/ui/gtk/annotate.c | 13 ++++++++---
tools/perf/ui/gtk/gtk.h | 16 ++++++++++++++
tools/perf/ui/gtk/hists.c | 2 --
tools/perf/ui/setup.c | 51 +++++++++++++++++++++++++++++++++++++++++--
tools/perf/ui/ui.h | 12 +---------
tools/perf/util/annotate.h | 24 --------------------
tools/perf/util/hist.h | 15 -------------
11 files changed, 150 insertions(+), 76 deletions(-)

--
1.7.11.7


2013-08-06 05:14:47

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 1/4] perf ui/gtk: Fix segmentation fault on perf_hpp__for_each_format loop

From: Namhyung Kim <[email protected]>

The commit 2b8bfa6bb8a7 ("perf tools: Centralize default columns init
in perf_hpp__init") moves initialization of common overhead column to
perf_hpp__init() but forgot about the gtk code.

So the gtk code added the same column to the list twice causing
infinite loop when iterating it by perf_hpp__for_each_format loop.
When I run perf report --gtk, I can see following messages
indefinitely.

(perf:11687): Gtk-CRITICAL **: IA__gtk_main_quit: assertion 'main_loops != NULL' failed
perf: Segmentation fault

Cc: Jiri Olsa <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: Andi Kleen <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/ui/gtk/hists.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index cb2ed1980147..2ca66cc1160f 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -109,8 +109,6 @@ __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us)

void perf_gtk__init_hpp(void)
{
- perf_hpp__column_enable(PERF_HPP__OVERHEAD);
-
perf_hpp__init();

perf_hpp__format[PERF_HPP__OVERHEAD].color =
--
1.7.11.7

2013-08-06 05:15:26

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 3/4] perf tools: Setup GTK browser dynamically

Call setup/exit GTK browser function using libdl.

Cc: Andi Kleen <[email protected]>
Cc: Pekka Enberg <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/ui/gtk/gtk.h | 3 +++
tools/perf/ui/setup.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++--
tools/perf/ui/ui.h | 12 +-----------
3 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h
index 3d96785ef155..09b7a062fd48 100644
--- a/tools/perf/ui/gtk/gtk.h
+++ b/tools/perf/ui/gtk/gtk.h
@@ -20,6 +20,9 @@ struct perf_gtk_context {
guint statbar_ctx_id;
};

+int perf_gtk__init(void);
+void perf_gtk__exit(bool wait_for_ok);
+
extern struct perf_gtk_context *pgctx;

static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx)
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index 47d9a571f261..51a7f7357371 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -1,4 +1,5 @@
#include <pthread.h>
+#include <dlfcn.h>

#include "../util/cache.h"
#include "../util/debug.h"
@@ -6,6 +7,52 @@

pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;

+#ifdef GTK2_SUPPORT
+void *perf_gtk_handle;
+
+static int setup_gtk_browser(void)
+{
+ int (*perf_ui_init)(void);
+
+ perf_gtk_handle = dlopen("libperf-gtk.so", RTLD_LAZY);
+ if (perf_gtk_handle == NULL)
+ return -1;
+
+ perf_ui_init = dlsym(perf_gtk_handle, "perf_gtk__init");
+ if (perf_ui_init == NULL)
+ goto out_close;
+
+ if (perf_ui_init() == 0)
+ return 0;
+
+out_close:
+ dlclose(perf_gtk_handle);
+ return -1;
+}
+
+static void exit_gtk_browser(bool wait_for_ok)
+{
+ void (*perf_ui_exit)(bool);
+
+ if (perf_gtk_handle == NULL)
+ return;
+
+ perf_ui_exit = dlsym(perf_gtk_handle, "perf_gtk__exit");
+ if (perf_ui_exit == NULL)
+ goto out_close;
+
+ perf_ui_exit(wait_for_ok);
+
+out_close:
+ dlclose(perf_gtk_handle);
+
+ perf_gtk_handle = NULL;
+}
+#else
+static inline int setup_gtk_browser(void) { return -1; }
+static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {}
+#endif
+
void setup_browser(bool fallback_to_pager)
{
if (use_browser < 2 && (!isatty(1) || dump_trace))
@@ -17,7 +64,7 @@ void setup_browser(bool fallback_to_pager)

switch (use_browser) {
case 2:
- if (perf_gtk__init() == 0)
+ if (setup_gtk_browser() == 0)
break;
/* fall through */
case 1:
@@ -39,7 +86,7 @@ void exit_browser(bool wait_for_ok)
{
switch (use_browser) {
case 2:
- perf_gtk__exit(wait_for_ok);
+ exit_gtk_browser(wait_for_ok);
break;

case 1:
diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h
index 70cb0d4eb8aa..4f7cbe6a2608 100644
--- a/tools/perf/ui/ui.h
+++ b/tools/perf/ui/ui.h
@@ -6,6 +6,7 @@
#include <linux/compiler.h>

extern pthread_mutex_t ui__lock;
+extern void *perf_gtk_handle;

extern int use_browser;

@@ -23,17 +24,6 @@ static inline int ui__init(void)
static inline void ui__exit(bool wait_for_ok __maybe_unused) {}
#endif

-#ifdef GTK2_SUPPORT
-int perf_gtk__init(void);
-void perf_gtk__exit(bool wait_for_ok);
-#else
-static inline int perf_gtk__init(void)
-{
- return -1;
-}
-static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {}
-#endif
-
void ui__refresh_dimensions(bool force);

#endif /* _PERF_UI_H_ */
--
1.7.11.7

2013-08-06 05:15:23

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 2/4] perf tools: Separate out GTK codes to libperf-gtk.so

Separate out GTK codes to a shared object called libperf-gtk.so. This
time only GTK codes are built with -fPIC and libperf remains as is.

Cc: Andi Kleen <[email protected]>
Cc: Pekka Enberg <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/Makefile | 39 ++++++++++++++++++++++++++++-----------
tools/perf/config/Makefile | 14 ++++++++++----
2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index bfd12d02a304..17f0509e0eb0 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -113,6 +113,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
BUILTIN_OBJS =
LIB_H =
LIB_OBJS =
+GTK_OBJS =
PYRF_OBJS =
SCRIPT_SH =

@@ -484,13 +485,19 @@ ifndef NO_SLANG
endif

ifndef NO_GTK2
- LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
- LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
- LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
- LIB_OBJS += $(OUTPUT)ui/gtk/util.o
- LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
- LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
- LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
+ ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so
+
+ GTK_OBJS += $(OUTPUT)ui/gtk/browser.o
+ GTK_OBJS += $(OUTPUT)ui/gtk/hists.o
+ GTK_OBJS += $(OUTPUT)ui/gtk/setup.o
+ GTK_OBJS += $(OUTPUT)ui/gtk/util.o
+ GTK_OBJS += $(OUTPUT)ui/gtk/helpline.o
+ GTK_OBJS += $(OUTPUT)ui/gtk/progress.o
+ GTK_OBJS += $(OUTPUT)ui/gtk/annotate.o
+
+install-gtk: $(OUTPUT)libperf-gtk.so
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'
+ $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)'
endif

ifndef NO_LIBPERL
@@ -544,6 +551,12 @@ $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
$(BUILTIN_OBJS) $(LIBS) -o $@

+$(GTK_OBJS): %.o: %.c $(LIB_H)
+ $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $<
+
+$(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS)
+ $(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS)
+
$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \
@@ -762,7 +775,9 @@ check: $(OUTPUT)common-cmds.h

### Installation rules

-install-bin: all
+install-gtk:
+
+install-bin: all install-gtk
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
@@ -795,15 +810,17 @@ $(INSTALL_DOC_TARGETS):
### Cleaning rules

clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean
- $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
+ $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(GTK_OBJS)
+ $(RM) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
$(RM) $(ALL_PROGRAMS) perf
- $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
+ $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo
+ $(RM) $(OUTPUT)common-cmds.h TAGS tags cscope*
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
$(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
$(RM) $(OUTPUT)util/*-bison*
$(RM) $(OUTPUT)util/*-flex*
$(python-clean)

-.PHONY: all install clean strip $(LIBTRACEEVENT) $(LIBLK)
+.PHONY: all install clean strip $(LIBTRACEEVENT) $(LIBLK) install-gtk
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
.PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 214e17e97e5c..6bdfd0302c4e 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -267,11 +267,11 @@ ifndef NO_GTK2
NO_GTK2 := 1
else
ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
- CFLAGS += -DHAVE_GTK_INFO_BAR
+ GTK_CFLAGS := -DHAVE_GTK_INFO_BAR
endif
- CFLAGS += -DGTK2_SUPPORT
- CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
- EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+ GTK_CFLAGS += -DGTK2_SUPPORT
+ GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
+ GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
endif
endif

@@ -456,7 +456,12 @@ else
sysconfdir = $(prefix)/etc
ETC_PERFCONFIG = etc/perfconfig
endif
+ifeq ($(IS_X86_64),1)
+lib = lib64
+else
lib = lib
+endif
+libdir = $(prefix)/$(lib)

# Shell quote (do not use $(call) to accommodate ancient setups);
ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
@@ -469,6 +474,7 @@ template_dir_SQ = $(subst ','\'',$(template_dir))
htmldir_SQ = $(subst ','\'',$(htmldir))
prefix_SQ = $(subst ','\'',$(prefix))
sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
+libdir_SQ = $(subst ','\'',$(libdir))

ifneq ($(filter /%,$(firstword $(perfexecdir))),)
perfexec_instdir = $(perfexecdir)
--
1.7.11.7

2013-08-06 05:15:21

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 4/4] perf tools: Run dynamic loaded GTK browser

Run GTK hist and annotation browser using libdl.

Cc: Andi Kleen <[email protected]>
Cc: Pekka Enberg <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/builtin-annotate.c | 26 +++++++++++++++++++++++---
tools/perf/builtin-report.c | 16 ++++++++++++++--
tools/perf/config/Makefile | 2 +-
tools/perf/ui/gtk/annotate.c | 13 ++++++++++---
tools/perf/ui/gtk/gtk.h | 13 +++++++++++++
tools/perf/util/annotate.h | 24 ------------------------
tools/perf/util/hist.h | 15 ---------------
7 files changed, 61 insertions(+), 48 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index db491e9a812b..82469b3ead07 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -30,6 +30,7 @@
#include "util/tool.h"
#include "arch/common.h"

+#include <dlfcn.h>
#include <linux/bitmap.h>

struct perf_annotate {
@@ -143,8 +144,18 @@ find_next:

if (use_browser == 2) {
int ret;
+ int (*annotate)(struct hist_entry *he,
+ struct perf_evsel *evsel,
+ struct hist_browser_timer *hbt);
+
+ annotate = dlsym(perf_gtk_handle,
+ "hist_entry__gtk_annotate");
+ if (annotate == NULL) {
+ ui__error("GTK browser not found!\n");
+ return;
+ }

- ret = hist_entry__gtk_annotate(he, evsel, NULL);
+ ret = annotate(he, evsel, NULL);
if (!ret || !ann->skip_missing)
return;

@@ -246,8 +257,17 @@ static int __cmd_annotate(struct perf_annotate *ann)
goto out_delete;
}

- if (use_browser == 2)
- perf_gtk__show_annotations();
+ if (use_browser == 2) {
+ void (*show_annotations)(void);
+
+ show_annotations = dlsym(perf_gtk_handle,
+ "perf_gtk__show_annotations");
+ if (show_annotations == NULL) {
+ ui__error("GTK browser not found!\n");
+ goto out_delete;
+ }
+ show_annotations();
+ }

out_delete:
/*
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index d785d89ed226..05c0e80c8ae4 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -35,6 +35,7 @@
#include "util/hist.h"
#include "arch/common.h"

+#include <dlfcn.h>
#include <linux/bitmap.h>

struct perf_report {
@@ -592,8 +593,19 @@ static int __cmd_report(struct perf_report *rep)
ret = 0;

} else if (use_browser == 2) {
- perf_evlist__gtk_browse_hists(session->evlist, help,
- NULL, rep->min_percent);
+ int (*hist_browser)(struct perf_evlist *,
+ const char *,
+ struct hist_browser_timer *,
+ float min_pcnt);
+
+ hist_browser = dlsym(perf_gtk_handle,
+ "perf_evlist__gtk_browse_hists");
+ if (hist_browser == NULL) {
+ ui__error("GTK browser not found!\n");
+ return ret;
+ }
+ hist_browser(session->evlist, help, NULL,
+ rep->min_percent);
}
} else
perf_evlist__tty_browse_hists(session->evlist, rep, help);
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 6bdfd0302c4e..1b6ccb242609 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -269,7 +269,7 @@ ifndef NO_GTK2
ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
GTK_CFLAGS := -DHAVE_GTK_INFO_BAR
endif
- GTK_CFLAGS += -DGTK2_SUPPORT
+ CFLAGS += -DGTK2_SUPPORT
GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
endif
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
index f538794615db..9c7ff8d31b27 100644
--- a/tools/perf/ui/gtk/annotate.c
+++ b/tools/perf/ui/gtk/annotate.c
@@ -154,9 +154,9 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
return 0;
}

-int symbol__gtk_annotate(struct symbol *sym, struct map *map,
- struct perf_evsel *evsel,
- struct hist_browser_timer *hbt)
+static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
+ struct perf_evsel *evsel,
+ struct hist_browser_timer *hbt)
{
GtkWidget *window;
GtkWidget *notebook;
@@ -226,6 +226,13 @@ int symbol__gtk_annotate(struct symbol *sym, struct map *map,
return 0;
}

+int hist_entry__gtk_annotate(struct hist_entry *he,
+ struct perf_evsel *evsel,
+ struct hist_browser_timer *hbt)
+{
+ return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
+}
+
void perf_gtk__show_annotations(void)
{
GtkWidget *window;
diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h
index 09b7a062fd48..62922d284bca 100644
--- a/tools/perf/ui/gtk/gtk.h
+++ b/tools/perf/ui/gtk/gtk.h
@@ -51,4 +51,17 @@ static inline GtkWidget *perf_gtk__setup_info_bar(void)
}
#endif

+struct perf_evsel;
+struct perf_evlist;
+struct hist_entry;
+struct hist_browser_timer;
+
+int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
+ struct hist_browser_timer *hbt,
+ float min_pcnt);
+int hist_entry__gtk_annotate(struct hist_entry *he,
+ struct perf_evsel *evsel,
+ struct hist_browser_timer *hbt);
+void perf_gtk__show_annotations(void);
+
#endif /* _PERF_GTK_H_ */
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index af755156d278..31b898312c3f 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -165,30 +165,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
}
#endif

-#ifdef GTK2_SUPPORT
-int symbol__gtk_annotate(struct symbol *sym, struct map *map,
- struct perf_evsel *evsel,
- struct hist_browser_timer *hbt);
-
-static inline int hist_entry__gtk_annotate(struct hist_entry *he,
- struct perf_evsel *evsel,
- struct hist_browser_timer *hbt)
-{
- return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
-}
-
-void perf_gtk__show_annotations(void);
-#else
-static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
- struct perf_evsel *evsel __maybe_unused,
- struct hist_browser_timer *hbt __maybe_unused)
-{
- return 0;
-}
-
-static inline void perf_gtk__show_annotations(void) {}
-#endif
-
extern const char *disassembler_style;

#endif /* __PERF_ANNOTATE_H */
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 1329b6b6ffe6..7f29792efc58 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -224,20 +224,5 @@ static inline int script_browse(const char *script_opt __maybe_unused)
#define K_SWITCH_INPUT_DATA -3000
#endif

-#ifdef GTK2_SUPPORT
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
- struct hist_browser_timer *hbt __maybe_unused,
- float min_pcnt);
-#else
-static inline
-int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
- const char *help __maybe_unused,
- struct hist_browser_timer *hbt __maybe_unused,
- float min_pcnt __maybe_unused)
-{
- return 0;
-}
-#endif
-
unsigned int hists__sort_list_width(struct hists *self);
#endif /* __PERF_HIST_H */
--
1.7.11.7

2013-08-06 05:56:28

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH 1/4] perf ui/gtk: Fix segmentation fault on perf_hpp__for_each_format loop

On Tue, Aug 6, 2013 at 8:14 AM, Namhyung Kim <[email protected]> wrote:
> From: Namhyung Kim <[email protected]>
>
> The commit 2b8bfa6bb8a7 ("perf tools: Centralize default columns init
> in perf_hpp__init") moves initialization of common overhead column to
> perf_hpp__init() but forgot about the gtk code.
>
> So the gtk code added the same column to the list twice causing
> infinite loop when iterating it by perf_hpp__for_each_format loop.
> When I run perf report --gtk, I can see following messages
> indefinitely.
>
> (perf:11687): Gtk-CRITICAL **: IA__gtk_main_quit: assertion 'main_loops != NULL' failed
> perf: Segmentation fault
>
> Cc: Jiri Olsa <[email protected]>
> Cc: Pekka Enberg <[email protected]>
> Cc: Andi Kleen <[email protected]>
> Signed-off-by: Namhyung Kim <[email protected]>

Reviewed-by: Pekka Enberg <[email protected]>

2013-08-06 05:57:03

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH 2/4] perf tools: Separate out GTK codes to libperf-gtk.so

On Tue, Aug 6, 2013 at 8:14 AM, Namhyung Kim <[email protected]> wrote:
> Separate out GTK codes to a shared object called libperf-gtk.so. This
> time only GTK codes are built with -fPIC and libperf remains as is.
>
> Cc: Andi Kleen <[email protected]>
> Cc: Pekka Enberg <[email protected]>
> Signed-off-by: Namhyung Kim <[email protected]>

Reviewed-by: Pekka Enberg <[email protected]>

2013-08-06 05:57:33

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH 3/4] perf tools: Setup GTK browser dynamically

On Tue, Aug 6, 2013 at 8:14 AM, Namhyung Kim <[email protected]> wrote:
> Call setup/exit GTK browser function using libdl.
>
> Cc: Andi Kleen <[email protected]>
> Cc: Pekka Enberg <[email protected]>
> Signed-off-by: Namhyung Kim <[email protected]>

Reviewed-by: Pekka Enberg <[email protected]>

2013-08-06 05:58:18

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH 4/4] perf tools: Run dynamic loaded GTK browser

On Tue, Aug 6, 2013 at 8:14 AM, Namhyung Kim <[email protected]> wrote:
> Run GTK hist and annotation browser using libdl.
>
> Cc: Andi Kleen <[email protected]>
> Cc: Pekka Enberg <[email protected]>
> Signed-off-by: Namhyung Kim <[email protected]>

Reviewed-by: Pekka Enberg <[email protected]>

2013-08-07 20:09:26

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH/RFC 0/4] perf ui/gtk: Separate out GTK code to a shared object (v2)

Em Tue, Aug 06, 2013 at 02:14:12PM +0900, Namhyung Kim escreveu:
> Hi,
>
> This is v2 of gtk code separation patchset to reduce library
> dependencies of the perf executable.
>
> I only built libperf-gtk.so with -fPIC, and it's not linked to libperf
> at build time. All unresolved symbols used for perf should be
> resolved at runtime via perf executable (so libperf.a) - I didn't know
> that the linker permits unresolved symbols in a shared library at
> build time.
>
> Tested on my x86-64 machine only. It seems work well for me.

Not for me, please take a look at O= handling:

[acme@sandy linux]$ make -j8 O=/tmp/build/perf -C tools/perf/ install
<SNIP>
CHK gtk2
CHK -DHAVE_GTK_INFO_BAR
<SNIP>
make: Entering directory `/home/acme/git/linux/tools/perf'
make: *** No rule to make target `/tmp/build/perf/ui/gtk/browser.c',
needed by `/tmp/build/perf/ui/gtk/browser.o'. Stop.
make: *** Waiting for unfinished jobs....
make[1]: Entering directory `/home/acme/git/linux/tools/lib/traceevent'
make[2]: warning: jobserver unavailable: using -j1. Add `+' to parent
make rule.
make[1]: Entering directory `/home/acme/git/linux/tools/lib/lk'
AR liblk.a
make[1]: Leaving directory `/home/acme/git/linux/tools/lib/traceevent'
make[1]: Leaving directory `/home/acme/git/linux/tools/lib/lk'
make: Leaving directory `/home/acme/git/linux/tools/perf'
[acme@sandy linux]$

> The patch 1 is a bug fix and can be applied independently.

I took it, thanks.

Subject: [tip:perf/core] perf ui/gtk: Fix segmentation fault on perf_hpp__for_each_format loop

Commit-ID: d50bf78ff69297d3f60aa778c272acc8e5f59a19
Gitweb: http://git.kernel.org/tip/d50bf78ff69297d3f60aa778c272acc8e5f59a19
Author: Namhyung Kim <[email protected]>
AuthorDate: Tue, 6 Aug 2013 14:14:13 +0900
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Wed, 7 Aug 2013 17:35:39 -0300

perf ui/gtk: Fix segmentation fault on perf_hpp__for_each_format loop

The commit 2b8bfa6bb8a7 ("perf tools: Centralize default columns init in
perf_hpp__init") moves initialization of common overhead column to
perf_hpp__init() but forgot about the gtk code.

So the gtk code added the same column to the list twice causing infinite
loop when iterating it by perf_hpp__for_each_format loop. When I run
perf report --gtk, I can see following messages indefinitely.

(perf:11687): Gtk-CRITICAL **: IA__gtk_main_quit: assertion 'main_loops != NULL' failed
perf: Segmentation fault

Signed-off-by: Namhyung Kim <[email protected]>
Reviewed-by: Pekka Enberg <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/ui/gtk/hists.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index cb2ed198..2ca66cc 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -109,8 +109,6 @@ __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us)

void perf_gtk__init_hpp(void)
{
- perf_hpp__column_enable(PERF_HPP__OVERHEAD);
-
perf_hpp__init();

perf_hpp__format[PERF_HPP__OVERHEAD].color =