Unverified Commit 552667f6 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11206 kprobe support %pd/%pD type

Merge Pull Request from: @ci-robot 
 
PR sync from: Ye Bin <yebin10@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/S6DWQYKJPACUERN4BMHBFQVZAIA44577/ 
Masami Hiramatsu (Google) (1):
  selftests/ftrace: Fix required features for VFS type test case

Ye Bin (5):
  tracing/probes: support '%pd' type for print struct dentry's name
  tracing/probes: support '%pD' type for print struct file's name
  Documentation: tracing: add new type '%pd' and '%pD' for kprobe
  selftests/ftrace: add kprobe test cases for VFS type "%pd" and "%pD"
  selftests/ftrace: add fprobe test cases for VFS type "%pd" and "%pD"


-- 
2.34.1
 
https://gitee.com/openeuler/kernel/issues/IAMXDU 
 
Link:https://gitee.com/openeuler/kernel/pulls/11206

 

Reviewed-by: default avatarYe Weihua <yeweihua4@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents cadde4a9 22f5d986
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -58,7 +58,8 @@ Synopsis of kprobe_events
  NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
  FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
		  (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
		  (x8/x16/x32/x64), "char", "string", "ustring", "symbol", "symstr"
		  (x8/x16/x32/x64), VFS layer common type(%pd/%pD), "char",
		  "string", "ustring", "symbol", "symstr"
                  and bitfield are supported.

  (\*1) only for the probe on function entry (offs == 0).
@@ -109,6 +110,9 @@ With 'symstr' type, you can filter the event with wildcard pattern of the
symbols, and you don't need to solve symbol name by yourself.
For $comm, the default type is "string"; any other type is invalid.

VFS layer common type(%pd/%pD) is a special type, which fetches dentry's or
file's name from struct dentry's address or struct file's address.

.. _user_mem_access:

User Memory Access
+1 −1
Original line number Diff line number Diff line
@@ -5763,7 +5763,7 @@ static const char readme_msg[] =
	"\t           +|-[u]<offset>(<fetcharg>), \\imm-value, \\\"imm-string\"\n"
	"\t     type: s8/16/32/64, u8/16/32/64, x8/16/32/64, char, string, symbol,\n"
	"\t           b<bit-width>@<bit-offset>/<container-size>, ustring,\n"
	"\t           symstr, <type>\\[<array-size>\\]\n"
	"\t           symstr, %pd/%pD, <type>\\[<array-size>\\]\n"
#ifdef CONFIG_HIST_TRIGGERS
	"\t    field: <stype> <name>;\n"
	"\t    stype: u8/u16/u32/u64, s8/s16/s32/s64, pid_t,\n"
+6 −0
Original line number Diff line number Diff line
@@ -976,6 +976,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
	char gbuf[MAX_EVENT_NAME_LEN];
	char sbuf[KSYM_NAME_LEN];
	char abuf[MAX_BTF_ARGS_LEN];
	char *dbuf = NULL;
	bool is_tracepoint = false;
	struct tracepoint *tpoint = NULL;
	struct traceprobe_parse_context ctx = {
@@ -1086,6 +1087,10 @@ static int __trace_fprobe_create(int argc, const char *argv[])
		argv = new_argv;
	}

	ret = traceprobe_expand_dentry_args(argc, argv, &dbuf);
	if (ret)
		goto out;

	/* setup a probe */
	tf = alloc_trace_fprobe(group, event, symbol, tpoint, maxactive,
				argc, is_return);
@@ -1131,6 +1136,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
	trace_probe_log_clear();
	kfree(new_argv);
	kfree(symbol);
	kfree(dbuf);
	return ret;

parse_error:
+6 −0
Original line number Diff line number Diff line
@@ -779,6 +779,7 @@ static int __trace_kprobe_create(int argc, const char *argv[])
	char buf[MAX_EVENT_NAME_LEN];
	char gbuf[MAX_EVENT_NAME_LEN];
	char abuf[MAX_BTF_ARGS_LEN];
	char *dbuf = NULL;
	struct traceprobe_parse_context ctx = { .flags = TPARG_FL_KERNEL };

	switch (argv[0][0]) {
@@ -930,6 +931,10 @@ static int __trace_kprobe_create(int argc, const char *argv[])
		argv = new_argv;
	}

	ret = traceprobe_expand_dentry_args(argc, argv, &dbuf);
	if (ret)
		goto out;

	/* setup a probe */
	tk = alloc_trace_kprobe(group, event, addr, symbol, offset, maxactive,
				argc, is_return);
@@ -971,6 +976,7 @@ static int __trace_kprobe_create(int argc, const char *argv[])
	trace_probe_log_clear();
	kfree(new_argv);
	kfree(symbol);
	kfree(dbuf);
	return ret;

parse_error:
+63 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#define pr_fmt(fmt)	"trace_probe: " fmt

#include <linux/bpf.h>
#include <linux/fs.h>
#include "trace_btf.h"

#include "trace_probe.h"
@@ -1573,6 +1574,68 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
	return ERR_PTR(ret);
}

/* @buf: *buf must be equal to NULL. Caller must to free *buf */
int traceprobe_expand_dentry_args(int argc, const char *argv[], char **buf)
{
	int i, used, ret;
	const int bufsize = MAX_DENTRY_ARGS_LEN;
	char *tmpbuf = NULL;

	if (*buf)
		return -EINVAL;

	used = 0;
	for (i = 0; i < argc; i++) {
		char *tmp;
		char *equal;
		size_t arg_len;

		if (!glob_match("*:%p[dD]", argv[i]))
			continue;

		if (!tmpbuf) {
			tmpbuf = kmalloc(bufsize, GFP_KERNEL);
			if (!tmpbuf)
				return -ENOMEM;
		}

		tmp = kstrdup(argv[i], GFP_KERNEL);
		if (!tmp)
			goto nomem;

		equal = strchr(tmp, '=');
		if (equal)
			*equal = '\0';
		arg_len = strlen(argv[i]);
		tmp[arg_len - 4] = '\0';
		if (argv[i][arg_len - 1] == 'd')
			ret = snprintf(tmpbuf + used, bufsize - used,
				       "%s%s+0x0(+0x%zx(%s)):string",
				       equal ? tmp : "", equal ? "=" : "",
				       offsetof(struct dentry, d_name.name),
				       equal ? equal + 1 : tmp);
		else
			ret = snprintf(tmpbuf + used, bufsize - used,
				       "%s%s+0x0(+0x%zx(+0x%zx(%s))):string",
				       equal ? tmp : "", equal ? "=" : "",
				       offsetof(struct dentry, d_name.name),
				       offsetof(struct file, f_path.dentry),
				       equal ? equal + 1 : tmp);

		kfree(tmp);
		if (ret >= bufsize - used)
			goto nomem;
		argv[i] = tmpbuf + used;
		used += ret + 1;
	}

	*buf = tmpbuf;
	return 0;
nomem:
	kfree(tmpbuf);
	return -ENOMEM;
}

void traceprobe_finish_parse(struct traceprobe_parse_context *ctx)
{
	clear_btf_context(ctx);
Loading