Skip to content

Commit 6c536a1

Browse files
committed
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
2 parents ba8a3d6 + f2f0945 commit 6c536a1

9 files changed

Lines changed: 84 additions & 8 deletions

File tree

arch/mips/kernel/kgdb.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,15 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
283283
struct pt_regs *regs = args->regs;
284284
int trap = (regs->cp0_cause & 0x7c) >> 2;
285285

286+
#ifdef CONFIG_KPROBES
287+
/*
288+
* Return immediately if the kprobes fault notifier has set
289+
* DIE_PAGE_FAULT.
290+
*/
291+
if (cmd == DIE_PAGE_FAULT)
292+
return NOTIFY_DONE;
293+
#endif /* CONFIG_KPROBES */
294+
286295
/* Userspace events, ignore. */
287296
if (user_mode(regs))
288297
return NOTIFY_DONE;

arch/x86/kernel/kgdb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,9 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
746746
int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
747747
{
748748
int err;
749+
#ifdef CONFIG_DEBUG_RODATA
749750
char opc[BREAK_INSTR_SIZE];
751+
#endif /* CONFIG_DEBUG_RODATA */
750752

751753
bpt->type = BP_BREAKPOINT;
752754
err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,

drivers/tty/serial/kgdboc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ static void kgdboc_restore_input(void)
9797

9898
static int kgdboc_register_kbd(char **cptr)
9999
{
100-
if (strncmp(*cptr, "kbd", 3) == 0) {
100+
if (strncmp(*cptr, "kbd", 3) == 0 ||
101+
strncmp(*cptr, "kdb", 3) == 0) {
101102
if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
102103
kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
103104
kdb_poll_idx++;

drivers/tty/vt/vt.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3442,6 +3442,19 @@ int con_debug_enter(struct vc_data *vc)
34423442
kdb_set(2, setargs);
34433443
}
34443444
}
3445+
if (vc->vc_cols < 999) {
3446+
int colcount;
3447+
char cols[4];
3448+
const char *setargs[3] = {
3449+
"set",
3450+
"COLUMNS",
3451+
cols,
3452+
};
3453+
if (kdbgetintenv(setargs[0], &colcount)) {
3454+
snprintf(cols, 4, "%i", vc->vc_cols);
3455+
kdb_set(2, setargs);
3456+
}
3457+
}
34453458
#endif /* CONFIG_KGDB_KDB */
34463459
return ret;
34473460
}

include/linux/console.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,14 @@ void give_up_console(const struct consw *sw);
8383
int con_debug_enter(struct vc_data *vc);
8484
int con_debug_leave(void);
8585
#else
86-
#define con_debug_enter(vc) (0)
87-
#define con_debug_leave() (0)
86+
static inline int con_debug_enter(struct vc_data *vc)
87+
{
88+
return 0;
89+
}
90+
static inline int con_debug_leave(void)
91+
{
92+
return 0;
93+
}
8894
#endif
8995

9096
/* scroll */

kernel/debug/debug_core.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,22 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
696696
return ret;
697697
}
698698

699+
/*
700+
* GDB places a breakpoint at this function to know dynamically
701+
* loaded objects. It's not defined static so that only one instance with this
702+
* name exists in the kernel.
703+
*/
704+
705+
static int module_event(struct notifier_block *self, unsigned long val,
706+
void *data)
707+
{
708+
return 0;
709+
}
710+
711+
static struct notifier_block dbg_module_load_nb = {
712+
.notifier_call = module_event,
713+
};
714+
699715
int kgdb_nmicallback(int cpu, void *regs)
700716
{
701717
#ifdef CONFIG_SMP
@@ -824,6 +840,7 @@ static void kgdb_register_callbacks(void)
824840
kgdb_arch_init();
825841
if (!dbg_is_early)
826842
kgdb_arch_late();
843+
register_module_notifier(&dbg_module_load_nb);
827844
register_reboot_notifier(&dbg_reboot_notifier);
828845
atomic_notifier_chain_register(&panic_notifier_list,
829846
&kgdb_panic_event_nb);
@@ -847,6 +864,7 @@ static void kgdb_unregister_callbacks(void)
847864
if (kgdb_io_module_registered) {
848865
kgdb_io_module_registered = 0;
849866
unregister_reboot_notifier(&dbg_reboot_notifier);
867+
unregister_module_notifier(&dbg_module_load_nb);
850868
atomic_notifier_chain_unregister(&panic_notifier_list,
851869
&kgdb_panic_event_nb);
852870
kgdb_arch_exit();

kernel/debug/kdb/kdb_bt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ kdb_bt(int argc, const char **argv)
129129
}
130130
/* Now the inactive tasks */
131131
kdb_do_each_thread(g, p) {
132+
if (KDB_FLAG(CMD_INTERRUPT))
133+
return 0;
132134
if (task_curr(p))
133135
continue;
134136
if (kdb_bt1(p, mask, argcount, btaprompt))

kernel/debug/kdb/kdb_io.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ int vkdb_printf(const char *fmt, va_list ap)
552552
{
553553
int diag;
554554
int linecount;
555+
int colcount;
555556
int logging, saved_loglevel = 0;
556557
int saved_trap_printk;
557558
int got_printf_lock = 0;
@@ -584,6 +585,10 @@ int vkdb_printf(const char *fmt, va_list ap)
584585
if (diag || linecount <= 1)
585586
linecount = 24;
586587

588+
diag = kdbgetintenv("COLUMNS", &colcount);
589+
if (diag || colcount <= 1)
590+
colcount = 80;
591+
587592
diag = kdbgetintenv("LOGGING", &logging);
588593
if (diag)
589594
logging = 0;
@@ -690,7 +695,7 @@ int vkdb_printf(const char *fmt, va_list ap)
690695
gdbstub_msg_write(kdb_buffer, retlen);
691696
} else {
692697
if (dbg_io_ops && !dbg_io_ops->is_console) {
693-
len = strlen(kdb_buffer);
698+
len = retlen;
694699
cp = kdb_buffer;
695700
while (len--) {
696701
dbg_io_ops->write_char(*cp);
@@ -709,11 +714,29 @@ int vkdb_printf(const char *fmt, va_list ap)
709714
printk(KERN_INFO "%s", kdb_buffer);
710715
}
711716

712-
if (KDB_STATE(PAGER) && strchr(kdb_buffer, '\n'))
713-
kdb_nextline++;
717+
if (KDB_STATE(PAGER)) {
718+
/*
719+
* Check printed string to decide how to bump the
720+
* kdb_nextline to control when the more prompt should
721+
* show up.
722+
*/
723+
int got = 0;
724+
len = retlen;
725+
while (len--) {
726+
if (kdb_buffer[len] == '\n') {
727+
kdb_nextline++;
728+
got = 0;
729+
} else if (kdb_buffer[len] == '\r') {
730+
got = 0;
731+
} else {
732+
got++;
733+
}
734+
}
735+
kdb_nextline += got / (colcount + 1);
736+
}
714737

715738
/* check for having reached the LINES number of printed lines */
716-
if (kdb_nextline == linecount) {
739+
if (kdb_nextline >= linecount) {
717740
char buf1[16] = "";
718741

719742
/* Watch out for recursion here. Any routine that calls
@@ -765,7 +788,7 @@ int vkdb_printf(const char *fmt, va_list ap)
765788
kdb_grepping_flag = 0;
766789
kdb_printf("\n");
767790
} else if (buf1[0] == ' ') {
768-
kdb_printf("\n");
791+
kdb_printf("\r");
769792
suspend_grep = 1; /* for this recursion */
770793
} else if (buf1[0] == '\n') {
771794
kdb_nextline = linecount - 1;

kernel/debug/kdb/kdb_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,6 +2101,8 @@ static int kdb_dmesg(int argc, const char **argv)
21012101
}
21022102
if (!lines--)
21032103
break;
2104+
if (KDB_FLAG(CMD_INTERRUPT))
2105+
return 0;
21042106

21052107
kdb_printf("%.*s\n", (int)len - 1, buf);
21062108
}

0 commit comments

Comments
 (0)