aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2010-05-20 22:04:24 -0400
committerJason Wessel <jason.wessel@windriver.com>2010-05-20 22:04:24 -0400
commita0de055cf61338549b13079a5677ef2e1b6472ef (patch)
tree6191bbd6b3d567350b12ad973356995dbeffeeb3 /kernel
parent6d45a1aed34b0cd7b298967eb9cb72b77afcb33b (diff)
kgdb: gdb "monitor" -> kdb passthrough
One of the driving forces behind integrating another front end (kdb) to the debug core is to allow front end commands to be accessible via gdb's monitor command. It is true that you could write gdb macros to get certain data, but you may want to just use gdb to access the commands that are available in the kdb front end. This patch implements the Rcmd gdb stub packet. In gdb you access this with the "monitor" command. For instance you could type "monitor help", "monitor lsmod" or "monitor ps A" etc... There is no error checking or command restrictions on what you can and cannot access at this point. Doing something like trying to set breakpoints with the monitor command is going to cause nothing but problems. Perhaps in the future only the commands that are actually known to work with the gdb monitor command will be available. Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/debug/debug_core.c2
-rw-r--r--kernel/debug/debug_core.h2
-rw-r--r--kernel/debug/gdbstub.c22
-rw-r--r--kernel/debug/kdb/kdb_io.c13
-rw-r--r--kernel/debug/kdb/kdb_private.h1
5 files changed, 34 insertions, 6 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 1d71df66f3fa..1aed37b4c564 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -82,7 +82,7 @@ static int kgdb_use_con;
82int dbg_switch_cpu; 82int dbg_switch_cpu;
83 83
84/* Use kdb or gdbserver mode */ 84/* Use kdb or gdbserver mode */
85static int dbg_kdb_mode = 1; 85int dbg_kdb_mode = 1;
86 86
87static int __init opt_kgdb_con(char *str) 87static int __init opt_kgdb_con(char *str)
88{ 88{
diff --git a/kernel/debug/debug_core.h b/kernel/debug/debug_core.h
index 44cf3de8cf9e..c5d753d80f67 100644
--- a/kernel/debug/debug_core.h
+++ b/kernel/debug/debug_core.h
@@ -66,9 +66,11 @@ extern void gdbstub_msg_write(const char *s, int len);
66 66
67/* gdbstub functions used for kdb <-> gdbstub transition */ 67/* gdbstub functions used for kdb <-> gdbstub transition */
68extern int gdbstub_state(struct kgdb_state *ks, char *cmd); 68extern int gdbstub_state(struct kgdb_state *ks, char *cmd);
69extern int dbg_kdb_mode;
69 70
70#ifdef CONFIG_KGDB_KDB 71#ifdef CONFIG_KGDB_KDB
71extern int kdb_stub(struct kgdb_state *ks); 72extern int kdb_stub(struct kgdb_state *ks);
73extern int kdb_parse(const char *cmdstr);
72#else /* ! CONFIG_KGDB_KDB */ 74#else /* ! CONFIG_KGDB_KDB */
73static inline int kdb_stub(struct kgdb_state *ks) 75static inline int kdb_stub(struct kgdb_state *ks)
74{ 76{
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c
index 3c000490a7dd..4b17b3269525 100644
--- a/kernel/debug/gdbstub.c
+++ b/kernel/debug/gdbstub.c
@@ -201,6 +201,9 @@ void gdbstub_msg_write(const char *s, int len)
201 int wcount; 201 int wcount;
202 int i; 202 int i;
203 203
204 if (len == 0)
205 len = strlen(s);
206
204 /* 'O'utput */ 207 /* 'O'utput */
205 gdbmsgbuf[0] = 'O'; 208 gdbmsgbuf[0] = 'O';
206 209
@@ -685,6 +688,25 @@ static void gdb_cmd_query(struct kgdb_state *ks)
685 kgdb_mem2hex(tmpstr, remcom_out_buffer, strlen(tmpstr)); 688 kgdb_mem2hex(tmpstr, remcom_out_buffer, strlen(tmpstr));
686 } 689 }
687 break; 690 break;
691#ifdef CONFIG_KGDB_KDB
692 case 'R':
693 if (strncmp(remcom_in_buffer, "qRcmd,", 6) == 0) {
694 int len = strlen(remcom_in_buffer + 6);
695
696 if ((len % 2) != 0) {
697 strcpy(remcom_out_buffer, "E01");
698 break;
699 }
700 kgdb_hex2mem(remcom_in_buffer + 6,
701 remcom_out_buffer, len);
702 len = len / 2;
703 remcom_out_buffer[len++] = 0;
704
705 kdb_parse(remcom_out_buffer);
706 strcpy(remcom_out_buffer, "OK");
707 }
708 break;
709#endif
688 } 710 }
689} 711}
690 712
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
index 9e3cec7a925c..8339b291e8bc 100644
--- a/kernel/debug/kdb/kdb_io.c
+++ b/kernel/debug/kdb/kdb_io.c
@@ -21,6 +21,7 @@
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/nmi.h> 22#include <linux/nmi.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/kgdb.h>
24#include <linux/kdb.h> 25#include <linux/kdb.h>
25#include <linux/kallsyms.h> 26#include <linux/kallsyms.h>
26#include "kdb_private.h" 27#include "kdb_private.h"
@@ -669,10 +670,14 @@ kdb_printit:
669 * Write to all consoles. 670 * Write to all consoles.
670 */ 671 */
671 retlen = strlen(kdb_buffer); 672 retlen = strlen(kdb_buffer);
672 while (c) { 673 if (!dbg_kdb_mode && kgdb_connected) {
673 c->write(c, kdb_buffer, retlen); 674 gdbstub_msg_write(kdb_buffer, retlen);
674 touch_nmi_watchdog(); 675 } else {
675 c = c->next; 676 while (c) {
677 c->write(c, kdb_buffer, retlen);
678 touch_nmi_watchdog();
679 c = c->next;
680 }
676 } 681 }
677 if (logging) { 682 if (logging) {
678 saved_loglevel = console_loglevel; 683 saved_loglevel = console_loglevel;
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h
index 69ed2eff3fea..97d3ba69775d 100644
--- a/kernel/debug/kdb/kdb_private.h
+++ b/kernel/debug/kdb/kdb_private.h
@@ -254,7 +254,6 @@ extern unsigned long kdb_task_state(const struct task_struct *p,
254 unsigned long mask); 254 unsigned long mask);
255extern void kdb_ps_suppressed(void); 255extern void kdb_ps_suppressed(void);
256extern void kdb_ps1(const struct task_struct *p); 256extern void kdb_ps1(const struct task_struct *p);
257extern int kdb_parse(const char *cmdstr);
258extern void kdb_print_nameval(const char *name, unsigned long val); 257extern void kdb_print_nameval(const char *name, unsigned long val);
259extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); 258extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info);
260extern void kdb_meminfo_proc_show(void); 259extern void kdb_meminfo_proc_show(void);