+++ /dev/null
-Subject: [PATCH] add syslog printing to xmon debugger.
-From: Linas Vepstas <linas@austin.ibm.com>
-
-
-This patch 'dmesg'/printk log buffer printing to xmon. I find this
-useful because crashes are almost always preceeded by interesting
-printk's. This patch is simple & straightforward, except for one
-possibly controversial aspect: it embeds a small snippet in
-kernel/printk.c to return the location of the syslog. This is
-needed because kallsyms and even CONFIG_KALLSYMS_ALL is not enough
-to reveal the location of log_buf. This code is about 90%
-cut-n-paste of earlier code from Keith Owens.
-
-Signed-off-by: Olaf Hering <olh@suse.de>
-
- arch/powerpc/xmon/xmon.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++
- kernel/printk.c | 15 ++++++++++++
- 2 files changed, 72 insertions(+)
-
---- a/arch/powerpc/xmon/xmon.c
-+++ b/arch/powerpc/xmon/xmon.c
-@@ -136,6 +136,7 @@ static struct bpt *in_breakpoint_table(u
- static int do_step(struct pt_regs *);
- static void bpt_cmds(void);
- static void cacheflush(void);
-+static void xmon_show_dmesg(void);
- static int cpu_cmd(void);
- static void csum(void);
- static void bootcmds(void);
-@@ -194,6 +195,7 @@ Commands:\n\
- #endif
- "\
- C checksum\n\
-+ D show dmesg (printk) buffer\n\
- d dump bytes\n\
- di dump instructions\n\
- df dump float values\n\
-@@ -808,6 +810,9 @@ cmds(struct pt_regs *excp)
- case 'd':
- dump();
- break;
-+ case 'D':
-+ xmon_show_dmesg();
-+ break;
- case 'l':
- symbol_lookup();
- break;
-@@ -2522,6 +2527,58 @@ static void xmon_print_symbol(unsigned l
- printf("%s", after);
- }
-
-+extern void debugger_syslog_data(char *syslog_data[4]);
-+#define SYSLOG_WRAP(p) if (p < syslog_data[0]) p = syslog_data[1]-1; \
-+ else if (p >= syslog_data[1]) p = syslog_data[0];
-+
-+static void xmon_show_dmesg(void)
-+{
-+ char *syslog_data[4], *start, *end, c;
-+ int logsize;
-+
-+ /* syslog_data[0,1] physical start, end+1.
-+ * syslog_data[2,3] logical start, end+1.
-+ */
-+ debugger_syslog_data(syslog_data);
-+ if (syslog_data[2] == syslog_data[3])
-+ return;
-+ logsize = syslog_data[1] - syslog_data[0];
-+ start = syslog_data[0] + (syslog_data[2] - syslog_data[0]) % logsize;
-+ end = syslog_data[0] + (syslog_data[3] - syslog_data[0]) % logsize;
-+
-+ /* Do a line at a time (max 200 chars) to reduce overhead */
-+ c = '\0';
-+ while(1) {
-+ char *p;
-+ int chars = 0;
-+ if (!*start) {
-+ while (!*start) {
-+ ++start;
-+ SYSLOG_WRAP(start);
-+ if (start == end)
-+ break;
-+ }
-+ if (start == end)
-+ break;
-+ }
-+ p = start;
-+ while (*start && chars < 200) {
-+ c = *start;
-+ ++chars;
-+ ++start;
-+ SYSLOG_WRAP(start);
-+ if (start == end || c == '\n')
-+ break;
-+ }
-+ if (chars)
-+ printf("%.*s", chars, p);
-+ if (start == end)
-+ break;
-+ }
-+ if (c != '\n')
-+ printf("\n");
-+}
-+
- #ifdef CONFIG_PPC64
- static void dump_slb(void)
- {
---- a/kernel/printk.c
-+++ b/kernel/printk.c
-@@ -426,6 +426,21 @@ asmlinkage long sys_syslog(int type, cha
- return do_syslog(type, buf, len);
- }
-
-+#ifdef CONFIG_DEBUG_KERNEL
-+/* Its very handy to be able to view the syslog buffer during debug.
-+ * But do_syslog() uses locks so it cannot be used during debugging.
-+ * Instead, provide the start and end of the physical and logical logs.
-+ * This is equivalent to do_syslog(3).
-+ */
-+void debugger_syslog_data(char *syslog_data[4])
-+{
-+ syslog_data[0] = log_buf;
-+ syslog_data[1] = log_buf + log_buf_len;
-+ syslog_data[2] = log_buf + log_end - (logged_chars < log_buf_len ? logged_chars : log_buf_len);
-+ syslog_data[3] = log_buf + log_end;
-+}
-+#endif /* CONFIG_DEBUG_KERNEL */
-+
- /*
- * Call the console drivers on a range of log_buf
- */