Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools lib traceevent: Export dynamic symbols used by traceevent plugins

Traceevent plugins need dynamic symbols exported from libtraceevent.a,
otherwise a dlopen error will occur during plugins loading.

This patch uses dynamic-list-file to export dynamic symbols which will
be used in plugins to perf executable.

The problem is covered up if feature-libpython is enabled, because
PYTHON_EMBED_LDOPTS contains '-Xlinker --export-dynamic' which adds all
symbols to the dynamic symbol table. So we should reproduce the problem
by setting NO_LIBPYTHON=1.

Before this patch:

(Prepare plugins)
$ ls /root/.traceevent/plugins/
plugin_sched_switch.so
plugin_function.so
...

$ perf record -e 'ftrace:function' ls

$ perf script
Warning: could not load plugin '/mnt/data/root/.traceevent/plugins/plugin_sched_switch.so'
/root/.traceevent/plugins/plugin_sched_switch.so: undefined symbol: pevent_unregister_event_handler

Warning: could not load plugin '/root/.traceevent/plugins/plugin_function.so'
/root/.traceevent/plugins/plugin_function.so: undefined symbol: warning
...
:1049 1049 [000] 9666.754487: ftrace:function: ffffffff8118bc50 <-- ffffffff8118c5b3
:1049 1049 [000] 9666.754487: ftrace:function: ffffffff818e2440 <-- ffffffff8118bc75
:1049 1049 [000] 9666.754487: ftrace:function: ffffffff8106eee0 <-- ffffffff811212e2

After this patch:

$ perf record -e 'ftrace:function' ls
$ perf script
:1049 1049 [000] 9666.754487: ftrace:function: __set_task_comm
:1049 1049 [000] 9666.754487: ftrace:function: _raw_spin_lock
:1049 1049 [000] 9666.754487: ftrace:function: task_tgid_nr_ns
...

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1432819735-35040-1-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

He Kuang and committed by
Arnaldo Carvalho de Melo
e3d09ec8 f87027b9

+25 -3
+13 -1
tools/lib/traceevent/Makefile
··· 23 23 # Allow setting CC and AR, or setting CROSS_COMPILE as a prefix. 24 24 $(call allow-override,CC,$(CROSS_COMPILE)gcc) 25 25 $(call allow-override,AR,$(CROSS_COMPILE)ar) 26 + $(call allow-override,NM,$(CROSS_COMPILE)nm) 26 27 27 28 EXT = -std=gnu99 28 29 INSTALL = install ··· 158 157 159 158 TE_IN := $(OUTPUT)libtraceevent-in.o 160 159 LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) 160 + DYNAMIC_LIST_FILE := $(OUTPUT)libtraceevent-dynamic-list 161 161 162 - CMD_TARGETS = $(LIB_FILE) $(PLUGINS) 162 + CMD_TARGETS = $(LIB_FILE) $(PLUGINS) $(DYNAMIC_LIST_FILE) 163 163 164 164 TARGETS = $(CMD_TARGETS) 165 165 ··· 176 174 177 175 $(OUTPUT)libtraceevent.a: $(TE_IN) 178 176 $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ 177 + 178 + $(OUTPUT)libtraceevent-dynamic-list: $(PLUGINS) 179 + $(QUIET_GEN)$(call do_generate_dynamic_list_file, $(PLUGINS), $@) 179 180 180 181 plugins: $(PLUGINS) 181 182 ··· 247 242 for plugin in $1; do \ 248 243 $(call do_install,$$plugin,$(plugin_dir_SQ)); \ 249 244 done 245 + endef 246 + 247 + define do_generate_dynamic_list_file 248 + (echo '{'; \ 249 + $(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u; \ 250 + echo '};'; \ 251 + ) > $2 250 252 endef 251 253 252 254 install_lib: all_cmd install_plugins
+12 -2
tools/perf/Makefile.perf
··· 173 173 LIBTRACEEVENT = $(TE_PATH)libtraceevent.a 174 174 export LIBTRACEEVENT 175 175 176 + LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list 177 + LDFLAGS += -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) 178 + 176 179 LIBAPI = $(LIB_PATH)libapi.a 177 180 export LIBAPI 178 181 ··· 281 278 $(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE 282 279 $(Q)$(MAKE) $(build)=perf 283 280 284 - $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) 281 + $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) 285 282 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(PERF_IN) $(LIBS) -o $@ 286 283 287 284 $(GTK_IN): FORCE ··· 376 373 LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 377 374 378 375 $(LIBTRACEEVENT): FORCE 379 - $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a plugins 376 + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a 377 + 378 + libtraceevent_plugins: FORCE 379 + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins 380 + 381 + $(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins 382 + $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent-dynamic-list 380 383 381 384 $(LIBTRACEEVENT)-clean: 382 385 $(call QUIET_CLEAN, libtraceevent) ··· 564 555 .PHONY: all install clean config-clean strip install-gtk 565 556 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 566 557 .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE single_dep 558 + .PHONY: libtraceevent_plugins 567 559