Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add events to enumerate kernel symbols #21

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ ifneq ($(KERNELRELEASE),)
-o \( $(VERSION) -eq 3 -a $(PATCHLEVEL) -ge 15 \) ] ; then \
echo "lttng-tracepoint.o" ; fi;)

ifneq ($(CONFIG_KALLSYMS),)
obj-$(CONFIG_LTTNG) += lttng-kallsyms.o
endif

obj-$(CONFIG_LTTNG) += lttng-statedump.o
lttng-statedump-objs := lttng-statedump-impl.o wrapper/irqdesc.o \
wrapper/fdtable.o
Expand Down
51 changes: 51 additions & 0 deletions instrumentation/events/lttng-module/lttng-kallsyms.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM lttng_kallsyms

#if !defined(LTTNG_TRACE_LTTNG_KALLSYMS_H) || defined(TRACE_HEADER_MULTI_READ)
#define LTTNG_TRACE_LTTNG_KALLSYMS_H

#include <probes/lttng-tracepoint-event.h>

LTTNG_TRACEPOINT_EVENT(lttng_kallsyms_kernel_symbol,
tahini marked this conversation as resolved.
Show resolved Hide resolved

TP_PROTO(struct lttng_session *session,
unsigned long addr, const char *symbol, const char *module),

TP_ARGS(session, addr, symbol, module),

TP_FIELDS(
ctf_integer_hex(unsigned long, addr, addr)
ctf_string(symbol, symbol)
ctf_string(module, module)
)
)

LTTNG_TRACEPOINT_EVENT(lttng_kallsyms_new_module_symbol,

TP_PROTO(unsigned long addr, const char *symbol, const char *module),

TP_ARGS(addr, symbol, module),

TP_FIELDS(
ctf_integer_hex(unsigned long, addr, addr)
ctf_string(symbol, symbol)
ctf_string(module, module)
)
)

LTTNG_TRACEPOINT_EVENT(lttng_kallsyms_module_unloaded,

TP_PROTO(const char *module),

TP_ARGS(module),

TP_FIELDS(
ctf_string(module, module)
)
)

#endif /* LTTNG_TRACE_LTTNG_KALLSYMS_H */

/* This part must be outside protection */
#include <probes/define_trace.h>
163 changes: 163 additions & 0 deletions lttng-kallsyms.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
*
* lttng-kallsyms.c
*
* Copyright (C) 2019 Geneviève Bastien <[email protected]>
*/

#include <linux/module.h>
#include <linux/kallsyms.h>
#include <lttng-events.h>
#include <lttng-kallsyms.h>

/* Define the tracepoints, but do not build the probes */
#define CREATE_TRACE_POINTS
#define TRACE_INCLUDE_PATH instrumentation/events/lttng-module
#define TRACE_INCLUDE_FILE lttng-kallsyms
#define LTTNG_INSTRUMENTATION
#include <instrumentation/events/lttng-module/lttng-kallsyms.h>

DEFINE_TRACE(lttng_kallsyms_kernel_symbol);
DEFINE_TRACE(lttng_kallsyms_new_module_symbol);
DEFINE_TRACE(lttng_kallsyms_module_unloaded);

/*
* Trace the kernel symbols from a given module
*
* data: The lttng_session instance
* symbol_name: The function name this symbol resolves to
* module: The module containing this symbol. Can be NULL
* symbol_addr: The symbol address
*/
static
int _lttng_one_symbol_received(void * data, const char * symbol_name,
struct module * module, unsigned long symbol_addr)
{
struct lttng_session *session = data;

if (module) {
trace_lttng_kallsyms_kernel_symbol(session, symbol_addr,
symbol_name, module->name);
} else {
trace_lttng_kallsyms_kernel_symbol(session, symbol_addr,
symbol_name, "");
}

return 0;
}

int lttng_enumerate_kernel_symbols(struct lttng_session *session)
{
int ret = 0;

ret = kallsyms_on_each_symbol(_lttng_one_symbol_received, (void *) session);
tahini marked this conversation as resolved.
Show resolved Hide resolved

return ret;
}
EXPORT_SYMBOL_GPL(lttng_enumerate_kernel_symbols);

#ifdef CONFIG_MODULES

/*
* Trace the symbols coming from a specific module
*
* data: The new module for which we want the symbols
* symbol_name: The function name this symbol resolves to
* module: The module containing this symbol. Can be NULL
* symbol_addr: The symbol address
*/
static
int _lttng_trace_module_symbol(void * data, const char * symbol_name,
struct module * module, unsigned long symbol_addr)
{
struct module *mod = data;

// Trace the symbols from the new module
tahini marked this conversation as resolved.
Show resolved Hide resolved
if (mod == module) {
trace_lttng_kallsyms_new_module_symbol(symbol_addr, symbol_name, mod->name);
}
return 0;
}

static
int lttng_kallsyms_module_coming(struct module *mod)
{
int ret = 0;

ret = kallsyms_on_each_symbol(_lttng_trace_module_symbol, (void *) mod);
tahini marked this conversation as resolved.
Show resolved Hide resolved

return ret;
}

static
int lttng_kallsyms_module_going(struct module *mod)
{
trace_lttng_kallsyms_module_unloaded(mod->name);
return 0;
}

static
int lttng_kallsyms_module_notify(struct notifier_block *self,
unsigned long val, void *data)
{
struct module *mod = data;
int ret = 0;

switch (val) {
case MODULE_STATE_COMING:
ret = lttng_kallsyms_module_coming(mod);
break;
case MODULE_STATE_GOING:
ret = lttng_kallsyms_module_going(mod);
break;
default:
break;
}
return ret;
}

static
struct notifier_block lttng_kallsyms_module_notifier = {
.notifier_call = lttng_kallsyms_module_notify,
.priority = 0,
};

static
int lttng_kallsyms_module_init(void)
{
return register_module_notifier(&lttng_kallsyms_module_notifier);
}

static
void lttng_kallsyms_module_exit(void)
{
WARN_ON(unregister_module_notifier(&lttng_kallsyms_module_notifier));
}

#else /* #ifdef CONFIG_MODULES */

static
int lttng_kallsyms_module_init(void)
{
return 0;
}

static
void lttng_kallsyms_module_exit(void)
{

tahini marked this conversation as resolved.
Show resolved Hide resolved
}

#endif /* #else #ifdef CONFIG_MODULES */

module_init(lttng_kallsyms_module_init);

module_exit(lttng_kallsyms_module_exit);

MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Geneviève Bastien <[email protected]");
MODULE_DESCRIPTION("LTTng kallsyms");
MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
__stringify(LTTNG_MODULES_MINOR_VERSION) "."
__stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
LTTNG_MODULES_EXTRAVERSION);
26 changes: 26 additions & 0 deletions lttng-kallsyms.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
*
* lttng-kallsyms.h
*
* Copyright (C) 2019 Geneviève Bastien <[email protected]>
*/

#ifndef _LTTNG_KALLSYMS_H
#define _LTTNG_KALLSYMS_H

#include <lttng-events.h>

#ifdef CONFIG_KALLSYMS

int lttng_enumerate_kernel_symbols(struct lttng_session *session);

#else /* !CONFIG_KALLSYMS */

static inline int lttng_enumerate_kernel_symbols(struct lttng_session *session)
{
return 0;
}

#endif /* !CONFIG_KALLSYMS */

#endif /* _LTTNG_KALLSYMS_H */
4 changes: 4 additions & 0 deletions lttng-statedump-impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define TRACE_INCLUDE_FILE lttng-statedump
#define LTTNG_INSTRUMENTATION
#include <instrumentation/events/lttng-module/lttng-statedump.h>
#include <lttng-kallsyms.h>

DEFINE_TRACE(lttng_statedump_block_device);
DEFINE_TRACE(lttng_statedump_end);
Expand Down Expand Up @@ -510,6 +511,9 @@ int do_lttng_statedump(struct lttng_session *session)
return ret;
}
ret = lttng_enumerate_cpu_topology(session);
if (ret)
return ret;
ret = lttng_enumerate_kernel_symbols(session);
if (ret)
return ret;

Expand Down
8 changes: 8 additions & 0 deletions probes/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@ endif # CONFIG_VIDEO_V4L2

obj-$(CONFIG_LTTNG) += lttng-probe-workqueue.o

ifneq ($(CONFIG_KALLSYMS),)
obj-$(CONFIG_LTTNG) += lttng-probe-kallsyms.o
else
ifdef CONFIG_LOCALVERSION # Check if dot-config is included.
$(warning CONFIG_KALLSYMS is disabled, therefore probe "kallsyms" is disabled. Rebuild your kernel with this configuration option enabled in order to trace this subsystem.)
endif
endif # CONFIG_KALLSYMS

ifneq ($(CONFIG_KALLSYMS_ALL),)
obj-$(CONFIG_LTTNG) += lttng-probe-writeback.o
else
Expand Down
31 changes: 31 additions & 0 deletions probes/lttng-probe-kallsyms.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
*
* probes/lttng-probe-kallsyms.c
*
* LTTng kallsyms probes.
*
* Copyright (C) 2019 Geneviève Bastien <[email protected]>
*/

#include <linux/module.h>
#include <linux/kallsyms.h>
#include <lttng-events.h>
#include <lttng-tracer.h>

/*
* Create LTTng tracepoint probes.
*/
#define LTTNG_PACKAGE_BUILD
#define CREATE_TRACE_POINTS
#define TRACE_INCLUDE_PATH instrumentation/events/lttng-module
#define TRACE_INCLUDE_FILE lttng-kallsyms

#include <instrumentation/events/lttng-module/lttng-kallsyms.h>

MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Geneviève Bastien <[email protected]");
MODULE_DESCRIPTION("LTTng kallsyms probes");
MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
__stringify(LTTNG_MODULES_MINOR_VERSION) "."
__stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
LTTNG_MODULES_EXTRAVERSION);