Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99fec39e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull kprobe fixes from Steven Rostedt:
 "The documentation for kprobe events says that symbol offets can take
  both a + and - sign to get to befor and after the symbol address.

  But in actuality, the code does not support the minus. This fixes that
  issue, and adds a few more selftests to kprobe events"

* tag 'trace-v4.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  selftests: ftrace: Add a testcase for probepoint
  selftests: ftrace: Add a testcase for string type with kprobe_event
  selftests: ftrace: Add probe event argument syntax testcase
  tracing: probeevent: Fix to support minus offset from symbol
parents 86d043d4 dfa453bc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -659,7 +659,7 @@ static int create_trace_kprobe(int argc, char **argv)
	char *symbol = NULL, *event = NULL, *group = NULL;
	int maxactive = 0;
	char *arg;
	unsigned long offset = 0;
	long offset = 0;
	void *addr = NULL;
	char buf[MAX_EVENT_NAME_LEN];

@@ -747,7 +747,7 @@ static int create_trace_kprobe(int argc, char **argv)
		symbol = argv[1];
		/* TODO: support .init module functions */
		ret = traceprobe_split_symbol_offset(symbol, &offset);
		if (ret) {
		if (ret || offset < 0 || offset > UINT_MAX) {
			pr_info("Failed to parse either an address or a symbol.\n");
			return ret;
		}
+3 −5
Original line number Diff line number Diff line
@@ -320,7 +320,7 @@ static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
}

/* Split symbol and offset. */
int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
int traceprobe_split_symbol_offset(char *symbol, long *offset)
{
	char *tmp;
	int ret;
@@ -328,13 +328,11 @@ int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
	if (!offset)
		return -EINVAL;

	tmp = strchr(symbol, '+');
	tmp = strpbrk(symbol, "+-");
	if (tmp) {
		/* skip sign because kstrtoul doesn't accept '+' */
		ret = kstrtoul(tmp + 1, 0, offset);
		ret = kstrtol(tmp, 0, offset);
		if (ret)
			return ret;

		*tmp = '\0';
	} else
		*offset = 0;
+1 −1
Original line number Diff line number Diff line
@@ -365,7 +365,7 @@ extern int traceprobe_conflict_field_name(const char *name,
extern void traceprobe_update_arg(struct probe_arg *arg);
extern void traceprobe_free_probe_arg(struct probe_arg *arg);

extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset);
extern int traceprobe_split_symbol_offset(char *symbol, long *offset);

/* Sum up total data length for dynamic arraies (strings) */
static nokprobe_inline int
+46 −0
Original line number Diff line number Diff line
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Kprobe event string type argument

[ -f kprobe_events ] || exit_unsupported # this is configurable

echo 0 > events/enable
echo > kprobe_events

case `uname -m` in
x86_64)
  ARG2=%si
  OFFS=8
;;
i[3456]86)
  ARG2=%cx
  OFFS=4
;;
aarch64)
  ARG2=%x1
  OFFS=8
;;
arm*)
  ARG2=%r1
  OFFS=4
;;
*)
  echo "Please implement other architecture here"
  exit_untested
esac

: "Test get argument (1)"
echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string" > kprobe_events
echo 1 > events/kprobes/testprobe/enable
! echo test >> kprobe_events
tail -n 1 trace | grep -qe "testprobe.* arg1=\"test\""

echo 0 > events/kprobes/testprobe/enable
: "Test get argument (2)"
echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string arg2=+0(+${OFFS}(${ARG2})):string" > kprobe_events
echo 1 > events/kprobes/testprobe/enable
! echo test1 test2 >> kprobe_events
tail -n 1 trace | grep -qe "testprobe.* arg1=\"test1\" arg2=\"test2\""

echo 0 > events/enable
echo > kprobe_events
+97 −0
Original line number Diff line number Diff line
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Kprobe event argument syntax

[ -f kprobe_events ] || exit_unsupported # this is configurable

grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue

echo 0 > events/enable
echo > kprobe_events

PROBEFUNC="vfs_read"
GOODREG=
BADREG=
GOODSYM="_sdata"
if ! grep -qw ${GOODSYM} /proc/kallsyms ; then
  GOODSYM=$PROBEFUNC
fi
BADSYM="deaqswdefr"
SYMADDR=0x`grep -w ${GOODSYM} /proc/kallsyms | cut -f 1 -d " "`
GOODTYPE="x16"
BADTYPE="y16"

case `uname -m` in
x86_64|i[3456]86)
  GOODREG=%ax
  BADREG=%ex
;;
aarch64)
  GOODREG=%x0
  BADREG=%ax
;;
arm*)
  GOODREG=%r0
  BADREG=%ax
;;
esac

test_goodarg() # Good-args
{
  while [ "$1" ]; do
    echo "p ${PROBEFUNC} $1" > kprobe_events
    shift 1
  done;
}

test_badarg() # Bad-args
{
  while [ "$1" ]; do
    ! echo "p ${PROBEFUNC} $1" > kprobe_events
    shift 1
  done;
}

echo > kprobe_events

: "Register access"
test_goodarg ${GOODREG}
test_badarg ${BADREG}

: "Symbol access"
test_goodarg "@${GOODSYM}" "@${SYMADDR}" "@${GOODSYM}+10" "@${GOODSYM}-10"
test_badarg "@" "@${BADSYM}" "@${GOODSYM}*10" "@${GOODSYM}/10" \
	    "@${GOODSYM}%10" "@${GOODSYM}&10" "@${GOODSYM}|10"

: "Stack access"
test_goodarg "\$stack" "\$stack0" "\$stack1"
test_badarg "\$stackp" "\$stack0+10" "\$stack1-10"

: "Retval access"
echo "r ${PROBEFUNC} \$retval" > kprobe_events
! echo "p ${PROBEFUNC} \$retval" > kprobe_events

: "Comm access"
test_goodarg "\$comm"

: "Indirect memory access"
test_goodarg "+0(${GOODREG})" "-0(${GOODREG})" "+10(\$stack)" \
	"+0(\$stack1)" "+10(@${GOODSYM}-10)" "+0(+10(+20(\$stack)))"
test_badarg "+(${GOODREG})" "(${GOODREG}+10)" "-(${GOODREG})" "(${GOODREG})" \
	"+10(\$comm)" "+0(${GOODREG})+10"

: "Name assignment"
test_goodarg "varname=${GOODREG}"
test_badarg "varname=varname2=${GOODREG}"

: "Type syntax"
test_goodarg "${GOODREG}:${GOODTYPE}"
test_badarg "${GOODREG}::${GOODTYPE}" "${GOODREG}:${BADTYPE}" \
	"${GOODTYPE}:${GOODREG}"

: "Combination check"

test_goodarg "\$comm:string" "+0(\$stack):string"
test_badarg "\$comm:x64" "\$stack:string" "${GOODREG}:string"

echo > kprobe_events
Loading