[PATCH] SW Breakpoint doesn't work after it triggers on non boot CPU
Konstantin Baydarov <[email protected]>
| Newsgroups | gmane.linux.kernel.debugging |
|---|---|
| Message-ID | <[email protected]> |
I'v set breakpoint to do_sync, then I'v triggered it, first on BOOT CPU(CPU0), than on CPU1. Here is log: [email protected]:~# sync Instruction(i) breakpoint #0 at 0xc01787c1 (adjusted) 0xc01787c1 do_sync: int3 Entering kdb (current=0xf7ce8ab0, pid 1718) on processor 0 due to Breakpoint @0xc01787c1 [0]kdb> go [email protected]:~# [email protected]:~# [email protected]:~# taskset -c 1 sync Instruction(i) breakpoint #0 at 0xc01787c1 (adjusted) 0xc01787c1 do_sync: int3 Entering kdb (current=0xf7f81a30, pid 1719) on processor 1 due to Breakpoint @0xc01787c1 [1]kdb> go [email protected]:~# [email protected]:~# [email protected]:~# sync [email protected]:~# [email protected]:~# sync [email protected]:~# Breakpoint on do_sync doesn't work after I've triggered it on the CPU1(taskset-c 1 sync). The reasons of issue are: 1) code that related to install/remove global bp was hardwired to CPU with id 0, don't know why. ... if (!kdb_quiet(reason) || smp_processor_id() == 0) { kdb_bp_install_global(regs); kdbnearsym_cleanup(); debug_kusage(); } ... 2) after single-step over a breakpoint KDB makes itself silent: kdb() ... if (KDB_STATE(GO1)) { kdb_bp_remove_global(); /* They were set for single-step purposes */ KDB_STATE_CLEAR(GO1); reason = KDB_REASON_SILENT; /* Now silently go */ } ... That prevents reinstall of global breakpoints when kernel is leaving kdb: /* * (Re)install the global breakpoints and cleanup the cached * symbol table. This is only done once from the initial * processor on go. */ KDB_DEBUG_STATE("kdb 12", reason); if (!kdb_quiet(reason) || smp_processor_id() == 0) { kdb_bp_install_global(regs); kdbnearsym_cleanup(); debug_kusage(); } How solved: 1) CPU0 code removed. 2) Patch checks if reason is set to KDB_REASON_SILENT and reinstall global breakpoints in that case. 3) Also patch fixes KDB notifier when kernel exits KDB. Patch was tested on x86_64 2 CPU PC with i386 2.6.21 kernel. Thanks. Signed-off-by: Konstantin Baydarov <[email protected]> kdb/kdbmain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) Index: linux-2.6.21/kdb/kdbmain.c =================================================================== --- linux-2.6.21.orig/kdb/kdbmain.c +++ linux-2.6.21/kdb/kdbmain.c @@ -1974,7 +1974,7 @@ kdb(kdb_reason_t reason, int error, stru * Remove the global breakpoints. This is only done * once from the initial processor on initial entry. */ - if (!kdb_quiet(reason) || smp_processor_id() == 0) + if (!kdb_quiet(reason)) kdb_bp_remove_global(); /* @@ -2028,7 +2028,7 @@ kdb(kdb_reason_t reason, int error, stru * processor on go. */ KDB_DEBUG_STATE("kdb 12", reason); - if (!kdb_quiet(reason) || smp_processor_id() == 0) { + if (!kdb_quiet(reason) || reason == KDB_REASON_SILENT) { kdb_bp_install_global(regs); kdbnearsym_cleanup(); debug_kusage(); @@ -2047,7 +2047,7 @@ kdb(kdb_reason_t reason, int error, stru /* Wait until all the other processors leave kdb */ while (kdb_previous_event() != 1) ; - if (!kdb_quiet(reason)) + if (!kdb_quiet(reason) || reason == KDB_REASON_SILENT) notify_die(DIE_KDEBUG_LEAVE, "KDEBUG LEAVE", regs, error, 0, 0); kdb_initial_cpu = -1; /* release kdb control */ KDB_DEBUG_STATE("kdb 13", reason); --------------------------- Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.