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 kdb_why = KDB_WHY_PANIC; 296 printf("KDB: panic\n"); 297 panic("%s", msg); 298 } 299 300 void 301 kdb_reboot(void) 302 { 303 304 kdb_why = KDB_WHY_REBOOT; 305 printf("KDB: reboot requested\n"); 306 shutdown_nice(0); 307 } 308 309 /* 310 * Solaris implements a new BREAK which is initiated by a character sequence 311 * CR ~ ^b which is similar to a familiar pattern used on Sun servers by the 312 * Remote Console. 313 * 314 * Note that this function may be called from almost anywhere, with interrupts 315 * disabled and with unknown locks held, so it must not access data other than 316 * its arguments. Its up to the caller to ensure that the state variable is 317 * consistent. 318 */ 319 #define KEY_CR 13 /* CR '\r' */ 320 #define KEY_TILDE 126 /* ~ */ 321 #define KEY_CRTLB 2 /* ^B */ 322 #define KEY_CRTLP 16 /* ^P */ 323 #define KEY_CRTLR 18 /* ^R */ 324 325 /* States of th KDB "alternate break sequence" detecting state machine. */ 326 enum { 327 KDB_ALT_BREAK_SEEN_NONE, 328 KDB_ALT_BREAK_SEEN_CR, 329 KDB_ALT_BREAK_SEEN_CR_TILDE, 330 }; 331 332 int 333 kdb_break(void) 334 { 335 336 if (!kdb_break_to_debugger) 337 return (0); 338 kdb_enter(KDB_WHY_BREAK, "Break to debugger"); 339 return (KDB_REQ_DEBUGGER); 340 } 341 342 static int 343 kdb_alt_break_state(int key, int *state) 344 { 345 int brk; 346 347 /* All states transition to KDB_ALT_BREAK_SEEN_CR on a CR. */ 348 if (key == KEY_CR) { 349 *state = KDB_ALT_BREAK_SEEN_CR; 350 return (0); 351 } 352 353 brk = 0; 354 switch (*state) { 355 case KDB_ALT_BREAK_SEEN_CR: 356 *state = KDB_ALT_BREAK_SEEN_NONE; 357 if (key == KEY_TILDE) 358 *state = KDB_ALT_BREAK_SEEN_CR_TILDE; 359 break; 360 case KDB_ALT_BREAK_SEEN_CR_TILDE: 361 *state = KDB_ALT_BREAK_SEEN_NONE; 362 if (key == KEY_CRTLB) 363 brk = KDB_REQ_DEBUGGER; 364 else if (key == KEY_CRTLP) 365 brk = KDB_REQ_PANIC; 366 else if (key == KEY_CRTLR) 367 brk = KDB_REQ_REBOOT; 368 break; 369 case KDB_ALT_BREAK_SEEN_NONE: 370 default: 371 *state = KDB_ALT_BREAK_SEEN_NONE; 372 break; 373 } 374 return (brk); 375 } 376 377 static int 378 kdb_alt_break_internal(int key, int *state, int force_gdb) 379 { 380 int brk; 381 382 if (!kdb_alt_break_to_debugger) 383 return (0); 384 brk = kdb_alt_break_state(key, state); 385 switch (brk) { 386 case KDB_REQ_DEBUGGER: 387 if (force_gdb) 388 kdb_dbbe_select("gdb"); 389 kdb_enter(KDB_WHY_BREAK, "Break to debugger"); 390 break; 391 392 case KDB_REQ_PANIC: 393 if (force_gdb) 394 kdb_dbbe_select("gdb"); 395 kdb_panic("Panic sequence on console"); 396 break; 397 398 case KDB_REQ_REBOOT: 399 kdb_reboot(); 400 break; 401 } 402 return (0); 403 } 404 405 int 406 kdb_alt_break(int key, int *state) 407 { 408 409 return (kdb_alt_break_internal(key, state, 0)); 410 } 411 412 /* 413 * This variation on kdb_alt_break() is used only by dcons, which has its own 414 * configuration flag to force GDB use regardless of the global KDB 415 * configuration. 416 */ 417 int 418 kdb_alt_break_gdb(int key, int *state) 419 { 420 421 return (kdb_alt_break_internal(key, state, 1)); 422 } 423 424 /* 425 * Print a backtrace of the calling thread. The backtrace is generated by 426 * the selected debugger, provided it supports backtraces. If no debugger 427 * is selected or the current debugger does not support backtraces, this 428 * function silently returns. 429 */ 430 void 431 kdb_backtrace(void) 432 { 433 434 if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) { 435 printf("KDB: stack backtrace:\n"); 436 kdb_dbbe->dbbe_trace(); 437 } 438 #ifdef STACK 439 else { 440 struct stack st; 441 442 printf("KDB: stack backtrace:\n"); 443 stack_save(&st); 444 stack_print_ddb(&st); 445 } 446 #endif 447 } 448 449 /* 450 * Similar to kdb_backtrace() except that it prints a backtrace of an 451 * arbitrary thread rather than the calling thread. 452 */ 453 void 454 kdb_backtrace_thread(struct thread *td) 455 { 456 457 if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace_thread != NULL) { 458 printf("KDB: stack backtrace of thread %d:\n", td->td_tid); 459 kdb_dbbe->dbbe_trace_thread(td); 460 } 461 #ifdef STACK 462 else { 463 struct stack st; 464 465 printf("KDB: stack backtrace of thread %d:\n", td->td_tid); 466 if (stack_save_td(&st, td) == 0) 467 stack_print_ddb(&st); 468 } 469 #endif 470 } 471 472 /* 473 * Set/change the current backend. 474 */ 475 int 476 kdb_dbbe_select(const char *name) 477 { 478 struct kdb_dbbe *be, **iter; 479 480 SET_FOREACH(iter, kdb_dbbe_set) { 481 be = *iter; 482 if (be->dbbe_active == 0 && strcmp(be->dbbe_name, name) == 0) { 483 kdb_dbbe = be; 484 return (0); 485 } 486 } 487 return (EINVAL); 488 } 489 490 /* 491 * Enter the currently selected debugger. If a message has been provided, 492 * it is printed first. If the debugger does not support the enter method, 493 * it is entered by using breakpoint(), which enters the debugger through 494 * kdb_trap(). The 'why' argument will contain a more mechanically usable 495 * string than 'msg', and is relied upon by DDB scripting to identify the 496 * reason for entering the debugger so that the right script can be run. 497 */ 498 void 499 kdb_enter(const char *why, const char *msg) 500 { 501 502 if (kdb_dbbe != NULL && kdb_active == 0) { 503 kdb_why = why; 504 if (msg != NULL) 505 printf("KDB: enter: %s\n", msg); 506 breakpoint(); 507 kdb_why = KDB_WHY_UNSET; 508 } 509 } 510 511 /* 512 * Initialize the kernel debugger interface. 513 */ 514 void 515 kdb_init(void) 516 { 517 struct kdb_dbbe *be, **iter; 518 int cur_pri, pri; 519 520 kdb_active = 0; 521 kdb_dbbe = NULL; 522 cur_pri = -1; 523 SET_FOREACH(iter, kdb_dbbe_set) { 524 be = *iter; 525 pri = (be->dbbe_init != NULL) ? be->dbbe_init() : -1; 526 be->dbbe_active = (pri >= 0) ? 0 : -1; 527 if (pri > cur_pri) { 528 cur_pri = pri; 529 kdb_dbbe = be; 530 } 531 } 532 if (kdb_dbbe != NULL) { 533 printf("KDB: debugger backends:"); 534 SET_FOREACH(iter, kdb_dbbe_set) { 535 be = *iter; 536 if (be->dbbe_active == 0) 537 printf(" %s", be->dbbe_name); 538 } 539 printf("\n"); 540 printf("KDB: current backend: %s\n", 541 kdb_dbbe->dbbe_name); 542 } 543 } 544 545 /* 546 * Handle contexts. 547 */ 548 void * 549 kdb_jmpbuf(jmp_buf new) 550 { 551 void *old; 552 553 old = kdb_jmpbufp; 554 kdb_jmpbufp = new; 555 return (old); 556 } 557 558 void 559 kdb_reenter(void) 560 { 561 562 if (!kdb_active || kdb_jmpbufp == NULL) 563 return; 564 565 printf("KDB: reentering\n"); 566 kdb_backtrace(); 567 longjmp(kdb_jmpbufp, 1); 568 /* NOTREACHED */ 569 } 570 571 void 572 kdb_reenter_silent(void) 573 { 574 575 if (!kdb_active || kdb_jmpbufp == NULL) 576 return; 577 578 longjmp(kdb_jmpbufp, 1); 579 /* NOTREACHED */ 580 } 581 582 /* 583 * Thread-related support functions. 584 */ 585 struct pcb * 586 kdb_thr_ctx(struct thread *thr) 587 { 588 #if defined(SMP) && defined(KDB_STOPPEDPCB) 589 struct pcpu *pc; 590 #endif 591 592 if (thr == curthread) 593 return (&kdb_pcb); 594 595 #if defined(SMP) && defined(KDB_STOPPEDPCB) 596 STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { 597 if (pc->pc_curthread == thr && 598 CPU_ISSET(pc->pc_cpuid, &stopped_cpus)) 599 return (KDB_STOPPEDPCB(pc)); 600 } 601 #endif 602 return (thr->td_pcb); 603 } 604 605 struct thread * 606 kdb_thr_first(void) 607 { 608 struct proc *p; 609 struct thread *thr; 610 u_int i; 611 612 /* This function may be called early. */ 613 if (pidhashtbl == NULL) 614 return (&thread0); 615 616 for (i = 0; i <= pidhash; i++) { 617 LIST_FOREACH(p, &pidhashtbl[i], p_hash) { 618 thr = FIRST_THREAD_IN_PROC(p); 619 if (thr != NULL) 620 return (thr); 621 } 622 } 623 return (NULL); 624 } 625 626 struct thread * 627 kdb_thr_from_pid(pid_t pid) 628 { 629 struct proc *p; 630 631 LIST_FOREACH(p, PIDHASH(pid), p_hash) { 632 if (p->p_pid == pid) 633 return (FIRST_THREAD_IN_PROC(p)); 634 } 635 return (NULL); 636 } 637 638 struct thread * 639 kdb_thr_lookup(lwpid_t tid) 640 { 641 struct thread *thr; 642 643 thr = kdb_thr_first(); 644 while (thr != NULL && thr->td_tid != tid) 645 thr = kdb_thr_next(thr); 646 return (thr); 647 } 648 649 struct thread * 650 kdb_thr_next(struct thread *thr) 651 { 652 struct proc *p; 653 u_int hash; 654 655 p = thr->td_proc; 656 thr = TAILQ_NEXT(thr, td_plist); 657 if (thr != NULL) 658 return (thr); 659 if (pidhashtbl == NULL) 660 return (NULL); 661 hash = p->p_pid & pidhash; 662 for (;;) { 663 p = LIST_NEXT(p, p_hash); 664 while (p == NULL) { 665 if (++hash > pidhash) 666 return (NULL); 667 p = LIST_FIRST(&pidhashtbl[hash]); 668 } 669 thr = FIRST_THREAD_IN_PROC(p); 670 if (thr != NULL) 671 return (thr); 672 } 673 } 674 675 int 676 kdb_thr_select(struct thread *thr) 677 { 678 if (thr == NULL) 679 return (EINVAL); 680 kdb_thread = thr; 681 kdb_thrctx = kdb_thr_ctx(thr); 682 return (0); 683 } 684 685 /* 686 * Enter the debugger due to a trap. 687 */ 688 int 689 kdb_trap(int type, int code, struct trapframe *tf) 690 { 691 #ifdef SMP 692 cpuset_t other_cpus; 693 #endif 694 struct kdb_dbbe *be; 695 register_t intr; 696 int handled; 697 int did_stop_cpus; 698 699 be = kdb_dbbe; 700 if (be == NULL || be->dbbe_trap == NULL) 701 return (0); 702 703 /* We reenter the debugger through kdb_reenter(). */ 704 if (kdb_active) 705 return (0); 706 707 intr = intr_disable(); 708 709 if (!SCHEDULER_STOPPED()) { 710 #ifdef SMP 711 other_cpus = all_cpus; 712 CPU_ANDNOT(&other_cpus, &other_cpus, &stopped_cpus); 713 CPU_CLR(PCPU_GET(cpuid), &other_cpus); 714 stop_cpus_hard(other_cpus); 715 #endif 716 curthread->td_stopsched = 1; 717 did_stop_cpus = 1; 718 } else 719 did_stop_cpus = 0; 720 721 kdb_active++; 722 723 kdb_frame = tf; 724 725 /* Let MD code do its thing first... */ 726 kdb_cpu_trap(type, code); 727 728 makectx(tf, &kdb_pcb); 729 kdb_thr_select(curthread); 730 731 cngrab(); 732 733 for (;;) { 734 handled = be->dbbe_trap(type, code); 735 if (be == kdb_dbbe) 736 break; 737 be = kdb_dbbe; 738 if (be == NULL || be->dbbe_trap == NULL) 739 break; 740 printf("Switching to %s back-end\n", be->dbbe_name); 741 } 742 743 cnungrab(); 744 745 kdb_active--; 746 747 if (did_stop_cpus) { 748 curthread->td_stopsched = 0; 749 #ifdef SMP 750 CPU_AND(&other_cpus, &other_cpus, &stopped_cpus); 751 restart_cpus(other_cpus); 752 #endif 753 } 754 755 intr_restore(intr); 756 757 return (handled); 758 } 759