KGDB/KDB fixes and cleanups
Cleanups Clean up compile warnings in kgdboc.c and x86/kernel/kgdb.c Add module event hooks for simplified debugging with gdb Fixes Fix kdb to stop paging with 'q' on bta and dmesg Fix for data that scrolls off the vga console due to line wrapping when using the kdb pager New The debug core registers for kernel module events which allows a kernel aware gdb to automatically load symbols and break on entry to a kernel module Allow kgdboc=kdb to setup kdb on the vga console -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJQeB8KAAoJEIciOldedpOjpbIP/j+LXEkzXKKfi/3m79VQ87DB 5iUmTS84t84pomHamXX175AC0gA/2mC0FbbcHpqjlhxF4awXcviCNIiTdtSOTbbu G102naLHY8i77X+XbHuN2utJeaRLw8rsfMMZGmjJnjfpc4LtsaH0YTkUzbt3qvba N6/QvknadzIrmoCJvHipdOdsSmL0YmTS22+koG4es9B5jvOqVH/W7jZs1qRlVw96 VxG5Psx4LPB+RI+ZwF1WwbGxbtqKGwkVvkcGG1XIW7FQojHmjw+vUERQCjoFueJ5 NkKfus98j85/+MvSTkWx3L1K46MHMCFbtJs9RWftJ8GtoNNnm7GDxasoIG2bJKyG HFD3IGPuKAokE/equF3eGTRHeEM0IUGwT3EnBqdKd73zud27WsHaSqC/1CPR+74v ojLQ2ft1QF+pEkGrhRTdQpLyVnvEmxu8q+j9z9n/HlGEVv8kZ6LGxDPjWB+um/Yi Cs0XAryYrL5gE5O+Vwna61luughtIYJwR7+DeVxnQYJ43x/0MtN/SoURnwvrCTEo 9FeoMgZm1nLh6EW29ahIT/hMu4f0sM91Kiwrmc/zEWZgoB++wo1n470qQmUUrOx4 CPD7zdmDrf6YxDG2QTHjCtVErO4aJ5zN4Dq0+YyodV545SZVn3t4qBDTVvKhq4Y6 NIhZAxrv5RKABwtLcP9E =uf0L -----END PGP SIGNATURE----- Merge tag 'for_linus-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb Pull KGDB/KDB fixes and cleanups from Jason Wessel: "Cleanups - Clean up compile warnings in kgdboc.c and x86/kernel/kgdb.c - Add module event hooks for simplified debugging with gdb Fixes - Fix kdb to stop paging with 'q' on bta and dmesg - Fix for data that scrolls off the vga console due to line wrapping when using the kdb pager New - The debug core registers for kernel module events which allows a kernel aware gdb to automatically load symbols and break on entry to a kernel module - Allow kgdboc=kdb to setup kdb on the vga console" * tag 'for_linus-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb: tty/console: fix warnings in drivers/tty/serial/kgdboc.c kdb,vt_console: Fix missed data due to pager overruns kdb: Fix dmesg/bta scroll to quit with 'q' kgdboc: Accept either kbd or kdb to activate the vga + keyboard kdb shell kgdb,x86: fix warning about unused variable mips,kgdb: fix recursive page fault with CONFIG_KPROBES kgdb: Add module event hooks
This commit is contained in:
commit
6c536a17fa
|
@ -283,6 +283,15 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
|
|||
struct pt_regs *regs = args->regs;
|
||||
int trap = (regs->cp0_cause & 0x7c) >> 2;
|
||||
|
||||
#ifdef CONFIG_KPROBES
|
||||
/*
|
||||
* Return immediately if the kprobes fault notifier has set
|
||||
* DIE_PAGE_FAULT.
|
||||
*/
|
||||
if (cmd == DIE_PAGE_FAULT)
|
||||
return NOTIFY_DONE;
|
||||
#endif /* CONFIG_KPROBES */
|
||||
|
||||
/* Userspace events, ignore. */
|
||||
if (user_mode(regs))
|
||||
return NOTIFY_DONE;
|
||||
|
|
|
@ -746,7 +746,9 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
|
|||
int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
|
||||
{
|
||||
int err;
|
||||
#ifdef CONFIG_DEBUG_RODATA
|
||||
char opc[BREAK_INSTR_SIZE];
|
||||
#endif /* CONFIG_DEBUG_RODATA */
|
||||
|
||||
bpt->type = BP_BREAKPOINT;
|
||||
err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
|
||||
|
|
|
@ -97,7 +97,8 @@ static void kgdboc_restore_input(void)
|
|||
|
||||
static int kgdboc_register_kbd(char **cptr)
|
||||
{
|
||||
if (strncmp(*cptr, "kbd", 3) == 0) {
|
||||
if (strncmp(*cptr, "kbd", 3) == 0 ||
|
||||
strncmp(*cptr, "kdb", 3) == 0) {
|
||||
if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
|
||||
kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
|
||||
kdb_poll_idx++;
|
||||
|
|
|
@ -3442,6 +3442,19 @@ int con_debug_enter(struct vc_data *vc)
|
|||
kdb_set(2, setargs);
|
||||
}
|
||||
}
|
||||
if (vc->vc_cols < 999) {
|
||||
int colcount;
|
||||
char cols[4];
|
||||
const char *setargs[3] = {
|
||||
"set",
|
||||
"COLUMNS",
|
||||
cols,
|
||||
};
|
||||
if (kdbgetintenv(setargs[0], &colcount)) {
|
||||
snprintf(cols, 4, "%i", vc->vc_cols);
|
||||
kdb_set(2, setargs);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_KGDB_KDB */
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -83,8 +83,14 @@ void give_up_console(const struct consw *sw);
|
|||
int con_debug_enter(struct vc_data *vc);
|
||||
int con_debug_leave(void);
|
||||
#else
|
||||
#define con_debug_enter(vc) (0)
|
||||
#define con_debug_leave() (0)
|
||||
static inline int con_debug_enter(struct vc_data *vc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int con_debug_leave(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* scroll */
|
||||
|
|
|
@ -696,6 +696,22 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* GDB places a breakpoint at this function to know dynamically
|
||||
* loaded objects. It's not defined static so that only one instance with this
|
||||
* name exists in the kernel.
|
||||
*/
|
||||
|
||||
static int module_event(struct notifier_block *self, unsigned long val,
|
||||
void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block dbg_module_load_nb = {
|
||||
.notifier_call = module_event,
|
||||
};
|
||||
|
||||
int kgdb_nmicallback(int cpu, void *regs)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
|
@ -824,6 +840,7 @@ static void kgdb_register_callbacks(void)
|
|||
kgdb_arch_init();
|
||||
if (!dbg_is_early)
|
||||
kgdb_arch_late();
|
||||
register_module_notifier(&dbg_module_load_nb);
|
||||
register_reboot_notifier(&dbg_reboot_notifier);
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&kgdb_panic_event_nb);
|
||||
|
@ -847,6 +864,7 @@ static void kgdb_unregister_callbacks(void)
|
|||
if (kgdb_io_module_registered) {
|
||||
kgdb_io_module_registered = 0;
|
||||
unregister_reboot_notifier(&dbg_reboot_notifier);
|
||||
unregister_module_notifier(&dbg_module_load_nb);
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&kgdb_panic_event_nb);
|
||||
kgdb_arch_exit();
|
||||
|
|
|
@ -129,6 +129,8 @@ kdb_bt(int argc, const char **argv)
|
|||
}
|
||||
/* Now the inactive tasks */
|
||||
kdb_do_each_thread(g, p) {
|
||||
if (KDB_FLAG(CMD_INTERRUPT))
|
||||
return 0;
|
||||
if (task_curr(p))
|
||||
continue;
|
||||
if (kdb_bt1(p, mask, argcount, btaprompt))
|
||||
|
|
|
@ -552,6 +552,7 @@ int vkdb_printf(const char *fmt, va_list ap)
|
|||
{
|
||||
int diag;
|
||||
int linecount;
|
||||
int colcount;
|
||||
int logging, saved_loglevel = 0;
|
||||
int saved_trap_printk;
|
||||
int got_printf_lock = 0;
|
||||
|
@ -584,6 +585,10 @@ int vkdb_printf(const char *fmt, va_list ap)
|
|||
if (diag || linecount <= 1)
|
||||
linecount = 24;
|
||||
|
||||
diag = kdbgetintenv("COLUMNS", &colcount);
|
||||
if (diag || colcount <= 1)
|
||||
colcount = 80;
|
||||
|
||||
diag = kdbgetintenv("LOGGING", &logging);
|
||||
if (diag)
|
||||
logging = 0;
|
||||
|
@ -690,7 +695,7 @@ int vkdb_printf(const char *fmt, va_list ap)
|
|||
gdbstub_msg_write(kdb_buffer, retlen);
|
||||
} else {
|
||||
if (dbg_io_ops && !dbg_io_ops->is_console) {
|
||||
len = strlen(kdb_buffer);
|
||||
len = retlen;
|
||||
cp = kdb_buffer;
|
||||
while (len--) {
|
||||
dbg_io_ops->write_char(*cp);
|
||||
|
@ -709,11 +714,29 @@ int vkdb_printf(const char *fmt, va_list ap)
|
|||
printk(KERN_INFO "%s", kdb_buffer);
|
||||
}
|
||||
|
||||
if (KDB_STATE(PAGER) && strchr(kdb_buffer, '\n'))
|
||||
kdb_nextline++;
|
||||
if (KDB_STATE(PAGER)) {
|
||||
/*
|
||||
* Check printed string to decide how to bump the
|
||||
* kdb_nextline to control when the more prompt should
|
||||
* show up.
|
||||
*/
|
||||
int got = 0;
|
||||
len = retlen;
|
||||
while (len--) {
|
||||
if (kdb_buffer[len] == '\n') {
|
||||
kdb_nextline++;
|
||||
got = 0;
|
||||
} else if (kdb_buffer[len] == '\r') {
|
||||
got = 0;
|
||||
} else {
|
||||
got++;
|
||||
}
|
||||
}
|
||||
kdb_nextline += got / (colcount + 1);
|
||||
}
|
||||
|
||||
/* check for having reached the LINES number of printed lines */
|
||||
if (kdb_nextline == linecount) {
|
||||
if (kdb_nextline >= linecount) {
|
||||
char buf1[16] = "";
|
||||
|
||||
/* Watch out for recursion here. Any routine that calls
|
||||
|
@ -765,7 +788,7 @@ int vkdb_printf(const char *fmt, va_list ap)
|
|||
kdb_grepping_flag = 0;
|
||||
kdb_printf("\n");
|
||||
} else if (buf1[0] == ' ') {
|
||||
kdb_printf("\n");
|
||||
kdb_printf("\r");
|
||||
suspend_grep = 1; /* for this recursion */
|
||||
} else if (buf1[0] == '\n') {
|
||||
kdb_nextline = linecount - 1;
|
||||
|
|
|
@ -2101,6 +2101,8 @@ static int kdb_dmesg(int argc, const char **argv)
|
|||
}
|
||||
if (!lines--)
|
||||
break;
|
||||
if (KDB_FLAG(CMD_INTERRUPT))
|
||||
return 0;
|
||||
|
||||
kdb_printf("%.*s\n", (int)len - 1, buf);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user