Skip to contentSkip to conversation

KGTP (Linux Kernel debugger and tracer) lite patch for review

PATCH In review Hui Zhu 2 participants 7 messages May 9, 2012 – Nov 21, 2013

Subsystems (8)
Arm (32-bit) x86 Library code MIPS +4 more subsystems
lore
Share & tools
lore

Hui Zhu

author
#0 lore raw

PATCH 1/1 KGTP (Linux Kernel debugger and tracer) lite patch for review

Hi guys,

According to the comments of Andi, I make a patch for review that remove most of the function inside it. It just support function set tracepoint collect the register info (http://code.google.com/p/kgtp/wiki/HOWTO#Use_tracepoint_get_register_info_from_a_point_of_kernel) and access memory directly (http://code.google.com/p/kgtp/wiki/HOWTO#Access_memory_directly).
Please help me review it.

Following part is the introduce of KGTP:
KGTP is a realtime and lightweight Linux Kernel debugger and tracer.
It makes Linux Kernel supply a GDB remote debug interface. Then GDB in current machine or remote machine can debug and trace Linux through GDB tracepoint and some other functions without stopping the Linux Kernel. And even if the board doesn't have GDB on it and doesn't have interface for remote debug. It can debug the Linux Kernel using offline debug (See http://code.google.com/p/kgtp/wiki/HOWTO#/sys/kernel/debug/gtpframe_and_offline_debug).
And it can work with Android (See http://code.google.com/p/kgtp/wiki/HowToUseKGTPinAndroid).
Now, it supports X86-32, X86-64, MIPS and ARM.
Please go to http://code.google.com/p/kgtp/wiki/HOWTO or http://code.google.com/p/kgtp/wiki/HOWTO (Chinese) to get more info about howto use KGTP.

Thanks,
Hui

---

---
 arch/arm/include/asm/gtp.h  |   34 +
 arch/mips/include/asm/gtp.h |   68 +++
 arch/x86/include/asm/gtp.h  |   96 ++++
 kernel/Makefile             |    2
 kernel/gtp.c                |  966 ++++++++++++++++++++++++++++++++++++++++++++
 lib/Kconfig.debug           |    8
 6 files changed, 1174 insertions(+)
arch/arm/include/asm/gtp.h new file +34 -0
@@ -0,0 +1,34 @@
+#ifndef _ASM_ARM_GTP_H_
+#define _ASM_ARM_GTP_H_
+
+#define ULONGEST		uint64_t
+#define CORE_ADDR		unsigned long
+
+#define GTP_REG_ASCII_SIZE	336
+
+static inline void
+gtp_regs2ascii(struct pt_regs *regs, char *buf)
+{
+#ifdef __LITTLE_ENDIAN
+#define SWAB(a)		swab32(a)
+#else
+#define SWAB(a)		(a)
+#endif
+	int	i;
+
+	for (i = 0; i < 16; i++) {
+		sprintf(buf, "%08lx", (unsigned long) SWAB(regs->uregs[i]));
+		buf += 8;
+	}
+
+	/* f0-f7 fps */
+	memset(buf, '0', 200);
+	buf += 200;
+
+	sprintf(buf, "%08lx",
+		 (unsigned long) SWAB(regs->uregs[16]));
+	buf += 8;
+#undef SWAB
+}
+
+#endif
arch/mips/include/asm/gtp.h new file +68 -0

68 lines not on this page · raw message

arch/x86/include/asm/gtp.h new file +96 -0

96 lines not on this page · raw message

kernel/Makefile +2 -0
@@ -107,6 +107,8 @@ obj-$(CONFIG_PADATA) += padata.o
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_JUMP_LABEL) += jump_label.o
 
+obj-$(CONFIG_GTP) += gtp.o
+
 $(obj)/configs.o: $(obj)/config_data.h
 
 # config_data.h contains the same information as ikconfig.h but gzipped.
kernel/gtp.c new file +966 -0

966 lines not on this page · raw message

lib/Kconfig.debug +8 -0
@@ -1289,6 +1289,14 @@ config ASYNC_RAID6_TEST
 
 	  If unsure, say N.
 
+config GTP
+	tristate "GDB tracepoint support"
+	depends on X86 || ARM || MIPS
+	select KPROBES
+	select DEBUG_FS
+	---help---
+	  Supply GDB tracepoint interface in /sys/kernel/debug/gtp.
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
#1 lore raw

Please provide better explanation of the use case for this module. One paragraph why someone would want it in their kernel.

arch/arm/include/asm/gtp.h line 4

Quoted 6 lines

+++ b/arch/arm/include/asm/gtp.h

arch/arm/include/asm/gtp.h new file +4 -0
@@ -0,0 +1,34 @@
+#ifndef _ASM_ARM_GTP_H_
+#define _ASM_ARM_GTP_H_
+
+#define ULONGEST		uint64_t

So u64 in kernel. Just use that.

Review line 5

Quoted 1 line
(quoted diff) +1 -0
+#define CORE_ADDR		unsigned long

In linux kernel CORE_ADDR is always unsigned long. Use that.

arch/arm/include/asm/gtp.h line 16

Quoted 11 lines
arch/arm/include/asm/gtp.h new file +11 -0
+
+#define GTP_REG_ASCII_SIZE	336
+
+static inline void
+gtp_regs2ascii(struct pt_regs *regs, char *buf)
+{
+#ifdef __LITTLE_ENDIAN
+#define SWAB(a)		swab32(a)
+#else
+#define SWAB(a)		(a)
+#endif

That's just ntohl()? Just use that

Linux already has macros for this:

arch/arm/include/asm/gtp.h line 20

Quoted 4 lines
arch/arm/include/asm/gtp.h new file +4 -0
+	int	i;
+
+	for (i = 0; i < 16; i++) {
+		sprintf(buf, "%08lx", (unsigned long) SWAB(regs->uregs[i]));

Is the gdb protocol really big endian in ASCII?

Also could you share code on this with the in kernel gdbstub?

kernel/gtp.c line 34

Quoted 4 lines
kernel/gtp.c new file +4 -0
+#include <linux/slab.h>
+#include <asm/gtp.h>
+
+#define GTP_DEBUG		KERN_WARNING

You should use the pr_* macros now

kernel/gtp.c line 87

Quoted 4 lines
kernel/gtp.c new file +4 -0
+static int			gtp_disconnected_tracing;
+static int			gtp_circular;
+
+static DEFINE_SPINLOCK(gtp_frame_lock);

Every spinlock needs a comment that describes what it protects. I believe checkpatch warns about that. Did you run it?

kernel/gtp.c line 158

Quoted 12 lines
kernel/gtp.c new file +12 -0
+
+	tmp = gtp_frame_alloc(GTP_FRAME_REG_SIZE);
+	if (!tmp)
+		return NULL;
+
+	*next = tmp;
+	tmp[0] = 'r';
+	freg = (struct gtp_frame_reg *) (tmp + 1);
+	memcpy(&freg->regs, regs, sizeof(struct pt_regs));
+#if !defined CONFIG_X86_32 && !defined CONFIG_X86_64
+	freg->regs.sp = (unsigned long)&regs->sp;
+#endif	/* CONFIG_X86_32 CONFIG_X86_64 */

That looks weird. What does that do?

kernel/gtp.c line 219

Quoted 5 lines
kernel/gtp.c new file +5 -0
+gtp_action_alloc(char type)
+{
+	struct action	*ret;
+
+	ret = kmalloc(sizeof(struct action), GFP_KERNEL);

kzalloc

Same problem in others.

kernel/gtp.c line 313

Quoted 2 lines
kernel/gtp.c new file +2 -0
+static int
+hex2int(char hex, int *i)

I'm sure we have code for this. strtoul et.al.?

Didn't read further so far.

-Andi

author
#2 lore raw
Quoted 2 lines · Andi Kleen

Please provide better explanation of the use case for this module. One paragraph why someone would want it in their kernel.

sudo insmod kernel/gtp.ko
sudo gdb ./vmlinux
#Connect KGTP interface
(gdb) target remote /sys/kernel/debug/gtp
Remote debugging using /sys/kernel/debug/gtp
0x0000000000000000 in irq_stack_union ()
#Access memory directly
(gdb) p jiffies_64
$1 = 4332444293
(gdb) p jiffies_64
$2 = 4332444591
(gdb) p *((struct module *)((char *)modules->next - ((size_t) &(((struct module *)0)->list)))) $3 = {state = MODULE_STATE_LIVE, list = {next = 0xffffffffa0964188, prev = 0xffffffff81c345f0},

  name = "gtp", '\000' <repeats 52 times>, mkobj = {kobj = {name = 0xffff88011f5c49c8 "gtp", entry = {
        next = 0xffff880221cd6420, prev = 0xffffffffa09641d8}, parent = 0xffff880221cd6438, kset = 0xffff880221cd6420,
...
(gdb) p *(struct device *)(__per_cpu_offset[0]+(uint64_t)(&mce_device))
$4 = {parent = 0xffff8802212f8000, p = 0x1fe, kobj = {name = 0x0, entry = {next = 0x0, prev = 0xffffffff8102ae70},
    parent = 0x0, kset = 0x0, ktype = 0x0, sd = 0x0, kref = {refcount = {counter = 0}}, state_initialized = 0,

...
#Set tracepoint to collect the register info of function vfs_read
(gdb) trace vfs_read
Tracepoint 1 at 0xffffffff8117a3d0: file /home/teawater/kernel2/linux/fs/read_write.c, line 365. (gdb) actions
Enter actions for tracepoint 1, one per line.
End with a line saying just "end".

Quoted 2 lines

collect $reg
end

(gdb) tstart
(gdb) tstop
(gdb) tfind
Found trace frame 0, tracepoint 1
#0 vfs_read (file=0xffff880070bb6100,

    buf=0x31cb8f0 "$2aa6178136313733#331bb700088ffff481fe4450188ffff002", '0' <repeats 13 times>, "f0b81c03000000000061bb700088ffff781fe4450188ffff301fe4450188ffff606944030000000058f19a010288ffff01", '0' <repeats 14 times>, "4602", '0' <repeats 12 times>, "f0b81c0"..., count=8192, pos=0xffff880145e41f48) at /home/teawater/kernel2/linux/fs/read_write.c:365
365	{
(gdb) info reg
rax            0x0	0
rbx            0xffff880070bb6100	-131939504004864
rcx            0xffff880145e41f48	-131935927787704
rdx            0x2000	8192
rsi            0x31cb8f0	52214000
rdi            0xffff880070bb6100	-131939504004864
rbp            0xffff880145e41f78	0xffff880145e41f78
rsp            0xffff880145e41f30	0xffff880145e41f30
r8             0x3446960	54815072
r9             0xffff8802019af158	-131932778466984
r10            0x1	1
r11            0x246	582
r12            0x31cb8f0	52214000
r13            0x2000	8192
r14            0xa	10
r15            0xa	10
rip            0xffffffff8117a3d0	0xffffffff8117a3d0 <vfs_read>
eflags         0x286	[ PF SF IF ]
cs             0x10	16
ss             0x18	24
ds             *value not available*
es             *value not available*
fs             *value not available*
gs             *value not available*

Because this is a lite patch, so this patch doesn't support other functions of KGTP.

Quoted 10 lines

Review line 4

Quoted 7 lines

+++ b/arch/arm/include/asm/gtp.h

(quoted diff) +4 -0
@@ -0,0 +1,34 @@
+#ifndef _ASM_ARM_GTP_H_
+#define _ASM_ARM_GTP_H_
+
+#define ULONGEST		uint64_t

So u64 in kernel. Just use that.

Quoted 4 lines

Review line 5

Quoted 1 line
(quoted diff) +1 -0
+#define CORE_ADDR		unsigned long

In linux kernel CORE_ADDR is always unsigned long. Use that.

ULONGEST and CORE_ADDR is the type from GDB rsp packet. I use it to parse the package from GDB. Then want to add add a new arch to KGTP, just need set this two type same with GDB. So do you mind I keep it?

Quoted 5 lines
Quoted 5 lines
(quoted diff) +5 -0
+
+#define GTP_REG_ASCII_SIZE	336
+
+static inline void
+gtp_regs2ascii(struct pt_regs *regs, char *buf)
Quoted 8 lines

Review line 16

Quoted 6 lines
(quoted diff) +6 -0
+{
+#ifdef __LITTLE_ENDIAN
+#define SWAB(a)		swab32(a)
+#else
+#define SWAB(a)		(a)
+#endif

That's just ntohl()? Just use that

It is fixed in new patch.

Quoted 9 lines

Linux already has macros for this:

Review line 20

Quoted 4 lines
(quoted diff) +4 -0
+	int	i;
+
+	for (i = 0; i < 16; i++) {
+		sprintf(buf, "%08lx", (unsigned long) SWAB(regs->uregs[i]));

Is the gdb protocol really big endian in ASCII?

Yes, I tested this part of code in before. GDB need it in this format.

Quoted 1 line

Also could you share code on this with the in kernel gdbstub?

Most of this part of code is deep inside the kgdb c code. Share these code need change this part of code out of kgdb and something else.

Quoted 7 lines

Review line 24

Quoted 5 lines
(quoted diff) +4 -0
+#include <linux/slab.h>
+#include <asm/gtp.h>
+
+#define GTP_DEBUG		KERN_WARNING

You should use the pr_* macros now

OK. I changed all of them to pr_devel.

Quoted 8 lines

Review line 28

Quoted 5 lines
(quoted diff) +4 -0
+static int			gtp_disconnected_tracing;
+static int			gtp_circular;
+
+static DEFINE_SPINLOCK(gtp_frame_lock);

Every spinlock needs a comment that describes what it protects. I believe checkpatch warns about that. Did you run it?

I use it with the patch but didn't get the warn. It is fixed in the new patch.

Quoted 15 lines

Review

Quoted 13 lines
(quoted diff) +12 -0
+
+	tmp = gtp_frame_alloc(GTP_FRAME_REG_SIZE);
+	if (!tmp)
+		return NULL;
+
+	*next = tmp;
+	tmp[0] = 'r';
+	freg = (struct gtp_frame_reg *) (tmp + 1);
+	memcpy(&freg->regs, regs, sizeof(struct pt_regs));
+#if !defined CONFIG_X86_32 && !defined CONFIG_X86_64
+	freg->regs.sp = (unsigned long)&regs->sp;
+#endif	/* CONFIG_X86_32 CONFIG_X86_64 */

That looks weird. What does that do?

Oops, this part of code is worng.(I copy this function from a very old version of KGTP.) Fixed in new patch.

Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +5 -0
+gtp_action_alloc(char type)
+{
+	struct action	*ret;
+
+	ret = kmalloc(sizeof(struct action), GFP_KERNEL);

kzalloc

All fixed.

Quoted 7 lines

Same problem in others.

Review

Quoted 2 lines
(quoted diff) +2 -0
+static int
+hex2int(char hex, int *i)

I'm sure we have code for this. strtoul et.al.?

OK. I changed hex2ulongest to simple_strtoull in new patch.
But I meet a issue is checkpatch told me that "simple_strtoull is obsolete, use kstrtoull instead". But kstrtoull cannot get the address that where this convert stop at. Do you have some comments on it?

Quoted 6 lines

Didn't read further so far.

-Andi

Thanks for your help.
I post a new patch according to your comments. Please help me review it.

Thanks,
Hui

---
 arch/arm/include/asm/gtp.h  |   28 +
 arch/mips/include/asm/gtp.h |   64 +++
 arch/x86/include/asm/gtp.h  |   96 ++++
 kernel/Makefile             |    2
 kernel/gtp.c                |  914 ++++++++++++++++++++++++++++++++++++++++++++
 lib/Kconfig.debug           |    8
 6 files changed, 1112 insertions(+)
arch/arm/include/asm/gtp.h new file +28 -0
@@ -0,0 +1,28 @@
+#ifndef _ASM_ARM_GTP_H_
+#define _ASM_ARM_GTP_H_
+
+#define ULONGEST		uint64_t
+#define CORE_ADDR		unsigned long
+
+#define GTP_REG_ASCII_SIZE	336
+
+static inline void
+gtp_regs2ascii(struct pt_regs *regs, char *buf)
+{
+	int	i;
+
+	for (i = 0; i < 16; i++) {
+		sprintf(buf, "%08lx", (unsigned long) ntohl(regs->uregs[i]));
+		buf += 8;
+	}
+
+	/* f0-f7 fps */
+	memset(buf, '0', 200);
+	buf += 200;
+
+	sprintf(buf, "%08lx",
+		 (unsigned long) ntohl(regs->uregs[16]));
+	buf += 8;
+}
+
+#endif
arch/mips/include/asm/gtp.h new file +64 -0

64 lines not on this page · raw message

arch/x86/include/asm/gtp.h new file +96 -0

96 lines not on this page · raw message

kernel/Makefile +2 -0
@@ -107,6 +107,8 @@ obj-$(CONFIG_PADATA) += padata.o
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_JUMP_LABEL) += jump_label.o
 
+obj-$(CONFIG_GTP) += gtp.o
+
 $(obj)/configs.o: $(obj)/config_data.h
 
 # config_data.h contains the same information as ikconfig.h but gzipped.
kernel/gtp.c new file +914 -0

914 lines not on this page · raw message

lib/Kconfig.debug +8 -0
@@ -1289,6 +1289,14 @@ config ASYNC_RAID6_TEST
 
 	  If unsure, say N.
 
+config GTP
+	tristate "GDB tracepoint support"
+	depends on X86 || ARM || MIPS
+	select KPROBES
+	select DEBUG_FS
+	---help---
+	  Supply GDB tracepoint interface in /sys/kernel/debug/gtp.
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
#3 lore raw
Quoted 5 lines · Hui Zhu
Quoted 2 lines · Andi Kleen

Please provide better explanation of the use case for this module. One paragraph why someone would want it in their kernel.

sudo insmod kernel/gtp.ko

Thanks. Please put that into the change log for the next iteration.

Quoted 7 lines
Quoted 7 lines

arch/arm/include/asm/gtp.h line 4

Quoted 4 lines
arch/arm/include/asm/gtp.h new file +4 -0
+#ifndef _ASM_ARM_GTP_H_
+#define _ASM_ARM_GTP_H_
+
+#define ULONGEST		uint64_t

So u64 in kernel. Just use that.

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

+#define CORE_ADDR unsigned long

In linux kernel CORE_ADDR is always unsigned long. Use that.

ULONGEST and CORE_ADDR is the type from GDB rsp packet. I use it to parse the package from GDB. Then want to add add a new arch to KGTP, just need set this two type same with GDB. So do you mind I keep it?

I was just aiming to eliminate the asm files. Is that possible? If you can't please reuse stuff from kgdb.

Quoted 4 lines

OK. I changed hex2ulongest to simple_strtoull in new patch. But I meet a issue is checkpatch told me that "simple_strtoull is obsolete, use kstrtoull instead". But kstrtoull cannot get the address that where this convert stop at. Do you have some comments on it?

Keep using simple_strtoull. Ignore checkpatch when it's wrong.

arch/mips/include/asm/gtp.h line 18

Quoted 4 lines
arch/mips/include/asm/gtp.h new file +4 -0
+static inline void
+gtp_regs2ascii(struct pt_regs *regs, char *buf)
+{
+#ifdef CONFIG_32BIT

BITS_PER_LONG == 32 ? Then it would work on other archs and you could move it out from asm/

arch/mips/include/asm/gtp.h line 29

Quoted 11 lines
arch/mips/include/asm/gtp.h new file +11 -0
+#define OUTFORMAT	"%08lx"
+#define REGSIZE		8
+#define SWAB(a)		ntohl(a)
+#else
+#define OUTFORMAT	"%016lx"
+#define REGSIZE		16
+#ifdef __LITTLE_ENDIAN
+#define SWAB(a)		swab64(a)
+#else
+#define SWAB(a)		(a)
+#endif

be64_to_cpu()

kernel/gtp.c line 2

Quoted 3 lines
kernel/gtp.c new file +2 -0
@@ -0,0 +1,914 @@
+/*
+ * Kernel GDB tracepoint module.

add one sentence here what this file does.

kernel/gtp.c line 160

Quoted 7 lines
kernel/gtp.c new file +7 -0
+	memcpy(&freg->regs, regs, sizeof(struct pt_regs));
+#ifdef CONFIG_X86_32
+	freg->regs.sp = (unsigned long)&regs->sp;
+#endif	/* CONFIG_X86_32 */
+#ifdef CONFIG_X86
+	freg->regs.ip -= 1;
+#endif	/* CONFIG_X86 */

What is that for? - 1?

kernel/gtp.c line 229

Quoted 3 lines
kernel/gtp.c new file +3 -0
+
+static void
+gtp_action_release(struct action *ae)

Standard style is type on the same line.

kernel/gtp.c line 238

Quoted 9 lines
kernel/gtp.c new file +9 -0
+{
+	struct action	*ae2;
+
+	while (ae) {
+		ae2 = ae;
+		ae = ae->next;
+		/* Release ae2.  */
+		kfree(ae2);
+	}

Better use a list_head from list.h and list_for_each_entry_safe() etc. This will simplify some of the list code.

kernel/gtp.c line 583

Quoted 7 lines
kernel/gtp.c new file +7 -0
+static int
+gtp_gdbrsp_qtstart(void)
+{
+	struct gtp_entry	*tpe;
+
+	if (gtp_start)
+		return -EBUSY;

This is in a lot of places. Can you put it somewhere more central?

Quoted 4 lines
kernel/gtp.c new file +4 -0
+	if (!gtp_frame) {
+		gtp_frame = vmalloc(GTP_FRAME_SIZE);
+		if (!gtp_frame)
+			return -ENOMEM;

kernel/gtp.c line 598

Quoted 10 lines
kernel/gtp.c new file +10 -0
+
+		gtp_frame_reset();
+	}
+
+	for (tpe = gtp_list; tpe; tpe = tpe->next) {
+		if (tpe->action_list) {
+			int	ret = register_kprobe(&tpe->kp);
+			if (ret < 0) {
+				gtp_gdbrsp_qtstop();
+				return ret;

memory leak with frame?

kernel/gtp.c line 617

Quoted 4 lines
kernel/gtp.c new file +4 -0
+	pr_devel("gtp_gdbrsp_QT: %s\n", pkg);
+
+	if (strcmp("init", pkg) == 0)
+		ret = gtp_gdbrsp_qtinit();

This if cascade should be probably a table walk

kernel/gtp.c line 634

Quoted 7 lines
kernel/gtp.c new file +7 -0
+	else if (strcmp("Stop", pkg) == 0)
+		ret = gtp_gdbrsp_qtstop();
+
+	return ret;
+}
+
+static unsigned char	gtp_m_buffer[0xffff];

Ok so what lock protects this buffer?

kernel/gtp.c line 679

Quoted 4 lines
kernel/gtp.c new file +4 -0
+	struct gtp_frame_reg	*fr = NULL;
+
+	if (GTP_RW_MAX - 4 - gtp_rw_size < GTP_REG_ASCII_SIZE)
+		return -E2BIG;

The magic 4 should be a define

kernel/gtp.c line 691

Quoted 7 lines
kernel/gtp.c new file +7 -0
+	next = gtp_frame_current->next;
+	while (next) {
+		switch (next[0]) {
+		case 'r':
+			fr = (struct gtp_frame_reg *) (next + 1);
+			goto check;
+			break;

either check or break, but not both

kernel/gtp.c line 693

Quoted 2 lines
kernel/gtp.c new file +2 -0
+		default:
+			next = NULL;

Not needed

kernel/gtp.c line 701

Quoted 8 lines
kernel/gtp.c new file +8 -0
+			break;
+		}
+	}
+check:
+	if (fr)
+		gtp_regs2ascii(&fr->regs, gtp_rw_bufp);
+	else
+		memset(gtp_rw_bufp, '0', GTP_REG_ASCII_SIZE);

No 0 termination?

kernel/gtp.c line 713

Quoted 8 lines
kernel/gtp.c new file +8 -0
+
+static int
+gtp_open(struct inode *inode, struct file *file)
+{
+	if (atomic_inc_return(&gtp_count) > 1) {
+		atomic_dec(&gtp_count);
+		return -EBUSY;
+	}

This looks racy. Better use a try mutex lock

Quoted 8 lines
kernel/gtp.c new file +8 -0
+static int __init gtp_init(void)
+{
+	atomic_set(&gtp_count, 0);
+	gtp_read_ack = 0;
+	gtp_rw_buf = NULL;
+	gtp_rw_bufp = NULL;
+	gtp_rw_size = 0;
+	gtp_start = 0;

kernel/gtp.c line 894

Quoted 10 lines
kernel/gtp.c new file +10 -0
+	gtp_disconnected_tracing = 0;
+	gtp_circular = 0;
+	gtp_frame_num = 0;
+	gtp_frame = NULL;
+	gtp_frame_r_start = NULL;
+	gtp_frame_w_start = NULL;
+	gtp_frame_w_end = NULL;
+	gtp_frame_r_cache = NULL;
+	gtp_frame_is_circular = 0;
+	gtp_frame_current = NULL;

Globals don't need to be initialized with 0

lib/Kconfig.debug config ASYNC_RAID6_TEST · line 1298

Quoted 8 lines
lib/Kconfig.debug +7 -0
+config GTP
+	tristate "GDB tracepoint support"
+	depends on X86 || ARM || MIPS
+	select KPROBES
+	select DEBUG_FS
+	---help---
+	  Supply GDB tracepoint interface in /sys/kernel/debug/gtp.

Need far more description here. Write 1-2 paragraphs why a user wants this. checkpatch should have warned.

-Andi

Signature · 1 line
[email protected] -- Speaking for myself only.
author
#4 lore raw
Quoted 8 lines · Andi Kleen
Quoted 5 lines · Hui Zhu
Quoted 2 lines · Andi Kleen

Please provide better explanation of the use case for this module. One paragraph why someone would want it in their kernel.

sudo insmod kernel/gtp.ko

Thanks. Please put that into the change log for the next iteration.

OK. I will add them.

Quoted 13 lines
Quoted 13 lines
Quoted 12 lines

Review

Quoted 5 lines
(quoted diff) +4 -0
+#ifndef _ASM_ARM_GTP_H_
+#define _ASM_ARM_GTP_H_
+
+#define ULONGEST           uint64_t

So u64 in kernel. Just use that.

Quoted 1 line

+#define CORE_ADDR unsigned long

In linux kernel CORE_ADDR is always unsigned long. Use that.

Quoted 6 lines
Quoted 3 lines

ULONGEST and CORE_ADDR is the type from GDB rsp packet. I use it to parse the package from GDB. Then want to add add a new arch to KGTP, just need set this two type same with GDB. So do you mind I keep it?

I was just aiming to eliminate the asm files. Is that possible? If you can't please reuse stuff from kgdb.

I remove them from asm files, and add:
#ifndef ULONGEST
#define ULONGEST uint64_t
#endif
#ifndef CORE_ADDR
#define CORE_ADDR unsigned long
#endif
in gtp.c
Then if not need, the arch didn't define ULONGEST and CORE_ADDR for itself.

Quoted 8 lines
Quoted 5 lines

OK. I changed hex2ulongest to simple_strtoull in new patch. But I meet a issue is checkpatch told me that "simple_strtoull is obsolete, use kstrtoull instead". But kstrtoull cannot get the address that where this convert stop at. Do you have some comments on it?

Keep using simple_strtoull. Ignore checkpatch when it's wrong.

Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+static inline void
+gtp_regs2ascii(struct pt_regs *regs, char *buf)
+{
+#ifdef CONFIG_32BIT

BITS_PER_LONG == 32 ? Then it would work on other archs and you could move it out from asm/

That is hard becuase the different arch's format of reg is so different. For example ARM and MIPS have a lot of special reg that cannot be converted by a for loop.

After check the code the kgdb, I thought that good ways is use dbg_reg_def of kgdb to convert the reg to gdb rsp format. But use it directly will make kgtp depend on kgdb. What I thought is move this part of code out from kgdb, when kgdb or kgtp need, select it too. But I am not sure Jason is OK with that.

Quoted 14 lines

Review

Quoted 12 lines
(quoted diff) +11 -0
+#define OUTFORMAT    "%08lx"
+#define REGSIZE              8
+#define SWAB(a)              ntohl(a)
+#else
+#define OUTFORMAT    "%016lx"
+#define REGSIZE              16
+#ifdef __LITTLE_ENDIAN
+#define SWAB(a)              swab64(a)
+#else
+#define SWAB(a)              (a)
+#endif

be64_to_cpu()

OK.

Quoted 6 lines

Review line 2

Quoted 4 lines
(quoted diff) +2 -0
@@ -0,0 +1,914 @@
+/*
+ * Kernel GDB tracepoint module.

add one sentence here what this file does.

OK.

Quoted 10 lines

Review line 9

Quoted 8 lines
(quoted diff) +7 -0
+     memcpy(&freg->regs, regs, sizeof(struct pt_regs));
+#ifdef CONFIG_X86_32
+     freg->regs.sp = (unsigned long)&regs->sp;
+#endif       /* CONFIG_X86_32 */
+#ifdef CONFIG_X86
+     freg->regs.ip -= 1;
+#endif       /* CONFIG_X86 */

What is that for? - 1?

That is because when kprobe, the ip of X86 point will have a offset with current ip.

Quoted 6 lines

Review line 12

Quoted 4 lines
(quoted diff) +3 -0
+
+static void
+gtp_action_release(struct action *ae)

Standard style is type on the same line.

OK. Fixed them all in the patch.

Quoted 13 lines

Review line 21

Quoted 10 lines
(quoted diff) +9 -0
+{
+     struct action   *ae2;
+
+     while (ae) {
+             ae2 = ae;
+             ae = ae->next;
+             /* Release ae2.  */
+             kfree(ae2);
+     }

Better use a list_head from list.h and list_for_each_entry_safe() etc. This will simplify some of the list code.

OK. I changed both gtp_list and action to list_head.

Quoted 10 lines

Review line 28

Quoted 8 lines
(quoted diff) +7 -0
+static int
+gtp_gdbrsp_qtstart(void)
+{
+     struct gtp_entry        *tpe;
+
+     if (gtp_start)
+             return -EBUSY;

This is in a lot of places. Can you put it somewhere more central?

Sorry I don't understand this part. Do you want I change all "struct gtp_entry *tpe;" to "struct gtp_entry *tpe;"?

Quoted 8 lines
Quoted 8 lines
(quoted diff) +8 -0
+     if (!gtp_frame) {
+             gtp_frame = vmalloc(GTP_FRAME_SIZE);
+             if (!gtp_frame)
+                     return -ENOMEM;
+
+             gtp_frame_reset();
+     }
+
Quoted 8 lines

Review line 42

Quoted 6 lines
(quoted diff) +6 -0
+     for (tpe = gtp_list; tpe; tpe = tpe->next) {
+             if (tpe->action_list) {
+                     int     ret = register_kprobe(&tpe->kp);
+                     if (ret < 0) {
+                             gtp_gdbrsp_qtstop();
+                             return ret;

memory leak with frame?

Use this because I don't want alloc frame each time tracepoint start. It will be release in gtp_release.

Quoted 7 lines

Review line 46

Quoted 5 lines
(quoted diff) +4 -0
+     pr_devel("gtp_gdbrsp_QT: %s\n", pkg);
+
+     if (strcmp("init", pkg) == 0)
+             ret = gtp_gdbrsp_qtinit();

This if cascade should be probably a table walk

I cannot find the examle about it in the Kernel, could you give me a example?

Quoted 10 lines

Review line 53

Quoted 8 lines
(quoted diff) +7 -0
+     else if (strcmp("Stop", pkg) == 0)
+             ret = gtp_gdbrsp_qtstop();
+
+     return ret;
+}
+
+static unsigned char gtp_m_buffer[0xffff];

Ok so what lock protects this buffer?

No. The gtp_frame_lock protects the vars that follow it:
static int gtp_frame_num;
static char *gtp_frame;
static char *gtp_frame_r_start;
static char *gtp_frame_w_start;
static char *gtp_frame_w_end;
static char *gtp_frame_r_cache;
static int gtp_frame_is_circular;
It protects them all.

gtp_m_buffer is protected by gtp_rw_lock that I just add in new patch.

Quoted 7 lines

Review line 57

Quoted 5 lines
(quoted diff) +4 -0
+     struct gtp_frame_reg    *fr = NULL;
+
+     if (GTP_RW_MAX - 4 - gtp_rw_size < GTP_REG_ASCII_SIZE)
+             return -E2BIG;

The magic 4 should be a define

Done.

Quoted 9 lines

Review line 64

Quoted 8 lines
(quoted diff) +7 -0
+     next = gtp_frame_current->next;
+     while (next) {
+             switch (next[0]) {
+             case 'r':
+                     fr = (struct gtp_frame_reg *) (next + 1);
+                     goto check;
+                     break;
Quoted 9 lines

either check or break, but not both

Review line 66

Quoted 2 lines
(quoted diff) +2 -0
+             default:
+                     next = NULL;

Not needed

Quoted 3 lines
(quoted diff) +3 -0
+                     break;
+             }
+     }

This part is fixed.

Quoted 7 lines

Review line 74

Quoted 5 lines
(quoted diff) +5 -0
+check:
+     if (fr)
+             gtp_regs2ascii(&fr->regs, gtp_rw_bufp);
+     else
+             memset(gtp_rw_bufp, '0', GTP_REG_ASCII_SIZE);

No 0 termination?

No, it don't need becuase it will add head and tail in gtp_write.

Quoted 11 lines

Review line 82

Quoted 9 lines
(quoted diff) +8 -0
+
+static int
+gtp_open(struct inode *inode, struct file *file)
+{
+     if (atomic_inc_return(&gtp_count) > 1) {
+             atomic_dec(&gtp_count);
+             return -EBUSY;
+     }

This looks racy. Better use a try mutex lock

Fixed.

Quoted 13 lines
Quoted 13 lines
(quoted diff) +12 -0
+static int __init gtp_init(void)
+{
+     atomic_set(&gtp_count, 0);
+     gtp_read_ack = 0;
+     gtp_rw_buf = NULL;
+     gtp_rw_bufp = NULL;
+     gtp_rw_size = 0;
+     gtp_start = 0;
+     gtp_disconnected_tracing = 0;
+     gtp_circular = 0;
+     gtp_frame_num = 0;
+     gtp_frame = NULL;
Quoted 8 lines

Review line 100

Quoted 6 lines
(quoted diff) +6 -0
+     gtp_frame_r_start = NULL;
+     gtp_frame_w_start = NULL;
+     gtp_frame_w_end = NULL;
+     gtp_frame_r_cache = NULL;
+     gtp_frame_is_circular = 0;
+     gtp_frame_current = NULL;

Globals don't need to be initialized with 0

OK. Fixed.

Quoted 10 lines

Review line 107

Quoted 9 lines
(quoted diff) +7 -0
+config GTP
+     tristate "GDB tracepoint support"
+     depends on X86 || ARM || MIPS
+     select KPROBES
+     select DEBUG_FS
+     ---help---
+       Supply GDB tracepoint interface in /sys/kernel/debug/gtp.
Quoted 2 lines

Need far more description here. Write 1-2 paragraphs why a user wants this. checkpatch should have warned.

OK. Add some introduce. checkpatch is OK with it.

Quoted 4 lines

-Andi
--
[email protected] -- Speaking for myself only.

Thanks for your help.

Best,
Hui

sudo insmod kernel/gtp.ko
sudo gdb ./vmlinux
#Connect KGTP interface
(gdb) target remote /sys/kernel/debug/gtp
Remote debugging using /sys/kernel/debug/gtp
0x0000000000000000 in irq_stack_union ()
#Access memory directly
(gdb) p jiffies_64
$1 = 4332444293
(gdb) p jiffies_64
$2 = 4332444591
(gdb) p *((struct module *)((char *)modules->next - ((size_t) &(((struct module *)0)->list)))) $3 = {state = MODULE_STATE_LIVE, list = {next = 0xffffffffa0964188, prev = 0xffffffff81c345f0},

 name = "gtp", '\000' <repeats 52 times>, mkobj = {kobj = {name = 0xffff88011f5c49c8 "gtp", entry = {
       next = 0xffff880221cd6420, prev = 0xffffffffa09641d8}, parent = 0xffff880221cd6438, kset = 0xffff880221cd6420,

...
(gdb) p *(struct device *)(__per_cpu_offset[0]+(uint64_t)(&mce_device))
$4 = {parent = 0xffff8802212f8000, p = 0x1fe, kobj = {name = 0x0, entry = {next = 0x0, prev = 0xffffffff8102ae70},
parent = 0x0, kset = 0x0, ktype = 0x0, sd = 0x0, kref = {refcount = {counter = 0}}, state_initialized = 0,
...
#Set tracepoint to collect the register info of function vfs_read
(gdb) trace vfs_read
Tracepoint 1 at 0xffffffff8117a3d0: file /home/teawater/kernel2/linux/fs/read_write.c, line 365.
(gdb) actions
Enter actions for tracepoint 1, one per line.
End with a line saying just "end".
collect $reg
end
(gdb) tstart
(gdb) tstop
(gdb) tfind
Found trace frame 0, tracepoint 1
#0 vfs_read (file=0xffff880070bb6100,
buf=0x31cb8f0 "$2aa6178136313733#331bb700088ffff481fe4450188ffff002", '0' <repeats 13 times>, "f0b81c03000000000061bb700088ffff781fe4450188ffff301fe4450188ffff606944030000000058f19a010288ffff01", '0' <repeats 14 times>, "4602", '0' <repeats 12 times>, "f0b81c0"..., count=8192, pos=0xffff880145e41f48) at /home/teawater/kernel2/linux/fs/read_write.c:365
365 {
(gdb) info reg

rax            0x0      0
rbx            0xffff880070bb6100       -131939504004864
rcx            0xffff880145e41f48       -131935927787704
rdx            0x2000   8192
rsi            0x31cb8f0        52214000
rdi            0xffff880070bb6100       -131939504004864
rbp            0xffff880145e41f78       0xffff880145e41f78
rsp            0xffff880145e41f30       0xffff880145e41f30
r8             0x3446960        54815072
r9             0xffff8802019af158       -131932778466984
r10            0x1      1
r11            0x246    582
r12            0x31cb8f0        52214000
r13            0x2000   8192
r14            0xa      10
r15            0xa      10
rip            0xffffffff8117a3d0       0xffffffff8117a3d0 <vfs_read>
eflags         0x286    [ PF SF IF ]
cs             0x10     16
ss             0x18     24
ds             *value not available*
es             *value not available*
fs             *value not available*
gs             *value not available*

Because this is a lite patch, so this patch doesn't support other functions of KGTP.

---
 arch/arm/include/asm/gtp.h  |   24 +
 arch/mips/include/asm/gtp.h |   56 ++
 arch/x86/include/asm/gtp.h  |   92 ++++
 kernel/Makefile             |    2
 kernel/gtp.c                |  892 ++++++++++++++++++++++++++++++++++++++++++++
 lib/Kconfig.debug           |   12
 6 files changed, 1078 insertions(+)
arch/arm/include/asm/gtp.h new file +24 -0
@@ -0,0 +1,24 @@
+#ifndef _ASM_ARM_GTP_H_
+#define _ASM_ARM_GTP_H_
+
+#define GTP_REG_ASCII_SIZE	336
+
+static inline void gtp_regs2ascii(struct pt_regs *regs, char *buf)
+{
+	int	i;
+
+	for (i = 0; i < 16; i++) {
+		sprintf(buf, "%08lx", (unsigned long) ntohl(regs->uregs[i]));
+		buf += 8;
+	}
+
+	/* f0-f7 fps */
+	memset(buf, '0', 200);
+	buf += 200;
+
+	sprintf(buf, "%08lx",
+		 (unsigned long) ntohl(regs->uregs[16]));
+	buf += 8;
+}
+
+#endif
arch/mips/include/asm/gtp.h new file +56 -0

56 lines not on this page · raw message

arch/x86/include/asm/gtp.h new file +92 -0

92 lines not on this page · raw message

kernel/Makefile +2 -0
@@ -108,6 +108,8 @@ obj-$(CONFIG_PADATA) += padata.o
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_JUMP_LABEL) += jump_label.o
 
+obj-$(CONFIG_GTP) += gtp.o
+
 $(obj)/configs.o: $(obj)/config_data.h
 
 # config_data.h contains the same information as ikconfig.h but gzipped.
kernel/gtp.c new file +892 -0

892 lines not on this page · raw message

lib/Kconfig.debug +12 -0
@@ -1307,6 +1307,18 @@ config ASYNC_RAID6_TEST
 
 	  If unsure, say N.
 
+config GTP
+	tristate "GDB tracepoint support"
+	depends on X86 || ARM || MIPS
+	select KPROBES
+	select DEBUG_FS
+	---help---
+	  KGTP is a realtime and lightweight Linux debugger and tracer.
+	  It makes Linux Kernel supply a GDB remote debug interface.
+	  Then GDB in current machine can debug and trace Linux through
+	  GDB tracepoint and some other functions without stopping the
+	  Linux Kernel.
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
#5 lore raw
Quoted 9 lines

I remove them from asm files, and add:
#ifndef ULONGEST
#define ULONGEST uint64_t
#endif
#ifndef CORE_ADDR
#define CORE_ADDR unsigned long
#endif
in gtp.c
Then if not need, the arch didn't define ULONGEST and CORE_ADDR for itself.

Which architecture needs it? Linux prefers to use "native" types.

Quoted 6 lines

For example ARM and MIPS have a lot of special reg that cannot be converted by a for loop.

After check the code the kgdb, I thought that good ways is use dbg_reg_def of kgdb to convert the reg to gdb rsp format. But use it directly will make kgtp depend on kgdb.

That's fine. Code reuse is good. Code duplication is bad.

Quoted 2 lines

What I thought is move this part of code out from kgdb, when kgdb or kgtp need, select it too. But I am not sure Jason is OK with that.

Just send a patch.

Quoted 11 lines
Quoted 10 lines

kernel/gtp.c line 171

Quoted 8 lines
kernel/gtp.c new file +7 -0
+     memcpy(&freg->regs, regs, sizeof(struct pt_regs));
+#ifdef CONFIG_X86_32
+     freg->regs.sp = (unsigned long)&regs->sp;
+#endif       /* CONFIG_X86_32 */
+#ifdef CONFIG_X86
+     freg->regs.ip -= 1;
+#endif       /* CONFIG_X86 */

What is that for? - 1?

Quoted 2 lines

That is because when kprobe, the ip of X86 point will have a offset with current ip.

But a kprobe is not necessarily one byte. e.g. a jumper probe is longer.

Anyways if that is really needed there should be some macros provided by kprobes to adjust IP. If it's not there it needs to be added.

Quoted 8 lines
Quoted 5 lines

kernel/gtp.c line 306

Quoted 3 lines
kernel/gtp.c new file +3 -0
+
+     if (gtp_start)
+             return -EBUSY;

This is in a lot of places. Can you put it somewhere more central?

Sorry I don't understand this part. Do you want I change all "struct
gtp_entry *tpe;" to "struct gtp_entry *tpe;"?

I mean the if (gtp_start) return -EBUSY check.

Quoted 10 lines
Quoted 7 lines

kernel/gtp.c line 598

Quoted 5 lines
kernel/gtp.c new file +4 -0
+     pr_devel("gtp_gdbrsp_QT: %s\n", pkg);
+
+     if (strcmp("init", pkg) == 0)
+             ret = gtp_gdbrsp_qtinit();

This if cascade should be probably a table walk

I cannot find the examle about it in the Kernel, could you give me a example?

struct cmd {
	char *name;
	int (*init)(void);
};
struct cmd cmds[] = {
	{ "init", gtp_xyz_init }
	...
	{} 
};

int i;
for (i = 0; cmds[i].name; i++)

	if (!strcmp(cmds[i].name, pkg))
		ret = cmds->init();
Quoted 12 lines
Quoted 1 line

Ok so what lock protects this buffer?

No. The gtp_frame_lock protects the vars that follow it:
static int gtp_frame_num;
static char *gtp_frame;
static char *gtp_frame_r_start;
static char *gtp_frame_w_start;
static char *gtp_frame_w_end;
static char *gtp_frame_r_cache;
static int gtp_frame_is_circular;
It protects them all.

Quoted 1 line

gtp_m_buffer is protected by gtp_rw_lock that I just add in new patch.

Then your comment was wrong/unclear?

Quoted 3 lines

OK. Add some introduce. checkpatch is OK with it.

You must be using an old version?

# check for Kconfig help text having a real description
# Only applies when adding the entry originally, after that we do not have
# sufficient context to determine whether it is indeed long enough.
...
        WARN("CONFIG_DESCRIPTION",
                             "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4);

I wonder how you avoided that.

-Andi

author
#6 lore raw

Hi Andi,

Thanks for your help.
Sorry for late so much time.

Quoted 11 lines · Andi Kleen
Quoted 9 lines

I remove them from asm files, and add:
#ifndef ULONGEST
#define ULONGEST uint64_t
#endif
#ifndef CORE_ADDR
#define CORE_ADDR unsigned long
#endif
in gtp.c
Then if not need, the arch didn't define ULONGEST and CORE_ADDR for itself.

Which architecture needs it? Linux prefers to use "native" types.

I removed all of ULONGEST and CORE_ADDR.

Quoted 8 lines
Quoted 7 lines

For example ARM and MIPS have a lot of special reg that cannot be converted by a for loop.

After check the code the kgdb, I thought that good ways is use dbg_reg_def of kgdb to convert the reg to gdb rsp format. But use it directly will make kgtp depend on kgdb.

Quoted 6 lines

That's fine. Code reuse is good. Code duplication is bad.

Quoted 2 lines

What I thought is move this part of code out from kgdb, when kgdb or kgtp need, select it too. But I am not sure Jason is OK with that.

Just send a patch.

I removed the GTP_REG_ASCII_SIZE and gtp_regs2ascii. Now, to convert pt_reg to gdb format, KGTP use:
pt_regs_to_gdb_regs(gdb_regs, &fr->regs); kgdb_mem2hex((char *)gdb_regs, gtp_rw_bufp, NUMREGBYTES);

Quoted 12 lines
Quoted 12 lines
Quoted 11 lines

Review

Quoted 9 lines
(quoted diff) +7 -0
+     memcpy(&freg->regs, regs, sizeof(struct pt_regs));
+#ifdef CONFIG_X86_32
+     freg->regs.sp = (unsigned long)&regs->sp;
+#endif       /* CONFIG_X86_32 */
+#ifdef CONFIG_X86
+     freg->regs.ip -= 1;
+#endif       /* CONFIG_X86 */

What is that for? - 1?

Quoted 7 lines
Quoted 2 lines

That is because when kprobe, the ip of X86 point will have a offset with current ip.

But a kprobe is not necessarily one byte. e.g. a jumper probe is longer.

Anyways if that is really needed there should be some macros provided by kprobes to adjust IP. If it's not there it needs to be added.

I changed this part to a function gtp_copy_and_adjuest_regs.

Quoted 34 lines
Quoted 8 lines
Quoted 5 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+
+     if (gtp_start)
+             return -EBUSY;

This is in a lot of places. Can you put it somewhere more central?

Sorry I don't understand this part. Do you want I change all "struct
gtp_entry *tpe;" to "struct gtp_entry *tpe;"?

I mean the if (gtp_start) return -EBUSY check.

Quoted 10 lines
Quoted 7 lines

Review

Quoted 5 lines
(quoted diff) +4 -0
+     pr_devel("gtp_gdbrsp_QT: %s\n", pkg);
+
+     if (strcmp("init", pkg) == 0)
+             ret = gtp_gdbrsp_qtinit();

This if cascade should be probably a table walk

I cannot find the examle about it in the Kernel, could you give me a example?

struct cmd {
        char *name;
        int (*init)(void);
};
struct cmd cmds[] = {
        { "init", gtp_xyz_init }
        ...
        {}
};
Quoted 5 lines

int i;
for (i = 0; cmds[i].name; i++)

        if (!strcmp(cmds[i].name, pkg))
                ret = cmds->init();

OK. I change gtp_gdbrsp_QT to this format and merge "return -EBUSY" to it together.

Quoted 13 lines
Quoted 13 lines
Quoted 2 lines

Ok so what lock protects this buffer?

No. The gtp_frame_lock protects the vars that follow it:

static int                    gtp_frame_num;
static char                   *gtp_frame;
static char                   *gtp_frame_r_start;
static char                   *gtp_frame_w_start;
static char                   *gtp_frame_w_end;
static char                   *gtp_frame_r_cache;
static int                    gtp_frame_is_circular;

It protects them all.

Quoted 3 lines
Quoted 1 line

gtp_m_buffer is protected by gtp_rw_lock that I just add in new patch.

Then your comment was wrong/unclear?

This comment is not OK. So I removed it.

Quoted 7 lines
Quoted 4 lines

OK. Add some introduce. checkpatch is OK with it.

You must be using an old version?

Quoted 8 lines
# check for Kconfig help text having a real description
# Only applies when adding the entry originally, after that we do not have
# sufficient context to determine whether it is indeed long enough.
...
        WARN("CONFIG_DESCRIPTION",
                             "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4);

I wonder how you avoided that.

I am not sure. I checked my checkpatch.py and it has check for description. My desciption is:
+config GTP
+ tristate "KGTP"
+ depends on X86
+ select KPROBES
+ select DEBUG_FS
+ select KGDB
+ ---help---

+  KGTP is a flexible, lightweight and realtime Linux (include
+  Android) debugger and tracer.
+  It makes Linux Kernel supply a GDB remote debug interface.
+  Then GDB in current machine or remote machine can debug and
+  trace Linux kernel and user space program through GDB tracepoint
+  and some other functions without stopping the Linux Kernel.
+  http://kgtp.googlecode.com/

I post a new version patch.
Please help me review it.

Thanks,
Hui

---

arch/arc/kernel/kgdb.c +1 -0
@@ -61,6 +61,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 	to_gdb_regs(gdb_regs, kernel_regs, (struct callee_regs *)
 		current->thread.callee_reg);
 }
+EXPORT_SYMBOL_GPL(pt_regs_to_gdb_regs);
 
 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
 {
arch/blackfin/kernel/kgdb.c +1 -0
@@ -73,6 +73,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 	gdb_regs[BFIN_EXTRA3] = 0;
 	gdb_regs[BFIN_IPEND] = regs->ipend;
 }
+EXPORT_SYMBOL_GPL(pt_regs_to_gdb_regs);
 
 /*
  * Extracts ebp, esp and eip values understandable by gdb from the values
arch/microblaze/kernel/kgdb.c +1 -0
@@ -64,6 +64,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 	__asm__ __volatile__ ("mfs %0, rtlbhi;" : "=r"(temp) : );
 	gdb_regs[GDB_RTLBHI] = temp;
 }
+EXPORT_SYMBOL_GPL(pt_regs_to_gdb_regs);
 
 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
arch/mn10300/kernel/kgdb.c +1 -0
@@ -66,6 +66,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 	gdb_regs[GDB_FR_DUMMY1]	= 0;
 	gdb_regs[GDB_FR_FS0]	= 0;
 }
+EXPORT_SYMBOL_GPL(pt_regs_to_gdb_regs);
 
 /*
  * Extracts kernel SP/PC values understandable by gdb from the values
arch/sparc/kernel/kgdb_32.c +1 -0
@@ -41,6 +41,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 	gdb_regs[GDB_FSR] = 0;
 	gdb_regs[GDB_CSR] = 0;
 }
+EXPORT_SYMBOL_GPL(pt_regs_to_gdb_regs);
 
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
arch/sparc/kernel/kgdb_64.c +1 -0
@@ -37,6 +37,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 	gdb_regs[GDB_FPRS] = 0;
 	gdb_regs[GDB_Y] = regs->y;
 }
+EXPORT_SYMBOL_GPL(pt_regs_to_gdb_regs);
 
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
arch/x86/include/asm/gtp.h new file +16 -0
@@ -0,0 +1,16 @@
+#ifndef _ASM_X86_GTP_H_
+#define _ASM_X86_GTP_H_
+
+static inline void gtp_copy_and_adjuest_regs(struct pt_regs *dest,
+					     struct pt_regs *src)
+{
+	memcpy(dest, src, sizeof(struct pt_regs));
+
+#ifdef CONFIG_X86_32
+	dest->sp = (unsigned long)&src->sp;
+#endif	/* CONFIG_X86_32 */
+
+	dest->ip -= 1;
+}
+
+#endif
kernel/Makefile +2 -0
@@ -93,6 +93,8 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_JUMP_LABEL) += jump_label.o
 obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
 
+obj-$(CONFIG_GTP) += gtp.o
+
 $(obj)/configs.o: $(obj)/config_data.h
 
 # config_data.h contains the same information as ikconfig.h but gzipped.
kernel/debug/gdbstub.c +2 -0
@@ -258,6 +258,7 @@ char *kgdb_mem2hex(char *mem, char *buf,
 
 	return buf;
 }
+EXPORT_SYMBOL_GPL(kgdb_mem2hex);
 
 /*
  * Convert the hex array pointed to by buf into binary to be placed in
@@ -349,6 +350,7 @@ void pt_regs_to_gdb_regs(unsigned long *
 		idx += dbg_reg_def[i].size;
 	}
 }
+EXPORT_SYMBOL_GPL(pt_regs_to_gdb_regs);
 
 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
kernel/gtp.c new file +876 -0

876 lines not on this page · raw message

lib/Kconfig.debug +15 -0
@@ -1578,6 +1578,21 @@ config DMA_API_DEBUG
 	  This option causes a performance degredation.  Use only if you want
 	  to debug device drivers. If unsure, say N.
 
+config GTP
+	tristate "KGTP"
+	depends on X86
+	select KPROBES
+	select DEBUG_FS
+	select KGDB
+	---help---
+	  KGTP is a flexible, lightweight and realtime Linux (include
+	  Android) debugger and tracer.
+	  It makes Linux Kernel supply a GDB remote debug interface.
+	  Then GDB in current machine or remote machine can debug and
+	  trace Linux kernel and user space program through GDB tracepoint
+	  and some other functions without stopping the Linux Kernel.
+	  http://kgtp.googlecode.com/
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"