1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2004 The FreeBSD Project 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include "opt_kdb.h" 33 #include "opt_stack.h" 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/cons.h> 38 #include <sys/kdb.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/lock.h> 42 #include <sys/pcpu.h> 43 #include <sys/proc.h> 44 #include <sys/sbuf.h> 45 #include <sys/smp.h> 46 #include <sys/stack.h> 47 #include <sys/sysctl.h> 48 49 #include <machine/kdb.h> 50 #include <machine/pcb.h> 51 52 #ifdef SMP 53 #include <machine/smp.h> 54 #endif 55 56 u_char __read_frequently kdb_active = 0; 57 static void *kdb_jmpbufp = NULL; 58 struct kdb_dbbe *kdb_dbbe = NULL; 59 static struct pcb kdb_pcb; 60 struct pcb *kdb_thrctx = NULL; 61 struct thread *kdb_thread = NULL; 62 struct trapframe *kdb_frame = NULL; 63 64 #ifdef BREAK_TO_DEBUGGER 65 #define KDB_BREAK_TO_DEBUGGER 1 66 #else 67 #define KDB_BREAK_TO_DEBUGGER 0 68 #endif 69 70 #ifdef ALT_BREAK_TO_DEBUGGER 71 #define KDB_ALT_BREAK_TO_DEBUGGER 1 72 #else 73 #define KDB_ALT_BREAK_TO_DEBUGGER 0 74 #endif 75 76 static int kdb_break_to_debugger = KDB_BREAK_TO_DEBUGGER; 77 static int kdb_alt_break_to_debugger = KDB_ALT_BREAK_TO_DEBUGGER; 78 79 KDB_BACKEND(null, NULL, NULL, NULL, NULL); 80 81 static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS); 82 static int kdb_sysctl_current(SYSCTL_HANDLER_ARGS); 83 static int kdb_sysctl_enter(SYSCTL_HANDLER_ARGS); 84 static int kdb_sysctl_panic(SYSCTL_HANDLER_ARGS); 85 static int kdb_sysctl_panic_str(SYSCTL_HANDLER_ARGS); 86 static int kdb_sysctl_trap(SYSCTL_HANDLER_ARGS); 87 static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS); 88 static int kdb_sysctl_stack_overflow(SYSCTL_HANDLER_ARGS); 89 90 static SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 91 "KDB nodes"); 92 93 SYSCTL_PROC(_debug_kdb, OID_AUTO, available, 94 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, 95 kdb_sysctl_available, "A", 96 "list of available KDB backends"); 97 98 SYSCTL_PROC(_debug_kdb, OID_AUTO, current, 99 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0, 100 kdb_sysctl_current, "A", 101 "currently selected KDB backend"); 102 103 SYSCTL_PROC(_debug_kdb, OID_AUTO, enter, 104 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0, 105 kdb_sysctl_enter, "I", 106 "set to enter the debugger"); 107 108 SYSCTL_PROC(_debug_kdb, OID_AUTO, panic, 109 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0, 110 kdb_sysctl_panic, "I", 111 "set to panic the kernel"); 112 113 SYSCTL_PROC(_debug_kdb, OID_AUTO, panic_str, 114 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0, 115 kdb_sysctl_panic_str, "A", 116 "trigger a kernel panic, using the provided string as the panic message"); 117 118 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap, 119 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0, 120 kdb_sysctl_trap, "I", 121 "set to cause a page fault via data access"); 122 123 SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, 124 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0, 125 kdb_sysctl_trap_code, "I", 126 "set to cause a page fault via code access"); 127 128 SYSCTL_PROC(_debug_kdb, OID_AUTO, stack_overflow, 129 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE, NULL, 0, 130 kdb_sysctl_stack_overflow, "I", 131 "set to cause a stack overflow"); 132 133 SYSCTL_INT(_debug_kdb, OID_AUTO, break_to_debugger, 134 CTLFLAG_RWTUN | CTLFLAG_SECURE, 135 &kdb_break_to_debugger, 0, "Enable break to debugger"); 136 137 SYSCTL_INT(_debug_kdb, OID_AUTO, alt_break_to_debugger, 138 CTLFLAG_RWTUN | CTLFLAG_SECURE, 139 &kdb_alt_break_to_debugger, 0, "Enable alternative break to debugger"); 140 141 /* 142 * Flag to indicate to debuggers why the debugger was entered. 143 */ 144 const char * volatile kdb_why = KDB_WHY_UNSET; 145 146 static int 147 kdb_sysctl_available(SYSCTL_HANDLER_ARGS) 148 { 149 struct kdb_dbbe **iter; 150 struct sbuf sbuf; 151 int error; 152 153 sbuf_new_for_sysctl(&sbuf, NULL, 64, req); 154 SET_FOREACH(iter, kdb_dbbe_set) { 155 if ((*iter)->dbbe_active == 0) 156 sbuf_printf(&sbuf, "%s ", (*iter)->dbbe_name); 157 } 158 error = sbuf_finish(&sbuf); 159 sbuf_delete(&sbuf); 160 return (error); 161 } 162 163 static int 164 kdb_sysctl_current(SYSCTL_HANDLER_ARGS) 165 { 166 char buf[16]; 167 int error; 168 169 if (kdb_dbbe != NULL) 170 strlcpy(buf, kdb_dbbe->dbbe_name, sizeof(buf)); 171 else 172 *buf = '\0'; 173 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 174 if (error != 0 || req->newptr == NULL) 175 return (error); 176 if (kdb_active) 177 return (EBUSY); 178 return (kdb_dbbe_select(buf)); 179 } 180 181 static int 182 kdb_sysctl_enter(SYSCTL_HANDLER_ARGS) 183 { 184 int error, i; 185 186 error = sysctl_wire_old_buffer(req, sizeof(int)); 187 if (error == 0) { 188 i = 0; 189 error = sysctl_handle_int(oidp, &i, 0, req); 190 } 191 if (error != 0 || req->newptr == NULL) 192 return (error); 193 if (kdb_active) 194 return (EBUSY); 195 kdb_enter(KDB_WHY_SYSCTL, "sysctl debug.kdb.enter"); 196 return (0); 197 } 198 199 static int 200 kdb_sysctl_panic(SYSCTL_HANDLER_ARGS) 201 { 202 int error, i; 203 204 error = sysctl_wire_old_buffer(req, sizeof(int)); 205 if (error == 0) { 206 i = 0; 207 error = sysctl_handle_int(oidp, &i, 0, req); 208 } 209 if (error != 0 || req->newptr == NULL) 210 return (error); 211 panic("kdb_sysctl_panic"); 212 return (0); 213 } 214 215 static int 216 kdb_sysctl_panic_str(SYSCTL_HANDLER_ARGS) 217 { 218 int error; 219 static char buf[256]; /* static buffer to limit mallocs when panicing */ 220 221 *buf = '\0'; 222 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 223 if (error != 0 || req->newptr == NULL) 224 return (error); 225 panic("kdb_sysctl_panic: %s", buf); 226 return (0); 227 } 228 229 static int 230 kdb_sysctl_trap(SYSCTL_HANDLER_ARGS) 231 { 232 int error, i; 233 int *addr = (int *)0x10; 234 235 error = sysctl_wire_old_buffer(req, sizeof(int)); 236 if (error == 0) { 237 i = 0; 238 error = sysctl_handle_int(oidp, &i, 0, req); 239 } 240 if (error != 0 || req->newptr == NULL) 241 return (error); 242 return (*addr); 243 } 244 245 static int 246 kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS) 247 { 248 int error, i; 249 void (*fp)(u_int, u_int, u_int) = (void *)0xdeadc0de; 250 251 error = sysctl_wire_old_buffer(req, sizeof(int)); 252 if (error == 0) { 253 i = 0; 254 error = sysctl_handle_int(oidp, &i, 0, req); 255 } 256 if (error != 0 || req->newptr == NULL) 257 return (error); 258 (*fp)(0x11111111, 0x22222222, 0x33333333); 259 return (0); 260 } 261 262 static void kdb_stack_overflow(volatile int *x) __noinline; 263 static void 264 kdb_stack_overflow(volatile int *x) 265 { 266 267 if (*x > 10000000) 268 return; 269 kdb_stack_overflow(x); 270 *x += PCPU_GET(cpuid) / 1000000; 271 } 272 273 static int 274 kdb_sysctl_stack_overflow(SYSCTL_HANDLER_ARGS) 275 { 276 int error, i; 277 volatile int x; 278 279 error = sysctl_wire_old_buffer(req, sizeof(int)); 280 if (error == 0) { 281 i = 0; 282 error = sysctl_handle_int(oidp, &i, 0, req); 283 } 284 if (error != 0 || req->newptr == NULL) 285 return (error); 286 x = 0; 287 kdb_stack_overflow(&x); 288 return (0); 289 } 290 291 void 292 kdb_panic(const char *msg) 293 { 294 295 printf("KDB: panic\n"); 296 panic("%s", msg); 297 } 298 299 void 300 kdb_reboot(void) 301 { 302 303 printf("KDB: reboot requested\n"); 304 shutdown_nice(0); 305 } 306 307 /* 308 * Solaris implements a new BREAK which is initiated by a character sequence 309 * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the 310 * Remote Console. 311 * 312 * Note that this function may be called from almost anywhere, with interrupts 313 * disabled and with unknown locks held, so it must not access data other than 314 * its arguments. Its up to the caller to ensure that the state variable is 315 * consistent. 316 */ 317 #define KEY_CR 13 /* CR '\r' */ 318 #define KEY_TILDE 126 /* ~ */ 319 #define KEY_CRTLB 2 /* ^B */ 320 #define KEY_CRTLP 16 /* ^P */ 321 #define KEY_CRTLR 18 /* ^R */ 322 323 /* States of th KDB "alternate break sequence" detecting state machine. */ 324 enum { 325 KDB_ALT_BREAK_SEEN_NONE, 326 KDB_ALT_BREAK_SEEN_CR, 327 KDB_ALT_BREAK_SEEN_CR_TILDE, 328 }; 329 330 int 331 kdb_break(void) 332 { 333 334 if (!kdb_break_to_debugger) 335 return (0); 336 kdb_enter(KDB_WHY_BREAK, "Break to debugger"); 337 return (KDB_REQ_DEBUGGER); 338 } 339 340 static int 341 kdb_alt_break_state(int key, int *state) 342 { 343 int brk; 344 345 /* All states transition to KDB_ALT_BREAK_SEEN_CR on a CR. */ 346 if (key == KEY_CR) { 347 *state = KDB_ALT_BREAK_SEEN_CR; 348 return (0); 349 } 350 351 brk = 0; 352 switch (*state) { 353 case KDB_ALT_BREAK_SEEN_CR: 354 *state = KDB_ALT_BREAK_SEEN_NONE; 355 if (key == KEY_TILDE) 356 *state = KDB_ALT_BREAK_SEEN_CR_TILDE; 357 break; 358 case KDB_ALT_BREAK_SEEN_CR_TILDE: 359 *state = KDB_ALT_BREAK_SEEN_NONE; 360 if (key == KEY_CRTLB) 361 brk = KDB_REQ_DEBUGGER; 362 else if (key == KEY_CRTLP) 363 brk = KDB_REQ_PANIC; 364 else if (key == KEY_CRTLR) 365 brk = KDB_REQ_REBOOT; 366 break; 367 case KDB_ALT_BREAK_SEEN_NONE: 368 default: 369 *state = KDB_ALT_BREAK_SEEN_NONE; 370 break; 371 } 372 return (brk); 373 } 374 375 static int 376 kdb_alt_break_internal(int key, int *state, int force_gdb) 377 { 378 int brk; 379 380 if (!kdb_alt_break_to_debugger) 381 return (0); 382 brk = kdb_alt_break_state(key, state); 383 switch (brk) { 384 case KDB_REQ_DEBUGGER: 385 if (force_gdb) 386 kdb_dbbe_select("gdb"); 387 kdb_enter(KDB_WHY_BREAK, "Break to debugger"); 388 break; 389 390 case KDB_REQ_PANIC: 391 if (force_gdb) 392 kdb_dbbe_select("gdb"); 393 kdb_panic("Panic sequence on console"); 394 break; 395 396 case KDB_REQ_REBOOT: 397 kdb_reboot(); 398 break; 399 } 400 return (0); 401 } 402 403 int 404 kdb_alt_break(int key, int *state) 405 { 406 407 return (kdb_alt_break_internal(key, state, 0)); 408 } 409 410 /* 411 * This variation on kdb_alt_break() is used only by dcons, which has its own 412 * configuration flag to force GDB use regardless of the global KDB 413 * configuration. 414 */ 415 int 416 kdb_alt_break_gdb(int key, int *state) 417 { 418 419 return (kdb_alt_break_internal(key, state, 1)); 420 } 421 422 /* 423 * Print a backtrace of the calling thread. The backtrace is generated by 424 * the selected debugger, provided it supports backtraces. If no debugger 425 * is selected or the current debugger does not support backtraces, this 426 * function silently returns. 427 */ 428 void 429 kdb_backtrace(void) 430 { 431 432 if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) { 433 printf("KDB: stack backtrace:\n"); 434 kdb_dbbe->dbbe_trace(); 435 } 436 #ifdef STACK 437 else { 438 struct stack st; 439 440 printf("KDB: stack backtrace:\n"); 441 stack_save(&st); 442 stack_print_ddb(&st); 443 } 444 #endif 445 } 446 447 /* 448 * Similar to kdb_backtrace() except that it prints a backtrace of an 449 * arbitrary thread rather than the calling thread. 450 */ 451 void 452 kdb_backtrace_thread(struct thread *td) 453 { 454 455 if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace_thread != NULL) { 456 printf("KDB: stack backtrace of thread %d:\n", td->td_tid); 457 kdb_dbbe->dbbe_trace_thread(td); 458 } 459 #ifdef STACK 460 else { 461 struct stack st; 462 463 printf("KDB: stack backtrace of thread %d:\n", td->td_tid); 464 if (stack_save_td(&st, td) == 0) 465 stack_print_ddb(&st); 466 } 467 #endif 468 } 469 470 /* 471 * Set/change the current backend. 472 */ 473 int 474 kdb_dbbe_select(const char *name) 475 { 476 struct kdb_dbbe *be, **iter; 477 478 SET_FOREACH(iter, kdb_dbbe_set) { 479 be = *iter; 480 if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) { 481 kdb_dbbe = be; 482 return (0); 483 } 484 } 485 return (EINVAL); 486 } 487 488 /* 489 * Enter the currently selected debugger. If a message has been provided, 490 * it is printed first. If the debugger does not support the enter method, 491 * it is entered by using breakpoint(), which enters the debugger through 492 * kdb_trap(). The 'why' argument will contain a more mechanically usable 493 * string than 'msg', and is relied upon by DDB scripting to identify the 494 * reason for entering the debugger so that the right script can be run. 495 */ 496 void 497 kdb_enter(const char *why, const char *msg) 498 { 499 500 if (kdb_dbbe != NULL && kdb_active == 0) { 501 if (msg != NULL) 502 printf("KDB: enter: %s\n", msg); 503 kdb_why = why; 504 breakpoint(); 505 kdb_why = KDB_WHY_UNSET; 506 } 507 } 508 509 /* 510 * Initialize the kernel debugger interface. 511 */ 512 void 513 kdb_init(void) 514 { 515 struct kdb_dbbe *be, **iter; 516 int cur_pri, pri; 517 518 kdb_active = 0; 519 kdb_dbbe = NULL; 520 cur_pri = -1; 521 SET_FOREACH(iter, kdb_dbbe_set) { 522 be = *iter; 523 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1; 524 be->dbbe_active = (pri >= 0) ? 0 : -1; 525 if (pri > cur_pri) { 526 cur_pri = pri; 527 kdb_dbbe = be; 528 } 529 } 530 if (kdb_dbbe != NULL) { 531 printf("KDB: debugger backends:"); 532 SET_FOREACH(iter, kdb_dbbe_set) { 533 be = *iter; 534 if (be->dbbe_active == 0) 535 printf(" %s", be->dbbe_name); 536 } 537 printf("\n"); 538 printf("KDB: current backend: %s\n", 539 kdb_dbbe->dbbe_name); 540 } 541 } 542 543 /* 544 * Handle contexts. 545 */ 546 void * 547 kdb_jmpbuf(jmp_buf new) 548 { 549 void *old; 550 551 old = kdb_jmpbufp; 552 kdb_jmpbufp = new; 553 return (old); 554 } 555 556 void 557 kdb_reenter(void) 558 { 559 560 if (!kdb_active || kdb_jmpbufp == NULL) 561 return; 562 563 printf("KDB: reentering\n"); 564 kdb_backtrace(); 565 longjmp(kdb_jmpbufp, 1); 566 /* NOTREACHED */ 567 } 568 569 void 570 kdb_reenter_silent(void) 571 { 572 573 if (!kdb_active || kdb_jmpbufp == NULL) 574 return; 575 576 longjmp(kdb_jmpbufp, 1); 577 /* NOTREACHED */ 578 } 579 580 /* 581 * Thread-related support functions. 582 */ 583 struct pcb * 584 kdb_thr_ctx(struct thread *thr) 585 { 586 #if defined(SMP) && defined(KDB_STOPPEDPCB) 587 struct pcpu *pc; 588 #endif 589 590 if (thr == curthread) 591 return (&kdb_pcb); 592 593 #if defined(SMP) && defined(KDB_STOPPEDPCB) 594 STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { 595 if (pc->pc_curthread == thr && 596 CPU_ISSET(pc->pc_cpuid, &stopped_cpus)) 597 return (KDB_STOPPEDPCB(pc)); 598 } 599 #endif 600 return (thr->td_pcb); 601 } 602 603 struct thread * 604 kdb_thr_first(void) 605 { 606 struct proc *p; 607 struct thread *thr; 608 u_int i; 609 610 /* This function may be called early. */ 611 if (pidhashtbl == NULL) 612 return (&thread0); 613 614 for (i = 0; i <= pidhash; i++) { 615 LIST_FOREACH(p, &pidhashtbl[i], p_hash) { 616 thr = FIRST_THREAD_IN_PROC(p); 617 if (thr != NULL) 618 return (thr); 619 } 620 } 621 return (NULL); 622 } 623 624 struct thread * 625 kdb_thr_from_pid(pid_t pid) 626 { 627 struct proc *p; 628 629 LIST_FOREACH(p, PIDHASH(pid), p_hash) { 630 if (p->p_pid == pid) 631 return (FIRST_THREAD_IN_PROC(p)); 632 } 633 return (NULL); 634 } 635 636 struct thread * 637 kdb_thr_lookup(lwpid_t tid) 638 { 639 struct thread *thr; 640 641 thr = kdb_thr_first(); 642 while (thr != NULL && thr->td_tid != tid) 643 thr = kdb_thr_next(thr); 644 return (thr); 645 } 646 647 struct thread * 648 kdb_thr_next(struct thread *thr) 649 { 650 struct proc *p; 651 u_int hash; 652 653 p = thr->td_proc; 654 thr = TAILQ_NEXT(thr, td_plist); 655 if (thr != NULL) 656 return (thr); 657 if (pidhashtbl == NULL) 658 return (NULL); 659 hash = p->p_pid & pidhash; 660 for (;;) { 661 p = LIST_NEXT(p, p_hash); 662 while (p == NULL) { 663 if (++hash > pidhash) 664 return (NULL); 665 p = LIST_FIRST(&pidhashtbl[hash]); 666 } 667 thr = FIRST_THREAD_IN_PROC(p); 668 if (thr != NULL) 669 return (thr); 670 } 671 } 672 673 int 674 kdb_thr_select(struct thread *thr) 675 { 676 if (thr == NULL) 677 return (EINVAL); 678 kdb_thread = thr; 679 kdb_thrctx = kdb_thr_ctx(thr); 680 return (0); 681 } 682 683 /* 684 * Enter the debugger due to a trap. 685 */ 686 int 687 kdb_trap(int type, int code, struct trapframe *tf) 688 { 689 #ifdef SMP 690 cpuset_t other_cpus; 691 #endif 692 struct kdb_dbbe *be; 693 register_t intr; 694 int handled; 695 int did_stop_cpus; 696 697 be = kdb_dbbe; 698 if (be == NULL || be->dbbe_trap == NULL) 699 return (0); 700 701 /* We reenter the debugger through kdb_reenter(). */ 702 if (kdb_active) 703 return (0); 704 705 intr = intr_disable(); 706 707 if (!SCHEDULER_STOPPED()) { 708 #ifdef SMP 709 other_cpus = all_cpus; 710 CPU_ANDNOT(&other_cpus, &other_cpus, &stopped_cpus); 711 CPU_CLR(PCPU_GET(cpuid), &other_cpus); 712 stop_cpus_hard(other_cpus); 713 #endif 714 curthread->td_stopsched = 1; 715 did_stop_cpus = 1; 716 } else 717 did_stop_cpus = 0; 718 719 kdb_active++; 720 721 kdb_frame = tf; 722 723 /* Let MD code do its thing first... */ 724 kdb_cpu_trap(type, code); 725 726 makectx(tf, &kdb_pcb); 727 kdb_thr_select(curthread); 728 729 cngrab(); 730 731 for (;;) { 732 handled = be->dbbe_trap(type, code); 733 if (be == kdb_dbbe) 734 break; 735 be = kdb_dbbe; 736 if (be == NULL || be->dbbe_trap == NULL) 737 break; 738 printf("Switching to %s back-end\n", be->dbbe_name); 739 } 740 741 cnungrab(); 742 743 kdb_active--; 744 745 if (did_stop_cpus) { 746 curthread->td_stopsched = 0; 747 #ifdef SMP 748 CPU_AND(&other_cpus, &other_cpus, &stopped_cpus); 749 restart_cpus(other_cpus); 750 #endif 751 } 752 753 intr_restore(intr); 754 755 return (handled); 756 } 757