1 Subject: [PATCH] add syslog printing to xmon debugger.
2 From: Linas Vepstas <linas@austin.ibm.com>
5 This patch 'dmesg'/printk log buffer printing to xmon. I find this
6 useful because crashes are almost always preceeded by interesting
7 printk's. This patch is simple & straightforward, except for one
8 possibly controversial aspect: it embeds a small snippet in
9 kernel/printk.c to return the location of the syslog. This is
10 needed because kallsyms and even CONFIG_KALLSYMS_ALL is not enough
11 to reveal the location of log_buf. This code is about 90%
12 cut-n-paste of earlier code from Keith Owens.
14 Signed-off-by: Olaf Hering <olh@suse.de>
16 arch/powerpc/xmon/xmon.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++
17 kernel/printk.c | 15 ++++++++++++
18 2 files changed, 72 insertions(+)
20 --- a/arch/powerpc/xmon/xmon.c
21 +++ b/arch/powerpc/xmon/xmon.c
22 @@ -136,6 +136,7 @@ static struct bpt *in_breakpoint_table(u
23 static int do_step(struct pt_regs *);
24 static void bpt_cmds(void);
25 static void cacheflush(void);
26 +static void xmon_show_dmesg(void);
27 static int cpu_cmd(void);
28 static void csum(void);
29 static void bootcmds(void);
30 @@ -194,6 +195,7 @@ Commands:\n\
34 + D show dmesg (printk) buffer\n\
36 di dump instructions\n\
37 df dump float values\n\
38 @@ -808,6 +810,9 @@ cmds(struct pt_regs *excp)
48 @@ -2522,6 +2527,58 @@ static void xmon_print_symbol(unsigned l
52 +extern void debugger_syslog_data(char *syslog_data[4]);
53 +#define SYSLOG_WRAP(p) if (p < syslog_data[0]) p = syslog_data[1]-1; \
54 + else if (p >= syslog_data[1]) p = syslog_data[0];
56 +static void xmon_show_dmesg(void)
58 + char *syslog_data[4], *start, *end, c;
61 + /* syslog_data[0,1] physical start, end+1.
62 + * syslog_data[2,3] logical start, end+1.
64 + debugger_syslog_data(syslog_data);
65 + if (syslog_data[2] == syslog_data[3])
67 + logsize = syslog_data[1] - syslog_data[0];
68 + start = syslog_data[0] + (syslog_data[2] - syslog_data[0]) % logsize;
69 + end = syslog_data[0] + (syslog_data[3] - syslog_data[0]) % logsize;
71 + /* Do a line at a time (max 200 chars) to reduce overhead */
87 + while (*start && chars < 200) {
92 + if (start == end || c == '\n')
96 + printf("%.*s", chars, p);
105 static void dump_slb(void)
107 --- a/kernel/printk.c
108 +++ b/kernel/printk.c
109 @@ -426,6 +426,21 @@ asmlinkage long sys_syslog(int type, cha
110 return do_syslog(type, buf, len);
113 +#ifdef CONFIG_DEBUG_KERNEL
114 +/* Its very handy to be able to view the syslog buffer during debug.
115 + * But do_syslog() uses locks so it cannot be used during debugging.
116 + * Instead, provide the start and end of the physical and logical logs.
117 + * This is equivalent to do_syslog(3).
119 +void debugger_syslog_data(char *syslog_data[4])
121 + syslog_data[0] = log_buf;
122 + syslog_data[1] = log_buf + log_buf_len;
123 + syslog_data[2] = log_buf + log_end - (logged_chars < log_buf_len ? logged_chars : log_buf_len);
124 + syslog_data[3] = log_buf + log_end;
126 +#endif /* CONFIG_DEBUG_KERNEL */
129 * Call the console drivers on a range of log_buf