--- linux-mm/arch/i386/Kconfig 2004-02-16 23:15:53.000000000 +0100 +++ clean-mm/arch/i386/Kconfig 2004-02-16 23:00:15.000000000 +0100 @@ -1267,6 +1267,23 @@ http://kgdb.sourceforge.net This is only useful for kernel hackers. If unsure, say N. +config KGDB_THREAD + bool "KGDB: Thread analysis" + depends on KGDB + help + With thread analysis enabled, gdb can talk to kgdb stub to list + threads and to get stack trace for a thread. This option also enables + some code which helps gdb get exact status of thread. Thread analysis + adds some overhead to schedule and down functions. You can disable + this option if you do not want to compromise on speed. + +config KGDB_CONSOLE + bool "KGDB: Console messages through gdb" + depends on KGDB + help + If you say Y here, console messages will appear through gdb. + Other consoles such as tty or ttyS will continue to work as usual. + config FRAME_POINTER bool "Compile the kernel with frame pointers" help --- linux-mm/arch/i386/kernel/entry.S 2004-02-17 23:23:55.000000000 +0100 +++ clean-mm/arch/i386/kernel/entry.S 2004-02-16 23:00:15.000000000 +0100 @@ -226,7 +226,7 @@ jz restore_all movl $PREEMPT_ACTIVE,TI_PRE_COUNT(%ebp) sti - call schedule + call user_schedule movl $0,TI_PRE_COUNT(%ebp) cli jmp need_resched @@ -308,7 +308,7 @@ testb $_TIF_NEED_RESCHED, %cl jz work_notifysig work_resched: - call schedule + call user_schedule cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret @@ -399,7 +399,17 @@ ALIGN common_interrupt: SAVE_ALL + movl %esp, %eax +/* Create a fake function call followed by a fake function prologue to fool + * gdb into believing that this is a normal function call. */ + pushl EIP(%eax) + +common_interrupt_1: + pushl %ebp + movl %esp, %ebp + pushl %eax call do_IRQ + addl $12, %esp jmp ret_from_intr #define BUILD_INTERRUPT(name, nr) \ @@ -606,6 +616,31 @@ pushl $do_spurious_interrupt_bug jmp error_code +#ifdef CONFIG_KGDB_THREAD +ENTRY(kern_schedule) + pushl %ebp + movl %esp, %ebp + pushl %ss + pushl %ebp + pushfl + pushl %cs + pushl 4(%ebp) + pushl %eax + pushl %es + pushl %ds + pushl %eax + pushl (%ebp) + pushl %edi + pushl %esi + pushl %edx + pushl %ecx + pushl %ebx + call kern_do_schedule + movl %ebp, %esp + pop %ebp + ret +#endif + .data ENTRY(sys_call_table) .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ --- linux-mm/arch/i386/kernel/irq.c 2004-02-17 23:23:55.000000000 +0100 +++ clean-mm/arch/i386/kernel/irq.c 2004-02-16 23:00:15.000000000 +0100 @@ -410,7 +410,7 @@ * SMP cross-CPU interrupts have their own specific * handlers). */ -asmlinkage unsigned int do_IRQ(struct pt_regs regs) +asmlinkage unsigned int do_IRQ(struct pt_regs *regs) { /* * We ack quickly, we don't want the irq controller @@ -422,7 +422,7 @@ * 0 return value means that this irq is already being * handled by some other CPU. (or is disabled) */ - int irq = regs.orig_eax & 0xff; /* high bits used in ret_from_ code */ + int irq = regs->orig_eax & 0xff; /* high bits used in ret_from_ code */ irq_desc_t *desc = irq_desc + irq; struct irqaction * action; unsigned int status; @@ -488,7 +488,7 @@ irqreturn_t action_ret; spin_unlock(&desc->lock); - action_ret = handle_IRQ_event(irq, ®s, action); + action_ret = handle_IRQ_event(irq, regs, action); spin_lock(&desc->lock); if (!noirqdebug) note_interrupt(irq, desc, action_ret);