==== //depot/software/kernel/linux2.4/linux_kdb/kdb/kdb_bp.c#3 (ktext) - //depot/software/kernel/linux2.4/linux_kdb/kdb/kdb_bp.c#4 (ktext) ==== content @@ -557,15 +557,6 @@ if (argc != 0) return KDB_ARGCOUNT; - /* - * Set trace flag and go. - */ - KDB_STATE_SET(DOING_SS); - if (ssb) - KDB_STATE_SET(DOING_SSB); - - kdba_setsinglestep(ef); /* Enable single step */ - if (ssb) return KDB_CMD_SSB; return KDB_CMD_SS; ==== //depot/software/kernel/linux2.4/linux_kdb/kdb/kdb_io.c#5 (text) - //depot/software/kernel/linux2.4/linux_kdb/kdb/kdb_io.c#7 (text) ==== content @@ -158,17 +158,22 @@ int linecount; int logging, saved_loglevel = 0; int do_longjmp = 0; +#ifndef CONFIG_SPARC64 struct console *c = console_drivers; +#endif static spinlock_t kdb_printf_lock = SPIN_LOCK_UNLOCKED; + static int kdb_printf_count; /* Serialize kdb_printf if multiple cpus try to write at once. * But if any cpu goes recursive in kdb, just print the output, * even if it is interleaved with any other text. */ if (!KDB_STATE(PRINTF_LOCK)) { + spin_lock(&kdb_printf_lock); KDB_STATE_SET(PRINTF_LOCK); - spin_lock(&kdb_printf_lock); - } + kdb_printf_count = 1; + } else + kdb_printf_count++; diag = kdbgetintenv("LINES", &linecount); if (diag) @@ -186,14 +191,13 @@ * Write to all consoles. */ #ifdef CONFIG_SPARC64 - if (c == NULL) - prom_printf("%s", buffer); - else -#endif + prom_printf("%s",buffer); +#else while (c) { c->write(c, buffer, strlen(buffer)); c = c->next; } +#endif if (logging) { saved_loglevel = console_loglevel; console_loglevel = 0; @@ -233,16 +237,16 @@ } #endif +#ifdef CONFIG_SPARC64 + prom_printf("%s", moreprompt); + +#else c = console_drivers; -#ifdef CONFIG_SPARC64 - if (c == NULL) - prom_printf("%s", moreprompt); - else -#endif while (c) { c->write(c, moreprompt, strlen(moreprompt)); c = c->next; } +#endif if (logging) printk("%s", moreprompt); @@ -259,9 +263,11 @@ if (logging) { console_loglevel = saved_loglevel; } - if (KDB_STATE(PRINTF_LOCK)) { + if (!KDB_STATE(PRINTF_LOCK)) + kdb_printf("kdb_printf panic: lock not set!\n"); + else if (--kdb_printf_count == 0) { + KDB_STATE_CLEAR(PRINTF_LOCK); spin_unlock(&kdb_printf_lock); - KDB_STATE_CLEAR(PRINTF_LOCK); } if (do_longjmp) #ifdef KDB_HAVE_LONGJMP ==== //depot/software/kernel/linux2.4/linux_kdb/kdb/kdbmain.c#9 (ktext) - //depot/software/kernel/linux2.4/linux_kdb/kdb/kdbmain.c#12 (ktext) ==== content @@ -1085,7 +1085,6 @@ KDB_DEBUG_STATE("kdb_main_loop 4a", reason); KDB_STATE_SET(DOING_SS); KDB_STATE_SET(DOING_SSBPT); - kdba_setsinglestep(ef); break; } @@ -1453,6 +1452,9 @@ KDB_STATE_CLEAR(KDB); /* Main kdb state has been cleared */ KDB_STATE_CLEAR(LEAVING); /* Elvis has left the building ... */ KDB_STATE_CLEAR(NEED_SSBPT); + if (KDB_STATE(DOING_SS)) + kdba_setsinglestep(ef); + KDB_DEBUG_STATE("kdb 14", result); if (cpu == kdb_initial_cpu && ==== //depot/software/kernel/linux2.4/linux_kdb/arch/i386/kdb/kdba_bp.c#2 (ktext) - //depot/software/kernel/linux2.4/linux_kdb/arch/i386/kdb/kdba_bp.c#3 (ktext) ==== content @@ -95,44 +95,22 @@ if (KDB_DEBUG(BP)) kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7); if (dr6 & DR6_BS) { - if (KDB_STATE(SSBPT)) { - if (KDB_DEBUG(BP)) - kdb_printf("ssbpt\n"); - KDB_STATE_CLEAR(SSBPT); - for(i=0,bp=kdb_breakpoints; - i < KDB_MAXBPT; - i++, bp++) { - if (KDB_DEBUG(BP)) - kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n", - bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu); - if (!bp->bp_enabled) - continue; - if (!bp->bp_global && bp->bp_cpu != smp_processor_id()) - continue; - if (KDB_DEBUG(BP)) - kdb_printf("bp for this cpu\n"); - if (bp->bp_delayed) { - bp->bp_delayed = 0; - if (KDB_DEBUG(BP)) - kdb_printf("kdba_installbp\n"); - kdba_installbp(ef, bp); - if (!KDB_STATE(DOING_SS)) { - ef->eflags &= ~EF_TF; - return(KDB_DB_SSBPT); - } - break; - } - } - if (i == KDB_MAXBPT) { - kdb_printf("kdb: Unable to find delayed breakpoint\n"); - } - if (!KDB_STATE(DOING_SS)) { - ef->eflags &= ~EF_TF; - return(KDB_DB_NOBPT); - } - /* FALLTHROUGH */ - } + if (!KDB_STATE(DOING_SS)) + goto unknown; + + KDB_STATE_CLEAR(DOING_SS); + + if (!KDB_STATE(DOING_SSBPT)) + goto not_ssbpt; + + KDB_STATE_CLEAR(DOING_SSBPT); + + if (KDB_DEBUG(BP)) + kdb_printf("ssbpt\n"); + + return (KDB_DB_SSBPT); +not_ssbpt: /* * KDB_STATE_DOING_SS is set when the kernel debugger is using * the processor trap flag to single-step a processor. If a @@ -140,8 +118,6 @@ * will be ignored by KDB and the kernel will be allowed to deal * with it as necessary (e.g. for ptrace). */ - if (!KDB_STATE(DOING_SS)) - goto unknown; /* single step */ rv = KDB_DB_SS; /* Indicate single step */ @@ -162,8 +138,8 @@ * End the ssb command here. */ KDB_STATE_CLEAR(DOING_SSB); - KDB_STATE_CLEAR(DOING_SS); } else { + KDB_STATE_SET(DOING_SS); /* still need to step */ rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */ } } else { @@ -173,11 +149,7 @@ kdb_printf("SS trap at "); kdb_symbol_print(ef->eip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE); kdb_id1(ef->eip); - KDB_STATE_CLEAR(DOING_SS); } - - if (rv != KDB_DB_SSB) - ef->eflags &= ~EF_TF; } if (dr6 & DR6_B0) { @@ -244,6 +216,7 @@ unknown: ef->eflags |= EF_RF; /* Supress further faults */ + kdb_printf("kdb: debug trap, unknown cause\n"); rv = KDB_DB_NOBPT; /* Cause kdb() to return */ handled: @@ -307,6 +280,9 @@ "eflags=0x%lx ef=0x%p esp=0x%lx\n", ef->eip, ef->eflags, ef, ef->esp); + if (KDB_STATE(DOING_SS)) + kdb_printf("kdba_bp_trap: ??? should be single stepping!\n"); + rv = KDB_DB_NOBPT; /* Cause kdb() to return */ for(i=0, bp=kdb_breakpoints; ieip); kdb_id1(ef->eip); rv = KDB_DB_BPT; - bp->bp_delay = 1; + KDB_STATE_SET(NEED_SSBPT); break; } } @@ -330,56 +306,6 @@ } /* - * kdba_handle_bp - * - * Handle an instruction-breakpoint trap. Called when re-installing - * an enabled breakpoint which has has the bp_delay bit set. - * - * Parameters: - * Returns: - * Locking: - * Remarks: - * - * Ok, we really need to: - * 1) Restore the original instruction byte - * 2) Single Step - * 3) Restore breakpoint instruction - * 4) Continue. - * - * - */ - -static void -kdba_handle_bp(kdb_eframe_t ef, kdb_bp_t *bp) -{ - if (!ef) { - kdb_printf("kdba_handle_bp: ef == NULL\n"); - return; - } - - if (KDB_DEBUG(BP)) - kdb_printf("ef->eip = 0x%lx\n", ef->eip); - - /* - * Setup single step - */ - kdba_setsinglestep(ef); - - /* KDB_STATE_SSBPT is set when the kernel debugger must single step - * a task in order to re-establish an instruction breakpoint which - * uses the instruction replacement mechanism. - */ - KDB_STATE_SET(SSBPT); - - /* - * Reset delay attribute - */ - bp->bp_delay = 0; - bp->bp_delayed = 1; -} - - -/* * kdba_bptype * * Return a string describing type of breakpoint. @@ -714,10 +640,6 @@ kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n", bp->bp_hard->bph_reg, bp->bp_addr); } - } else if (bp->bp_delay) { - if (KDB_DEBUG(BP)) - kdb_printf("kdba_installbp delayed bp\n"); - kdba_handle_bp(ef, bp); } else { if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) || kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) { ==== //depot/software/kernel/linux2.4/linux_kdb/arch/i386/kdb/kdbasupport.c#2 (ktext) - //depot/software/kernel/linux2.4/linux_kdb/arch/i386/kdb/kdbasupport.c#3 (ktext) ==== content @@ -1001,6 +1001,9 @@ void kdba_setsinglestep(struct pt_regs *regs) { + if (regs->eflags & EF_TF) + return; + if (regs->eflags & EF_IE) KDB_STATE_SET(A_IF); else @@ -1011,10 +1014,14 @@ void kdba_clearsinglestep(struct pt_regs *regs) { + if ((regs->eflags & EF_TF) == 0) + return; + if (KDB_STATE(A_IF)) regs->eflags |= EF_IE; else regs->eflags &= ~EF_IE; + regs->eflags &= ~EF_TF; } int