mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2026-08-02 08:30:48 +00:00
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 @@ out:
|
||||
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 @@ kdb_printit:
|
||||
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 @@ kdb_printit:
|
||||
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 @@ kdb_printit:
|
||||
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