[BUG?]3.0-rc4+ftrace+kprobe: set kprobe at instruction 'stwu' lead tosystem crash/freeze

From: Yong Zhang
Date: Fri Jun 24 2011 - 05:22:02 EST


Hi,

When I use kprobe to do something, I found some wired thing.

When CONFIG_FUNCTION_TRACER is disabled:
(gdb) disassemble do_fork
Dump of assembler code for function do_fork:
0xc0037390 <+0>: mflr r0
0xc0037394 <+4>: stwu r1,-64(r1)
0xc0037398 <+8>: mfcr r12
0xc003739c <+12>: stmw r27,44(r1)

Then I:
modprobe kprobe_example func=do_fork offset=4
ls
Things works well.

But when CONFIG_FUNCTION_TRACER is enabled:
(gdb) disassemble do_fork
Dump of assembler code for function do_fork:
0xc0040334 <+0>: mflr r0
0xc0040338 <+4>: stw r0,4(r1)
0xc004033c <+8>: bl 0xc00109d4 <mcount>
0xc0040340 <+12>: stwu r1,-80(r1)
0xc0040344 <+16>: mflr r0
0xc0040348 <+20>: stw r0,84(r1)
0xc004034c <+24>: mfcr r12
Then I:
modprobe kprobe_example func=do_fork offset=12
ls
'ls' will never retrun. system freeze.

I'm using toolchain from:http://www.denx.de/wiki/ELDK-5/WebHome
powerpc-linux-gcc -v
Using built-in specs.
COLLECT_GCC=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/bin/powerpc-linux/powerpc-linux-gcc
COLLECT_LTO_WRAPPER=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/libexec/powerpc-linux/gcc/powerpc-linux/4.5.1/lto-wrapper
Target: powerpc-linux
Configured with:
/opt/poky/build/eldk-2011-05-20-5cde06e-powerpc/tmp/work/i686-nativesdk-oesdk-linux/gcc-cross-canadian-powerpc-4.5.1-r4/gcc-4.5.1/configure
--build=x86_64-linux --host=i686-oesdk-linux --target=powerpc-linux
--prefix=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr
--exec_prefix=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr
--bindir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/bin/powerpc-linux
--sbindir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/bin/powerpc-linux
--libexecdir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/libexec/powerpc-linux
--datadir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/share
--sysconfdir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/etc
--sharedstatedir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/com
--localstatedir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/var
--libdir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/lib/powerpc-linux
--includedir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/include
--oldincludedir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/include
--infodir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/share/info
--mandir=/opt/eldk-5.0/powerpc/sysroots/i686-oesdk-linux/usr/share/man
--with-libtool-sysroot=/opt/poky/build/eldk-2011-05-20-5cde06e-powerpc/tmp/sysroots/i686-oesdk-linux-nativesdk
--with-gnu-ld --enable-shared --enable-languages=c,c++
--enable-threads=posix --disable-multilib --enable-c99
--enable-long-long --enable-symvers=gnu --enable-libstdcxx-pch
--program-prefix=powerpc-linux- --enable-lto --enable-libssp
--disable-bootstrap --disable-libgomp --disable-libmudflap
--enable-cheaders=c_global
--with-local-prefix=/opt/eldk-5.0/powerpc/sysroots/powerpc-linux/usr
--with-gxx-include-dir=/usr/include/c++
--with-build-time-tools=/opt/poky/build/eldk-2011-05-20-5cde06e-powerpc/tmp/sysroots/x86_64-linux/usr/powerpc-linux/bin
--with-sysroot=/opt/eldk-5.0/powerpc/sysroots/powerpc-linux
--with-build-sysroot=/opt/poky/build/eldk-2011-05-20-5cde06e-powerpc/tmp/sysroots/powerpc
--disable-libunwind-exceptions --disable-libssp --disable-libgomp
--disable-libmudflap
--with-mpfr=/opt/poky/build/eldk-2011-05-20-5cde06e-powerpc/tmp/sysroots/i686-oesdk-linux-nativesdk
--with-mpc=/opt/poky/build/eldk-2011-05-20-5cde06e-powerpc/tmp/sysroots/i686-oesdk-linux-nativesdk
--enable-__cxa_atexit
Thread model: posix
gcc version 4.5.1 (GCC)


And kernel config is attached.

BTW, I have made a patch to make kprobe_example set breakpoint easily,
attached too.

Thanks,
Yong

--
Only stand for myself

Attachment: .config
Description: Binary data

diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c
index ebf5e0c..f0ce4e6 100644
--- a/samples/kprobes/kprobe_example.c
+++ b/samples/kprobes/kprobe_example.c
@@ -13,11 +13,17 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
+#include <linux/limits.h>
+
+static char func_name[NAME_MAX] = "do_fork";
+module_param_string(func, func_name, NAME_MAX, S_IRUGO);
+MODULE_PARM_DESC(func, "Function to kprobe");
+
+static unsigned int offset;
+module_param(offset, uint, S_IRUGO);

/* For each probe you need to allocate a kprobe structure */
-static struct kprobe kp = {
- .symbol_name = "do_fork",
-};
+static struct kprobe kp;

/* kprobe pre_handler: called just before the probed instruction is executed */
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
@@ -76,6 +82,8 @@ static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
static int __init kprobe_init(void)
{
int ret;
+ kp.symbol_name = func_name;
+ kp.offset = offset;
kp.pre_handler = handler_pre;
kp.post_handler = handler_post;
kp.fault_handler = handler_fault;