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_zero(&st); 442 stack_save(&st); 443 stack_print_ddb(&st); 444 } 445 #endif 446 } 447 448 /* 449 * Similar to kdb_backtrace() except that it prints a backtrace of an 450 * arbitrary thread rather than the calling thread. 451 */ 452 void 453 kdb_backtrace_thread(struct thread *td) 454 { 455 456 if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace_thread != NULL) { 457 printf("KDB: stack backtrace of thread %d:\n", td->td_tid); 458 kdb_dbbe->dbbe_trace_thread(td); 459 } 460 #ifdef STACK 461 else { 462 struct stack st; 463 464 printf("KDB: stack backtrace of thread %d:\n", td->td_tid); 465 if (stack_save_td(&st, td) == 0) 466 stack_print_ddb(&st); 467 } 468 #endif 469 } 470 471 /* 472 * Set/change the current backend. 473 */ 474 int 475 kdb_dbbe_select(const char *name) 476 { 477 struct kdb_dbbe *be, **iter; 478 479 SET_FOREACH(iter, kdb_dbbe_set) { 480 be = *iter; 481 if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) { 482 kdb_dbbe = be; 483 return (0); 484 } 485 } 486 return (EINVAL); 487 } 488 489 /* 490 * Enter the currently selected debugger. If a message has been provided, 491 * it is printed first. If the debugger does not support the enter method, 492 * it is entered by using breakpoint(), which enters the debugger through 493 * kdb_trap(). The 'why' argument will contain a more mechanically usable 494 * string than 'msg', and is relied upon by DDB scripting to identify the 495 * reason for entering the debugger so that the right script can be run. 496 */ 497 void 498 kdb_enter(const char *why, const char *msg) 499 { 500 501 if (kdb_dbbe != NULL && kdb_active == 0) { 502 if (msg != NULL) 503 printf("KDB: enter: %s\n", msg); 504 kdb_why = why; 505 breakpoint(); 506 kdb_why = KDB_WHY_UNSET; 507 } 508 } 509 510 /* 511 * Initialize the kernel debugger interface. 512 */ 513 void 514 kdb_init(void) 515 { 516 struct kdb_dbbe *be, **iter; 517 int cur_pri, pri; 518 519 kdb_active = 0; 520 kdb_dbbe = NULL; 521 cur_pri = -1; 522 SET_FOREACH(iter, kdb_dbbe_set) { 523 be = *iter; 524 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1; 525 be->dbbe_active = (pri >= 0) ? 0 : -1; 526 if (pri > cur_pri) { 527 cur_pri = pri; 528 kdb_dbbe = be; 529 } 530 } 531 if (kdb_dbbe != NULL) { 532 printf("KDB: debugger backends:"); 533 SET_FOREACH(iter, kdb_dbbe_set) { 534 be = *iter; 535 if (be->dbbe_active == 0) 536 printf(" %s", be->dbbe_name); 537 } 538 printf("\n"); 539 printf("KDB: current backend: %s\n", 540 kdb_dbbe->dbbe_name); 541 } 542 } 543 544 /* 545 * Handle contexts. 546 */ 547 void * 548 kdb_jmpbuf(jmp_buf new) 549 { 550 void *old; 551 552 old = kdb_jmpbufp; 553 kdb_jmpbufp = new; 554 return (old); 555 } 556 557 void 558 kdb_reenter(void) 559 { 560 561 if (!kdb_active || kdb_jmpbufp == NULL) 562 return; 563 564 printf("KDB: reentering\n"); 565 kdb_backtrace(); 566 longjmp(kdb_jmpbufp, 1); 567 /* NOTREACHED */ 568 } 569 570 void 571 kdb_reenter_silent(void) 572 { 573 574 if (!kdb_active || kdb_jmpbufp == NULL) 575 return; 576 577 longjmp(kdb_jmpbufp, 1); 578 /* NOTREACHED */ 579 } 580 581 /* 582 * Thread-related support functions. 583 */ 584 struct pcb * 585 kdb_thr_ctx(struct thread *thr) 586 { 587 #if defined(SMP) && defined(KDB_STOPPEDPCB) 588 struct pcpu *pc; 589 #endif 590 591 if (thr == curthread) 592 return (&kdb_pcb); 593 594 #if defined(SMP) && defined(KDB_STOPPEDPCB) 595 STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { 596 if (pc->pc_curthread == thr && 597 CPU_ISSET(pc->pc_cpuid, &stopped_cpus)) 598 return (KDB_STOPPEDPCB(pc)); 599 } 600 #endif 601 return (thr->td_pcb); 602 } 603 604 struct thread * 605 kdb_thr_first(void) 606 { 607 struct proc *p; 608 struct thread *thr; 609 u_int i; 610 611 /* This function may be called early. */ 612 if (pidhashtbl == NULL) 613 return (&thread0); 614 615 for (i = 0; i <= pidhash; i++) { 616 LIST_FOREACH(p, &pidhashtbl[i], p_hash) { 617 thr = FIRST_THREAD_IN_PROC(p); 618 if (thr != NULL) 619 return (thr); 620 } 621 } 622 return (NULL); 623 } 624 625 struct thread * 626 kdb_thr_from_pid(pid_t pid) 627 { 628 struct proc *p; 629 630 LIST_FOREACH(p, PIDHASH(pid), p_hash) { 631 if (p->p_pid == pid) 632 return (FIRST_THREAD_IN_PROC(p)); 633 } 634 return (NULL); 635 } 636 637 struct thread * 638 kdb_thr_lookup(lwpid_t tid) 639 { 640 struct thread *thr; 641 642 thr = kdb_thr_first(); 643 while (thr != NULL && thr->td_tid != tid) 644 thr = kdb_thr_next(thr); 645 return (thr); 646 } 647 648 struct thread * 649 kdb_thr_next(struct thread *thr) 650 { 651 struct proc *p; 652 u_int hash; 653 654 p = thr->td_proc; 655 thr = TAILQ_NEXT(thr, td_plist); 656 if (thr != NULL) 657 return (thr); 658 if (pidhashtbl == NULL) 659 return (NULL); 660 hash = p->p_pid & pidhash; 661 for (;;) { 662 p = LIST_NEXT(p, p_hash); 663 while (p == NULL) { 664 if (++hash > pidhash) 665 return (NULL); 666 p = LIST_FIRST(&pidhashtbl[hash]); 667 } 668 thr = FIRST_THREAD_IN_PROC(p); 669 if (thr != NULL) 670 return (thr); 671 } 672 } 673 674 int 675 kdb_thr_select(struct thread *thr) 676 { 677 if (thr == NULL) 678 return (EINVAL); 679 kdb_thread = thr; 680 kdb_thrctx = kdb_thr_ctx(thr); 681 return (0); 682 } 683 684 /* 685 * Enter the debugger due to a trap. 686 */ 687 int 688 kdb_trap(int type, int code, struct trapframe *tf) 689 { 690 #ifdef SMP 691 cpuset_t other_cpus; 692 #endif 693 struct kdb_dbbe *be; 694 register_t intr; 695 int handled; 696 int did_stop_cpus; 697 698 be = kdb_dbbe; 699 if (be == NULL || be->dbbe_trap == NULL) 700 return (0); 701 702 /* We reenter the debugger through kdb_reenter(). */ 703 if (kdb_active) 704 return (0); 705 706 intr = intr_disable(); 707 708 if (!SCHEDULER_STOPPED()) { 709 #ifdef SMP 710 other_cpus = all_cpus; 711 CPU_ANDNOT(&other_cpus, &other_cpus, &stopped_cpus); 712 CPU_CLR(PCPU_GET(cpuid), &other_cpus); 713 stop_cpus_hard(other_cpus); 714 #endif 715 curthread->td_stopsched = 1; 716 did_stop_cpus = 1; 717 } else 718 did_stop_cpus = 0; 719 720 kdb_active++; 721 722 kdb_frame = tf; 723 724 /* Let MD code do its thing first... */ 725 kdb_cpu_trap(type, code); 726 727 makectx(tf, &kdb_pcb); 728 kdb_thr_select(curthread); 729 730 cngrab(); 731 732 for (;;) { 733 handled = be->dbbe_trap(type, code); 734 if (be == kdb_dbbe) 735 break; 736 be = kdb_dbbe; 737 if (be == NULL || be->dbbe_trap == NULL) 738 break; 739 printf("Switching to %s back-end\n", be->dbbe_name); 740 } 741 742 cnungrab(); 743 744 kdb_active--; 745 746 if (did_stop_cpus) { 747 curthread->td_stopsched = 0; 748 #ifdef SMP 749 CPU_AND(&other_cpus, &other_cpus, &stopped_cpus); 750 restart_cpus(other_cpus); 751 #endif 752 } 753 754 intr_restore(intr); 755 756 return (handled); 757 } 758