1 /* 2 * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 * 6 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 7 * Distributed under the terms of the NewOS License. 8 */ 9 10 11 /*! This file contains the debugger and debug output facilities */ 12 13 14 #include "blue_screen.h" 15 16 #include <algorithm> 17 18 #include <cpu.h> 19 #include <debug.h> 20 #include <debug_heap.h> 21 #include <debug_paranoia.h> 22 #include <driver_settings.h> 23 #include <frame_buffer_console.h> 24 #include <int.h> 25 #include <kernel.h> 26 #include <ksystem_info.h> 27 #include <safemode.h> 28 #include <smp.h> 29 #include <thread.h> 30 #include <tracing.h> 31 #include <vm/vm.h> 32 #include <vm/VMTranslationMap.h> 33 34 #include <arch/debug_console.h> 35 #include <arch/debug.h> 36 #include <util/AutoLock.h> 37 #include <util/ring_buffer.h> 38 39 #include <syslog_daemon.h> 40 41 #include <ctype.h> 42 #include <stdarg.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <syslog.h> 47 48 #include "debug_builtin_commands.h" 49 #include "debug_commands.h" 50 #include "debug_output_filter.h" 51 #include "debug_variables.h" 52 53 54 struct debug_memcpy_parameters { 55 void* to; 56 const void* from; 57 size_t size; 58 }; 59 60 struct debug_strlcpy_parameters { 61 char* to; 62 const char* from; 63 size_t size; 64 size_t result; 65 }; 66 67 68 static const char* const kKDLPrompt = "kdebug> "; 69 70 extern "C" int kgets(char* buffer, int length); 71 72 void call_modules_hook(bool enter); 73 74 75 int dbg_register_file[B_MAX_CPU_COUNT][14]; 76 /* XXXmpetit -- must be made generic */ 77 78 static debug_page_fault_info sPageFaultInfo; 79 80 static bool sSerialDebugEnabled = true; 81 static bool sSyslogOutputEnabled = true; 82 static bool sBlueScreenEnabled = false; 83 // must always be false on startup 84 static bool sDebugScreenEnabled = false; 85 static bool sBlueScreenOutput = true; 86 static bool sEmergencyKeysEnabled = true; 87 static spinlock sSpinlock = B_SPINLOCK_INITIALIZER; 88 static int32 sDebuggerOnCPU = -1; 89 90 static sem_id sSyslogNotify = -1; 91 static struct syslog_message* sSyslogMessage; 92 static struct ring_buffer* sSyslogBuffer; 93 static bool sSyslogDropped = false; 94 95 static const char* sCurrentKernelDebuggerMessage; 96 97 #define DEFAULT_SYSLOG_BUFFER_SIZE 65536 98 #define OUTPUT_BUFFER_SIZE 1024 99 static char sOutputBuffer[OUTPUT_BUFFER_SIZE]; 100 static char sInterruptOutputBuffer[OUTPUT_BUFFER_SIZE]; 101 static char sLastOutputBuffer[OUTPUT_BUFFER_SIZE]; 102 static DebugOutputFilter* sDebugOutputFilter = NULL; 103 DefaultDebugOutputFilter gDefaultDebugOutputFilter; 104 static mutex sOutputLock = MUTEX_INITIALIZER("debug output"); 105 106 static void flush_pending_repeats(bool syslogOutput); 107 static void check_pending_repeats(void* data, int iter); 108 109 static int64 sMessageRepeatFirstTime = 0; 110 static int64 sMessageRepeatLastTime = 0; 111 static int32 sMessageRepeatCount = 0; 112 113 static debugger_module_info* sDebuggerModules[8]; 114 static const uint32 kMaxDebuggerModules = sizeof(sDebuggerModules) 115 / sizeof(sDebuggerModules[0]); 116 117 #define LINE_BUFFER_SIZE 1024 118 #define HISTORY_SIZE 16 119 120 static char sLineBuffer[HISTORY_SIZE][LINE_BUFFER_SIZE] = { "", }; 121 static int32 sCurrentLine = 0; 122 123 static debugger_demangle_module_info* sDemangleModule; 124 125 static struct thread* sDebuggedThread; 126 static vint32 sInDebugger = 0; 127 static bool sPreviousDprintfState; 128 static volatile bool sHandOverKDL = false; 129 static vint32 sHandOverKDLToCPU = -1; 130 static bool sCPUTrapped[B_MAX_CPU_COUNT]; 131 132 133 #define distance(a, b) ((a) < (b) ? (b) - (a) : (a) - (b)) 134 135 136 // #pragma mark - DebugOutputFilter 137 138 139 DebugOutputFilter::DebugOutputFilter() 140 { 141 } 142 143 144 DebugOutputFilter::~DebugOutputFilter() 145 { 146 } 147 148 149 void 150 DebugOutputFilter::PrintString(const char* string) 151 { 152 } 153 154 155 void 156 DebugOutputFilter::Print(const char* format, va_list args) 157 { 158 } 159 160 161 void 162 DefaultDebugOutputFilter::PrintString(const char* string) 163 { 164 if (sSerialDebugEnabled) 165 arch_debug_serial_puts(string); 166 if (sBlueScreenEnabled || sDebugScreenEnabled) 167 blue_screen_puts(string); 168 169 for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++) { 170 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 171 sDebuggerModules[i]->debugger_puts(string, strlen(string)); 172 } 173 } 174 175 176 void 177 DefaultDebugOutputFilter::Print(const char* format, va_list args) 178 { 179 vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, format, args); 180 flush_pending_repeats(sInDebugger == 0); 181 PrintString(sInterruptOutputBuffer); 182 } 183 184 185 // #pragma mark - 186 187 188 DebugOutputFilter* 189 set_debug_output_filter(DebugOutputFilter* filter) 190 { 191 DebugOutputFilter* oldFilter = sDebugOutputFilter; 192 sDebugOutputFilter = filter; 193 return oldFilter; 194 } 195 196 197 static void 198 kputchar(char c) 199 { 200 if (sSerialDebugEnabled) 201 arch_debug_serial_putchar(c); 202 if (sBlueScreenEnabled || sDebugScreenEnabled) 203 blue_screen_putchar(c); 204 for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++) 205 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 206 sDebuggerModules[i]->debugger_puts(&c, sizeof(c)); 207 } 208 209 210 void 211 kputs(const char* s) 212 { 213 if (sDebugOutputFilter != NULL) 214 sDebugOutputFilter->PrintString(s); 215 } 216 217 218 void 219 kputs_unfiltered(const char* s) 220 { 221 gDefaultDebugOutputFilter.PrintString(s); 222 } 223 224 225 static void 226 insert_chars_into_line(char* buffer, int32& position, int32& length, 227 const char* chars, int32 charCount) 228 { 229 // move the following chars to make room for the ones to insert 230 if (position < length) { 231 memmove(buffer + position + charCount, buffer + position, 232 length - position); 233 } 234 235 // insert chars 236 memcpy(buffer + position, chars, charCount); 237 int32 oldPosition = position; 238 position += charCount; 239 length += charCount; 240 241 // print the new chars (and the following ones) 242 kprintf("%.*s", (int)(length - oldPosition), 243 buffer + oldPosition); 244 245 // reposition cursor, if necessary 246 if (position < length) 247 kprintf("\x1b[%ldD", length - position); 248 } 249 250 251 static void 252 insert_char_into_line(char* buffer, int32& position, int32& length, char c) 253 { 254 insert_chars_into_line(buffer, position, length, &c, 1); 255 } 256 257 258 static void 259 remove_char_from_line(char* buffer, int32& position, int32& length) 260 { 261 if (position == length) 262 return; 263 264 length--; 265 266 if (position < length) { 267 // move the subsequent chars 268 memmove(buffer + position, buffer + position + 1, length - position); 269 270 // print the rest of the line again, if necessary 271 for (int32 i = position; i < length; i++) 272 kputchar(buffer[i]); 273 } 274 275 // visually clear the last char 276 kputchar(' '); 277 278 // reposition the cursor 279 kprintf("\x1b[%ldD", length - position + 1); 280 } 281 282 283 class LineEditingHelper { 284 public: 285 virtual ~LineEditingHelper() {} 286 287 virtual void TabCompletion(char* buffer, int32 capacity, int32& position, 288 int32& length) = 0; 289 }; 290 291 292 class CommandLineEditingHelper : public LineEditingHelper { 293 public: 294 CommandLineEditingHelper() 295 { 296 } 297 298 virtual ~CommandLineEditingHelper() {} 299 300 virtual void TabCompletion(char* buffer, int32 capacity, int32& position, 301 int32& length) 302 { 303 // find the first space 304 char tmpChar = buffer[position]; 305 buffer[position] = '\0'; 306 char* firstSpace = strchr(buffer, ' '); 307 buffer[position] = tmpChar; 308 309 bool reprintLine = false; 310 311 if (firstSpace != NULL) { 312 // a complete command -- print its help 313 314 // get the command 315 tmpChar = *firstSpace; 316 *firstSpace = '\0'; 317 bool ambiguous; 318 debugger_command* command = find_debugger_command(buffer, true, ambiguous); 319 *firstSpace = tmpChar; 320 321 if (command != NULL) { 322 kputchar('\n'); 323 print_debugger_command_usage(command->name); 324 } else { 325 if (ambiguous) 326 kprintf("\nambiguous command\n"); 327 else 328 kprintf("\nno such command\n"); 329 } 330 331 reprintLine = true; 332 } else { 333 // a partial command -- look for completions 334 335 // check for possible completions 336 int32 count = 0; 337 int32 longestName = 0; 338 debugger_command* command = NULL; 339 int32 longestCommonPrefix = 0; 340 const char* previousCommandName = NULL; 341 while ((command = next_debugger_command(command, buffer, position)) 342 != NULL) { 343 count++; 344 int32 nameLength = strlen(command->name); 345 longestName = max_c(longestName, nameLength); 346 347 // updated the length of the longest common prefix of the 348 // commands 349 if (count == 1) { 350 longestCommonPrefix = longestName; 351 } else { 352 longestCommonPrefix = min_c(longestCommonPrefix, 353 nameLength); 354 355 for (int32 i = position; i < longestCommonPrefix; i++) { 356 if (previousCommandName[i] != command->name[i]) { 357 longestCommonPrefix = i; 358 break; 359 } 360 } 361 } 362 363 previousCommandName = command->name; 364 } 365 366 if (count == 0) { 367 // no possible completions 368 kprintf("\nno completions\n"); 369 reprintLine = true; 370 } else if (count == 1) { 371 // exactly one completion 372 command = next_debugger_command(NULL, buffer, position); 373 374 // check for sufficient space in the buffer 375 int32 neededSpace = longestName - position + 1; 376 // remainder of the name plus one space 377 // also consider the terminating null char 378 if (length + neededSpace + 1 >= capacity) 379 return; 380 381 insert_chars_into_line(buffer, position, length, 382 command->name + position, longestName - position); 383 insert_char_into_line(buffer, position, length, ' '); 384 } else if (longestCommonPrefix > position) { 385 // multiple possible completions with longer common prefix 386 // -- insert the remainder of the common prefix 387 388 // check for sufficient space in the buffer 389 int32 neededSpace = longestCommonPrefix - position; 390 // also consider the terminating null char 391 if (length + neededSpace + 1 >= capacity) 392 return; 393 394 insert_chars_into_line(buffer, position, length, 395 previousCommandName + position, neededSpace); 396 } else { 397 // multiple possible completions without longer common prefix 398 // -- print them all 399 kprintf("\n"); 400 reprintLine = true; 401 402 int columns = 80 / (longestName + 2); 403 debugger_command* command = NULL; 404 int column = 0; 405 while ((command = next_debugger_command(command, buffer, position)) 406 != NULL) { 407 // spacing 408 if (column > 0 && column % columns == 0) 409 kputchar('\n'); 410 column++; 411 412 kprintf(" %-*s", (int)longestName, command->name); 413 } 414 kputchar('\n'); 415 } 416 } 417 418 // reprint the editing line, if necessary 419 if (reprintLine) { 420 kprintf("%s%.*s", kKDLPrompt, (int)length, buffer); 421 if (position < length) 422 kprintf("\x1b[%ldD", length - position); 423 } 424 } 425 }; 426 427 428 static int 429 read_line(char* buffer, int32 maxLength, 430 LineEditingHelper* editingHelper = NULL) 431 { 432 int32 currentHistoryLine = sCurrentLine; 433 int32 position = 0; 434 int32 length = 0; 435 bool done = false; 436 char c = 0; 437 438 while (!done) { 439 c = kgetc(); 440 441 switch (c) { 442 case '\n': 443 case '\r': 444 buffer[length++] = '\0'; 445 kputchar('\n'); 446 done = true; 447 break; 448 case '\t': 449 { 450 if (editingHelper != NULL) { 451 editingHelper->TabCompletion(buffer, maxLength, 452 position, length); 453 } 454 break; 455 } 456 case 8: // backspace 457 if (position > 0) { 458 kputs("\x1b[1D"); // move to the left one 459 position--; 460 remove_char_from_line(buffer, position, length); 461 } 462 break; 463 case 0x1f & 'K': // CTRL-K -- clear line after current position 464 if (position < length) { 465 // clear chars 466 for (int32 i = position; i < length; i++) 467 kputchar(' '); 468 469 // reposition cursor 470 kprintf("\x1b[%ldD", length - position); 471 472 length = position; 473 } 474 break; 475 case 0x1f & 'L': // CTRL-L -- clear screen 476 if (sBlueScreenOutput) { 477 // All the following needs to be transparent for the 478 // serial debug output. I.e. after clearing the screen 479 // we have to get the on-screen line into the visual state 480 // it should have. 481 482 // clear screen 483 blue_screen_clear_screen(); 484 485 // reprint line 486 buffer[length] = '\0'; 487 blue_screen_puts(kKDLPrompt); 488 blue_screen_puts(buffer); 489 490 // reposition cursor 491 if (position < length) { 492 for (int i = length; i > position; i--) 493 blue_screen_puts("\x1b[1D"); 494 } 495 } 496 break; 497 case 27: // escape sequence 498 c = kgetc(); 499 if (c != '[') { 500 // ignore broken escape sequence 501 break; 502 } 503 c = kgetc(); 504 switch (c) { 505 case 'C': // right arrow 506 if (position < length) { 507 kputs("\x1b[1C"); // move to the right one 508 position++; 509 } 510 break; 511 case 'D': // left arrow 512 if (position > 0) { 513 kputs("\x1b[1D"); // move to the left one 514 position--; 515 } 516 break; 517 case 'A': // up arrow 518 case 'B': // down arrow 519 { 520 int32 historyLine = 0; 521 522 if (c == 'A') { 523 // up arrow 524 historyLine = currentHistoryLine - 1; 525 if (historyLine < 0) 526 historyLine = HISTORY_SIZE - 1; 527 } else { 528 // down arrow 529 if (currentHistoryLine == sCurrentLine) 530 break; 531 532 historyLine = currentHistoryLine + 1; 533 if (historyLine >= HISTORY_SIZE) 534 historyLine = 0; 535 } 536 537 // clear the history again if we're in the current line again 538 // (the buffer we get just is the current line buffer) 539 if (historyLine == sCurrentLine) { 540 sLineBuffer[historyLine][0] = '\0'; 541 } else if (sLineBuffer[historyLine][0] == '\0') { 542 // empty history lines are unused -- so bail out 543 break; 544 } 545 546 // swap the current line with something from the history 547 if (position > 0) 548 kprintf("\x1b[%ldD", position); // move to beginning of line 549 550 strcpy(buffer, sLineBuffer[historyLine]); 551 length = position = strlen(buffer); 552 kprintf("%s\x1b[K", buffer); // print the line and clear the rest 553 currentHistoryLine = historyLine; 554 break; 555 } 556 case '5': // if "5~", it's PAGE UP 557 case '6': // if "6~", it's PAGE DOWN 558 { 559 if (kgetc() != '~') 560 break; 561 562 // PAGE UP: search backward, PAGE DOWN: forward 563 int32 searchDirection = (c == '5' ? -1 : 1); 564 565 bool found = false; 566 int32 historyLine = currentHistoryLine; 567 do { 568 historyLine = (historyLine + searchDirection 569 + HISTORY_SIZE) % HISTORY_SIZE; 570 if (historyLine == sCurrentLine) 571 break; 572 573 if (strncmp(sLineBuffer[historyLine], buffer, 574 position) == 0) { 575 found = true; 576 } 577 } while (!found); 578 579 // bail out, if we've found nothing or hit an empty 580 // (i.e. unused) history line 581 if (!found || strlen(sLineBuffer[historyLine]) == 0) 582 break; 583 584 // found a suitable line -- replace the current buffer 585 // content with it 586 strcpy(buffer, sLineBuffer[historyLine]); 587 length = strlen(buffer); 588 kprintf("%s\x1b[K", buffer + position); 589 // print the line and clear the rest 590 kprintf("\x1b[%ldD", length - position); 591 // reposition cursor 592 currentHistoryLine = historyLine; 593 594 break; 595 } 596 case 'H': // home 597 { 598 if (position > 0) { 599 kprintf("\x1b[%ldD", position); 600 position = 0; 601 } 602 break; 603 } 604 case 'F': // end 605 { 606 if (position < length) { 607 kprintf("\x1b[%ldC", length - position); 608 position = length; 609 } 610 break; 611 } 612 case '3': // if "3~", it's DEL 613 { 614 if (kgetc() != '~') 615 break; 616 617 if (position < length) 618 remove_char_from_line(buffer, position, length); 619 620 break; 621 } 622 default: 623 break; 624 } 625 break; 626 case '$': 627 case '+': 628 if (!sBlueScreenOutput) { 629 /* HACK ALERT!!! 630 * 631 * If we get a $ at the beginning of the line 632 * we assume we are talking with GDB 633 */ 634 if (position == 0) { 635 strcpy(buffer, "gdb"); 636 position = 4; 637 done = true; 638 break; 639 } 640 } 641 /* supposed to fall through */ 642 default: 643 if (isprint(c)) 644 insert_char_into_line(buffer, position, length, c); 645 break; 646 } 647 648 if (length >= maxLength - 2) { 649 buffer[length++] = '\0'; 650 kputchar('\n'); 651 done = true; 652 break; 653 } 654 } 655 656 return length; 657 } 658 659 660 char 661 kgetc(void) 662 { 663 // give the kernel debugger modules a chance first 664 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 665 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_getchar) { 666 int getChar = sDebuggerModules[i]->debugger_getchar(); 667 if (getChar >= 0) 668 return (char)getChar; 669 } 670 } 671 672 if (sBlueScreenOutput) 673 return blue_screen_getchar(); 674 675 return arch_debug_serial_getchar(); 676 } 677 678 679 int 680 kgets(char* buffer, int length) 681 { 682 return read_line(buffer, length); 683 } 684 685 686 static void 687 kernel_debugger_loop(const char* message, int32 cpu) 688 { 689 int32 previousCPU = sDebuggerOnCPU; 690 sDebuggerOnCPU = cpu; 691 692 DebugAllocPool* allocPool = create_debug_alloc_pool(); 693 694 sCurrentKernelDebuggerMessage = message; 695 696 if (message) 697 kprintf("PANIC: %s\n", message); 698 699 kprintf("Welcome to Kernel Debugging Land...\n"); 700 701 // Set a few temporary debug variables and print on which CPU and in which 702 // thread we are running. 703 set_debug_variable("_cpu", sDebuggerOnCPU); 704 705 struct thread* thread = thread_get_current_thread(); 706 if (thread == NULL) { 707 kprintf("Running on CPU %ld\n", sDebuggerOnCPU); 708 } else if (!debug_is_kernel_memory_accessible((addr_t)thread, 709 sizeof(struct thread), B_KERNEL_READ_AREA)) { 710 kprintf("Running on CPU %ld\n", sDebuggerOnCPU); 711 kprintf("Current thread pointer is %p, which is an address we " 712 "can't read from.\n", thread); 713 arch_debug_unset_current_thread(); 714 } else { 715 set_debug_variable("_thread", (uint64)(addr_t)thread); 716 set_debug_variable("_threadID", thread->id); 717 718 kprintf("Thread %ld \"%.64s\" running on CPU %ld\n", thread->id, 719 thread->name, sDebuggerOnCPU); 720 721 if (thread->cpu != gCPU + cpu) { 722 kprintf("The thread's CPU pointer is %p, but should be %p.\n", 723 thread->cpu, gCPU + cpu); 724 arch_debug_unset_current_thread(); 725 } else if (thread->team != NULL) { 726 if (debug_is_kernel_memory_accessible((addr_t)thread->team, 727 sizeof(struct team), B_KERNEL_READ_AREA)) { 728 set_debug_variable("_team", (uint64)(addr_t)thread->team); 729 set_debug_variable("_teamID", thread->team->id); 730 } else { 731 kprintf("The thread's team pointer is %p, which is an " 732 "address we can't read from.\n", thread->team); 733 arch_debug_unset_current_thread(); 734 } 735 } 736 } 737 738 if (!has_debugger_command("help")) 739 arch_debug_stack_trace(); 740 741 int32 continuableLine = -1; 742 // Index of the previous command line, if the command returned 743 // B_KDEBUG_CONT, i.e. asked to be repeatable, -1 otherwise. 744 745 for (;;) { 746 CommandLineEditingHelper editingHelper; 747 kprintf(kKDLPrompt); 748 char* line = sLineBuffer[sCurrentLine]; 749 read_line(line, LINE_BUFFER_SIZE, &editingHelper); 750 751 // check, if the line is empty or whitespace only 752 bool whiteSpaceOnly = true; 753 for (int i = 0 ; line[i] != '\0'; i++) { 754 if (!isspace(line[i])) { 755 whiteSpaceOnly = false; 756 break; 757 } 758 } 759 760 if (whiteSpaceOnly) { 761 if (continuableLine < 0) 762 continue; 763 764 // the previous command can be repeated 765 sCurrentLine = continuableLine; 766 line = sLineBuffer[sCurrentLine]; 767 } 768 769 int rc = evaluate_debug_command(line); 770 771 if (rc == B_KDEBUG_QUIT) { 772 // okay, exit now. 773 break; 774 } 775 776 // If the command is continuable, remember the current line index. 777 continuableLine = (rc == B_KDEBUG_CONT ? sCurrentLine : -1); 778 779 int previousLine = sCurrentLine - 1; 780 if (previousLine < 0) 781 previousLine = HISTORY_SIZE - 1; 782 783 // Only use the next slot in the history, if the entries differ 784 if (strcmp(sLineBuffer[sCurrentLine], sLineBuffer[previousLine])) { 785 if (++sCurrentLine >= HISTORY_SIZE) 786 sCurrentLine = 0; 787 } 788 } 789 790 delete_debug_alloc_pool(allocPool); 791 792 sDebuggerOnCPU = previousCPU; 793 } 794 795 796 static void 797 enter_kernel_debugger(int32 cpu) 798 { 799 while (atomic_add(&sInDebugger, 1) > 0) { 800 // The debugger is already running, find out where... 801 if (sDebuggerOnCPU == cpu) { 802 // We are re-entering the debugger on the same CPU. 803 break; 804 } 805 806 // Some other CPU must have entered the debugger and tried to halt 807 // us. Process ICIs to ensure we get the halt request. Then we are 808 // blocking there until everyone leaves the debugger and we can 809 // try to enter it again. 810 atomic_add(&sInDebugger, -1); 811 smp_intercpu_int_handler(cpu); 812 } 813 814 arch_debug_save_registers(&dbg_register_file[cpu][0]); 815 sPreviousDprintfState = set_dprintf_enabled(true); 816 817 if (!gKernelStartup && sDebuggerOnCPU != cpu && smp_get_num_cpus() > 1) { 818 // First entry on a MP system, send a halt request to all of the other 819 // CPUs. Should they try to enter the debugger they will be cought in 820 // the loop above. 821 smp_send_broadcast_ici_interrupts_disabled(cpu, SMP_MSG_CPU_HALT, 0, 0, 822 0, NULL, SMP_MSG_FLAG_SYNC); 823 } 824 825 if (sBlueScreenOutput) { 826 if (blue_screen_enter(false) == B_OK) 827 sBlueScreenEnabled = true; 828 } 829 830 sDebugOutputFilter = &gDefaultDebugOutputFilter; 831 832 sDebuggedThread = NULL; 833 834 // sort the commands 835 sort_debugger_commands(); 836 837 call_modules_hook(true); 838 } 839 840 841 static void 842 exit_kernel_debugger() 843 { 844 call_modules_hook(false); 845 set_dprintf_enabled(sPreviousDprintfState); 846 847 sDebugOutputFilter = NULL; 848 849 sBlueScreenEnabled = false; 850 if (sDebugScreenEnabled) 851 blue_screen_enter(true); 852 853 atomic_add(&sInDebugger, -1); 854 } 855 856 857 static void 858 hand_over_kernel_debugger() 859 { 860 // Wait until the hand-over is complete. 861 // The other CPU gets our sInDebugger reference and will release it when 862 // done. Note, that there's a small race condition: the other CPU could 863 // hand over to another CPU without us noticing. Since this is only 864 // initiated by the user, it is harmless, though. 865 sHandOverKDL = true; 866 while (sHandOverKDLToCPU >= 0) 867 PAUSE(); 868 } 869 870 871 static void 872 kernel_debugger_internal(const char* message, int32 cpu) 873 { 874 while (true) { 875 if (sHandOverKDLToCPU == cpu) { 876 sHandOverKDLToCPU = -1; 877 sHandOverKDL = false; 878 } else 879 enter_kernel_debugger(cpu); 880 881 kernel_debugger_loop(message, cpu); 882 883 if (sHandOverKDLToCPU < 0) { 884 exit_kernel_debugger(); 885 break; 886 } 887 888 hand_over_kernel_debugger(); 889 890 debug_trap_cpu_in_kdl(cpu, true); 891 892 if (sHandOverKDLToCPU != cpu) 893 break; 894 } 895 } 896 897 898 static int 899 cmd_dump_kdl_message(int argc, char** argv) 900 { 901 if (sCurrentKernelDebuggerMessage) { 902 kputs(sCurrentKernelDebuggerMessage); 903 kputs("\n"); 904 } 905 906 return 0; 907 } 908 909 910 static int 911 cmd_dump_syslog(int argc, char** argv) 912 { 913 if (!sSyslogOutputEnabled) { 914 kprintf("Syslog is not enabled.\n"); 915 return 0; 916 } 917 918 bool currentOnly = false; 919 if (argc > 1) { 920 if (!strcmp(argv[1], "-n")) 921 currentOnly = true; 922 else { 923 print_debugger_command_usage(argv[0]); 924 return 0; 925 } 926 } 927 928 uint32 start = sSyslogBuffer->first; 929 size_t end = start + sSyslogBuffer->in; 930 if (!currentOnly) { 931 // Start the buffer after the current end (we don't really know if 932 // this part has been written to already). 933 start = (start + sSyslogBuffer->in) % sSyslogBuffer->size; 934 end = start + sSyslogBuffer->size; 935 } else if (!ring_buffer_readable(sSyslogBuffer)) { 936 kprintf("Syslog is empty.\n"); 937 return 0; 938 } 939 940 // break it down to lines to make it grep'able 941 942 bool newLine = false; 943 char line[256]; 944 size_t linePos = 0; 945 for (uint32 i = start; i < end; i++) { 946 char c = sSyslogBuffer->buffer[i % sSyslogBuffer->size]; 947 if (c == '\0' || (uint8)c == 0xcc) 948 continue; 949 950 line[linePos++] = c; 951 newLine = false; 952 953 if (c == '\n' || linePos == sizeof(line) - 1) { 954 newLine = c == '\n'; 955 line[linePos] = '\0'; 956 linePos = 0; 957 kprintf(line); 958 } 959 } 960 if (!newLine) 961 kprintf("\n"); 962 963 return 0; 964 } 965 966 967 static int 968 cmd_switch_cpu(int argc, char** argv) 969 { 970 if (argc > 2) { 971 print_debugger_command_usage(argv[0]); 972 return 0; 973 } 974 975 if (argc == 1) { 976 kprintf("running on CPU %ld\n", smp_get_current_cpu()); 977 return 0; 978 } 979 980 int32 newCPU = parse_expression(argv[1]); 981 if (newCPU < 0 || newCPU >= smp_get_num_cpus()) { 982 kprintf("invalid CPU index\n"); 983 return 0; 984 } 985 986 if (newCPU == smp_get_current_cpu()) { 987 kprintf("already running on CPU %ld\n", newCPU); 988 return 0; 989 } 990 991 sHandOverKDLToCPU = newCPU; 992 993 return B_KDEBUG_QUIT; 994 } 995 996 997 static status_t 998 syslog_sender(void* data) 999 { 1000 status_t error = B_BAD_PORT_ID; 1001 port_id port = -1; 1002 bool bufferPending = false; 1003 int32 length = 0; 1004 1005 while (true) { 1006 // wait for syslog data to become available 1007 acquire_sem(sSyslogNotify); 1008 1009 sSyslogMessage->when = real_time_clock(); 1010 1011 if (error == B_BAD_PORT_ID) { 1012 // last message couldn't be sent, try to locate the syslog_daemon 1013 port = find_port(SYSLOG_PORT_NAME); 1014 } 1015 1016 if (port >= B_OK) { 1017 if (!bufferPending) { 1018 // we need to have exclusive access to our syslog buffer 1019 cpu_status state = disable_interrupts(); 1020 acquire_spinlock(&sSpinlock); 1021 1022 length = ring_buffer_readable(sSyslogBuffer); 1023 if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH) 1024 length = SYSLOG_MAX_MESSAGE_LENGTH; 1025 1026 length = ring_buffer_read(sSyslogBuffer, 1027 (uint8*)sSyslogMessage->message, length); 1028 if (sSyslogDropped) { 1029 // Add drop marker - since parts had to be dropped, it's 1030 // guaranteed that we have enough space in the buffer now. 1031 ring_buffer_write(sSyslogBuffer, (uint8*)"<DROP>", 6); 1032 sSyslogDropped = false; 1033 } 1034 1035 release_spinlock(&sSpinlock); 1036 restore_interrupts(state); 1037 } 1038 1039 if (length == 0) { 1040 // the buffer we came here for might have been sent already 1041 bufferPending = false; 1042 continue; 1043 } 1044 1045 error = write_port_etc(port, SYSLOG_MESSAGE, sSyslogMessage, 1046 sizeof(struct syslog_message) + length, B_RELATIVE_TIMEOUT, 0); 1047 1048 if (error < B_OK) { 1049 // sending has failed - just wait, maybe it'll work later. 1050 bufferPending = true; 1051 continue; 1052 } 1053 1054 if (bufferPending) { 1055 // we could write the last pending buffer, try to read more 1056 // from the syslog ring buffer 1057 release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE); 1058 bufferPending = false; 1059 } 1060 } 1061 } 1062 1063 return 0; 1064 } 1065 1066 1067 static void 1068 syslog_write(const char* text, int32 length) 1069 { 1070 bool trunc = false; 1071 1072 if (sSyslogBuffer == NULL) 1073 return; 1074 1075 if ((int32)ring_buffer_writable(sSyslogBuffer) < length) { 1076 // truncate data 1077 length = ring_buffer_writable(sSyslogBuffer); 1078 1079 if (length > 8) { 1080 trunc = true; 1081 length -= 8; 1082 } else 1083 sSyslogDropped = true; 1084 } 1085 1086 ring_buffer_write(sSyslogBuffer, (uint8*)text, length); 1087 if (trunc) 1088 ring_buffer_write(sSyslogBuffer, (uint8*)"<TRUNC>", 7); 1089 1090 release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE); 1091 } 1092 1093 1094 static status_t 1095 syslog_init_post_threads(void) 1096 { 1097 if (!sSyslogOutputEnabled) 1098 return B_OK; 1099 1100 sSyslogNotify = create_sem(0, "syslog data"); 1101 if (sSyslogNotify >= B_OK) { 1102 thread_id thread = spawn_kernel_thread(syslog_sender, "syslog sender", 1103 B_LOW_PRIORITY, NULL); 1104 if (thread >= B_OK && resume_thread(thread) == B_OK) 1105 return B_OK; 1106 } 1107 1108 // initializing kernel syslog service failed -- disable it 1109 1110 sSyslogOutputEnabled = false; 1111 free(sSyslogMessage); 1112 free(sSyslogBuffer); 1113 delete_sem(sSyslogNotify); 1114 1115 return B_ERROR; 1116 } 1117 1118 1119 static status_t 1120 syslog_init(struct kernel_args* args) 1121 { 1122 status_t status; 1123 int32 length = 0; 1124 1125 if (!sSyslogOutputEnabled) 1126 return B_OK; 1127 1128 sSyslogMessage = (syslog_message*)malloc(SYSLOG_MESSAGE_BUFFER_SIZE); 1129 if (sSyslogMessage == NULL) { 1130 status = B_NO_MEMORY; 1131 goto err1; 1132 } 1133 1134 { 1135 size_t bufferSize = DEFAULT_SYSLOG_BUFFER_SIZE; 1136 void* handle = load_driver_settings("kernel"); 1137 if (handle != NULL) { 1138 const char* sizeString = get_driver_parameter(handle, 1139 "syslog_buffer_size", NULL, NULL); 1140 if (sizeString != NULL) { 1141 bufferSize = strtoul(sizeString, NULL, 0); 1142 if (bufferSize > 262144) 1143 bufferSize = 262144; 1144 else if (bufferSize < SYSLOG_MESSAGE_BUFFER_SIZE) 1145 bufferSize = SYSLOG_MESSAGE_BUFFER_SIZE; 1146 } 1147 1148 unload_driver_settings(handle); 1149 } 1150 1151 sSyslogBuffer = create_ring_buffer(bufferSize); 1152 } 1153 if (sSyslogBuffer == NULL) { 1154 status = B_NO_MEMORY; 1155 goto err2; 1156 } 1157 1158 // initialize syslog message 1159 sSyslogMessage->from = 0; 1160 sSyslogMessage->options = LOG_KERN; 1161 sSyslogMessage->priority = LOG_DEBUG; 1162 sSyslogMessage->ident[0] = '\0'; 1163 //strcpy(sSyslogMessage->ident, "KERNEL"); 1164 1165 if (args->debug_output != NULL) 1166 syslog_write((const char*)args->debug_output, args->debug_size); 1167 1168 char revisionBuffer[64]; 1169 length = snprintf(revisionBuffer, sizeof(revisionBuffer), 1170 "Welcome to syslog debug output!\nHaiku revision: %lu\n", 1171 get_haiku_revision()); 1172 syslog_write(revisionBuffer, 1173 std::min(length, (ssize_t)sizeof(revisionBuffer) - 1)); 1174 1175 add_debugger_command_etc("syslog", &cmd_dump_syslog, 1176 "Dumps the syslog buffer.", 1177 "[-n]\nDumps the whole syslog buffer, or, if -n is specified, only " 1178 "the part that hasn't been sent yet.\n", 0); 1179 1180 return B_OK; 1181 1182 err2: 1183 free(sSyslogMessage); 1184 err1: 1185 sSyslogOutputEnabled = false; 1186 return status; 1187 } 1188 1189 1190 static void 1191 debug_memcpy_trampoline(void* _parameters) 1192 { 1193 debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters; 1194 memcpy(parameters->to, parameters->from, parameters->size); 1195 } 1196 1197 1198 static void 1199 debug_strlcpy_trampoline(void* _parameters) 1200 { 1201 debug_strlcpy_parameters* parameters 1202 = (debug_strlcpy_parameters*)_parameters; 1203 parameters->result = strlcpy(parameters->to, parameters->from, 1204 parameters->size); 1205 } 1206 1207 1208 void 1209 call_modules_hook(bool enter) 1210 { 1211 uint32 index = 0; 1212 while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) { 1213 debugger_module_info* module = sDebuggerModules[index]; 1214 1215 if (enter && module->enter_debugger != NULL) 1216 module->enter_debugger(); 1217 else if (!enter && module->exit_debugger != NULL) 1218 module->exit_debugger(); 1219 1220 index++; 1221 } 1222 } 1223 1224 1225 //! Must be called with the sSpinlock held. 1226 static void 1227 debug_output(const char* string, int32 length, bool syslogOutput) 1228 { 1229 if (length >= OUTPUT_BUFFER_SIZE) 1230 length = OUTPUT_BUFFER_SIZE - 1; 1231 1232 if (length > 1 && string[length - 1] == '\n' 1233 && strncmp(string, sLastOutputBuffer, length) == 0) { 1234 sMessageRepeatCount++; 1235 sMessageRepeatLastTime = system_time(); 1236 if (sMessageRepeatFirstTime == 0) 1237 sMessageRepeatFirstTime = sMessageRepeatLastTime; 1238 } else { 1239 flush_pending_repeats(syslogOutput); 1240 1241 if (sSerialDebugEnabled) 1242 arch_debug_serial_puts(string); 1243 if (sSyslogOutputEnabled && syslogOutput) 1244 syslog_write(string, length); 1245 if (sBlueScreenEnabled || sDebugScreenEnabled) 1246 blue_screen_puts(string); 1247 if (sSerialDebugEnabled) { 1248 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1249 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 1250 sDebuggerModules[i]->debugger_puts(string, length); 1251 } 1252 } 1253 1254 memcpy(sLastOutputBuffer, string, length); 1255 sLastOutputBuffer[length] = 0; 1256 } 1257 } 1258 1259 1260 //! Must be called with the sSpinlock held. 1261 static void 1262 flush_pending_repeats(bool syslogOutput) 1263 { 1264 if (sMessageRepeatCount <= 0) 1265 return; 1266 1267 if (sMessageRepeatCount > 1) { 1268 static char temp[40]; 1269 size_t length = snprintf(temp, sizeof(temp), 1270 "Last message repeated %ld times.\n", sMessageRepeatCount); 1271 length = std::min(length, sizeof(temp) - 1); 1272 1273 if (sSerialDebugEnabled) 1274 arch_debug_serial_puts(temp); 1275 if (sSyslogOutputEnabled && syslogOutput) 1276 syslog_write(temp, length); 1277 if (sBlueScreenEnabled || sDebugScreenEnabled) 1278 blue_screen_puts(temp); 1279 if (sSerialDebugEnabled) { 1280 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1281 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 1282 sDebuggerModules[i]->debugger_puts(temp, length); 1283 } 1284 } 1285 } else { 1286 // if we only have one repeat just reprint the last buffer 1287 size_t length = strlen(sLastOutputBuffer); 1288 1289 if (sSerialDebugEnabled) 1290 arch_debug_serial_puts(sLastOutputBuffer); 1291 if (sSyslogOutputEnabled && syslogOutput) 1292 syslog_write(sLastOutputBuffer, length); 1293 if (sBlueScreenEnabled || sDebugScreenEnabled) 1294 blue_screen_puts(sLastOutputBuffer); 1295 if (sSerialDebugEnabled) { 1296 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1297 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) { 1298 sDebuggerModules[i]->debugger_puts(sLastOutputBuffer, 1299 length); 1300 } 1301 } 1302 } 1303 } 1304 1305 sMessageRepeatFirstTime = 0; 1306 sMessageRepeatCount = 0; 1307 } 1308 1309 1310 static void 1311 check_pending_repeats(void* /*data*/, int /*iteration*/) 1312 { 1313 if (sMessageRepeatCount > 0 1314 && (system_time() - sMessageRepeatLastTime > 1000000 1315 || system_time() - sMessageRepeatFirstTime > 3000000)) { 1316 cpu_status state = disable_interrupts(); 1317 acquire_spinlock(&sSpinlock); 1318 1319 flush_pending_repeats(true); 1320 1321 release_spinlock(&sSpinlock); 1322 restore_interrupts(state); 1323 } 1324 } 1325 1326 1327 static void 1328 dprintf_args(const char* format, va_list args, bool syslogOutput) 1329 { 1330 if (are_interrupts_enabled()) { 1331 MutexLocker locker(sOutputLock); 1332 1333 int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format, 1334 args); 1335 length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1); 1336 1337 InterruptsSpinLocker _(sSpinlock); 1338 debug_output(sOutputBuffer, length, syslogOutput); 1339 } else { 1340 InterruptsSpinLocker _(sSpinlock); 1341 1342 int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, 1343 format, args); 1344 length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1); 1345 1346 debug_output(sInterruptOutputBuffer, length, syslogOutput); 1347 } 1348 } 1349 1350 1351 // #pragma mark - private kernel API 1352 1353 1354 bool 1355 debug_screen_output_enabled(void) 1356 { 1357 return sDebugScreenEnabled; 1358 } 1359 1360 1361 void 1362 debug_stop_screen_debug_output(void) 1363 { 1364 sDebugScreenEnabled = false; 1365 } 1366 1367 1368 bool 1369 debug_debugger_running(void) 1370 { 1371 return sDebuggerOnCPU != -1; 1372 } 1373 1374 1375 void 1376 debug_puts(const char* string, int32 length) 1377 { 1378 InterruptsSpinLocker _(sSpinlock); 1379 debug_output(string, length, sSyslogOutputEnabled); 1380 } 1381 1382 1383 void 1384 debug_early_boot_message(const char* string) 1385 { 1386 arch_debug_serial_early_boot_message(string); 1387 } 1388 1389 1390 status_t 1391 debug_init(kernel_args* args) 1392 { 1393 new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter; 1394 1395 debug_paranoia_init(); 1396 return arch_debug_console_init(args); 1397 } 1398 1399 1400 status_t 1401 debug_init_post_vm(kernel_args* args) 1402 { 1403 add_debugger_command_etc("cpu", &cmd_switch_cpu, 1404 "Switches to another CPU.", 1405 "<cpu>\n" 1406 "Switches to CPU with the index <cpu>.\n", 0); 1407 add_debugger_command_etc("message", &cmd_dump_kdl_message, 1408 "Reprint the message printed when entering KDL", 1409 "\n" 1410 "Reprints the message printed when entering KDL.\n", 0); 1411 1412 debug_builtin_commands_init(); 1413 1414 debug_heap_init(); 1415 debug_variables_init(); 1416 frame_buffer_console_init(args); 1417 arch_debug_console_init_settings(args); 1418 tracing_init(); 1419 1420 // get debug settings 1421 1422 sSerialDebugEnabled = get_safemode_boolean("serial_debug_output", 1423 sSerialDebugEnabled); 1424 sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output", 1425 sSyslogOutputEnabled); 1426 sBlueScreenOutput = get_safemode_boolean("bluescreen", true); 1427 sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys", 1428 sEmergencyKeysEnabled); 1429 sDebugScreenEnabled = get_safemode_boolean("debug_screen", false); 1430 1431 if ((sBlueScreenOutput || sDebugScreenEnabled) 1432 && blue_screen_init() != B_OK) 1433 sBlueScreenOutput = sDebugScreenEnabled = false; 1434 1435 if (sDebugScreenEnabled) 1436 blue_screen_enter(true); 1437 1438 syslog_init(args); 1439 1440 return arch_debug_init(args); 1441 } 1442 1443 1444 status_t 1445 debug_init_post_modules(struct kernel_args* args) 1446 { 1447 void* cookie; 1448 1449 // check for dupped lines every 10/10 second 1450 register_kernel_daemon(check_pending_repeats, NULL, 10); 1451 1452 syslog_init_post_threads(); 1453 1454 // load kernel debugger addons 1455 1456 static const char* kDemanglePrefix = "debugger/demangle/"; 1457 1458 cookie = open_module_list("debugger"); 1459 uint32 count = 0; 1460 while (count < kMaxDebuggerModules) { 1461 char name[B_FILE_NAME_LENGTH]; 1462 size_t nameLength = sizeof(name); 1463 1464 if (read_next_module_name(cookie, name, &nameLength) != B_OK) 1465 break; 1466 1467 // get demangle module, if any 1468 if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) { 1469 if (sDemangleModule == NULL) 1470 get_module(name, (module_info**)&sDemangleModule); 1471 continue; 1472 } 1473 1474 if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) { 1475 dprintf("kernel debugger extension \"%s\": loaded\n", name); 1476 count++; 1477 } else 1478 dprintf("kernel debugger extension \"%s\": failed to load\n", name); 1479 } 1480 close_module_list(cookie); 1481 1482 return frame_buffer_console_init_post_modules(args); 1483 } 1484 1485 1486 void 1487 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags) 1488 { 1489 sPageFaultInfo.fault_address = faultAddress; 1490 sPageFaultInfo.pc = pc; 1491 sPageFaultInfo.flags = flags; 1492 } 1493 1494 1495 debug_page_fault_info* 1496 debug_get_page_fault_info() 1497 { 1498 return &sPageFaultInfo; 1499 } 1500 1501 1502 void 1503 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver) 1504 { 1505 InterruptsLocker locker; 1506 1507 // return, if we've been called recursively (we call 1508 // smp_intercpu_int_handler() below) 1509 if (sCPUTrapped[cpu]) 1510 return; 1511 1512 sCPUTrapped[cpu] = true; 1513 1514 while (sInDebugger != 0) { 1515 if (sHandOverKDL && sHandOverKDLToCPU == cpu) { 1516 if (returnIfHandedOver) 1517 break; 1518 1519 kernel_debugger_internal(NULL, cpu); 1520 } else 1521 smp_intercpu_int_handler(cpu); 1522 } 1523 1524 sCPUTrapped[cpu] = false; 1525 } 1526 1527 1528 void 1529 debug_double_fault(int32 cpu) 1530 { 1531 kernel_debugger_internal("Double Fault!\n", cpu); 1532 } 1533 1534 1535 bool 1536 debug_emergency_key_pressed(char key) 1537 { 1538 if (!sEmergencyKeysEnabled) 1539 return false; 1540 1541 if (key == 'd') { 1542 kernel_debugger("Keyboard Requested Halt."); 1543 return true; 1544 } 1545 1546 // Broadcast to the kernel debugger modules 1547 1548 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1549 if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) { 1550 if (sDebuggerModules[i]->emergency_key_pressed(key)) 1551 return true; 1552 } 1553 } 1554 1555 return false; 1556 } 1557 1558 1559 /*! Verifies that the complete given memory range is accessible in the current 1560 context. 1561 1562 Invoked in the kernel debugger only. 1563 1564 \param address The start address of the memory range to be checked. 1565 \param size The size of the memory range to be checked. 1566 \param protection The area protection for which to check. Valid is a bitwise 1567 or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA. 1568 \return \c true, if the complete memory range can be accessed in all ways 1569 specified by \a protection, \c false otherwise. 1570 */ 1571 bool 1572 debug_is_kernel_memory_accessible(addr_t address, size_t size, 1573 uint32 protection) 1574 { 1575 addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE); 1576 address = ROUNDDOWN(address, B_PAGE_SIZE); 1577 1578 if (!IS_KERNEL_ADDRESS(address) || endAddress < address) 1579 return false; 1580 1581 for (; address < endAddress; address += B_PAGE_SIZE) { 1582 if (!arch_vm_translation_map_is_kernel_page_accessible(address, 1583 protection)) { 1584 return false; 1585 } 1586 } 1587 1588 return true; 1589 } 1590 1591 1592 /*! Calls a function in a setjmp() + fault handler context. 1593 May only be used in the kernel debugger. 1594 1595 \param jumpBuffer Buffer to be used for setjmp()/longjmp(). 1596 \param function The function to be called. 1597 \param parameter The parameter to be passed to the function to be called. 1598 \return 1599 - \c 0, when the function executed without causing a page fault or 1600 calling longjmp(). 1601 - \c 1, when the function caused a page fault. 1602 - Any other value the function passes to longjmp(). 1603 */ 1604 int 1605 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*), 1606 void* parameter) 1607 { 1608 // save current fault handler 1609 cpu_ent* cpu = gCPU + sDebuggerOnCPU; 1610 addr_t oldFaultHandler = cpu->fault_handler; 1611 addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer; 1612 1613 int result = setjmp(jumpBuffer); 1614 if (result == 0) { 1615 arch_debug_call_with_fault_handler(cpu, jumpBuffer, function, 1616 parameter); 1617 } 1618 1619 // restore old fault handler 1620 cpu->fault_handler = oldFaultHandler; 1621 cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer; 1622 1623 return result; 1624 } 1625 1626 1627 /*! Similar to user_memcpy(), but can only be invoked from within the kernel 1628 debugger (and must not be used outside). 1629 */ 1630 status_t 1631 debug_memcpy(void* to, const void* from, size_t size) 1632 { 1633 // don't allow address overflows 1634 if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to) 1635 return B_BAD_ADDRESS; 1636 1637 debug_memcpy_parameters parameters = {to, from, size}; 1638 1639 if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer, 1640 &debug_memcpy_trampoline, ¶meters) != 0) { 1641 return B_BAD_ADDRESS; 1642 } 1643 return B_OK; 1644 } 1645 1646 1647 /*! Similar to user_strlcpy(), but can only be invoked from within the kernel 1648 debugger (and must not be used outside). 1649 */ 1650 ssize_t 1651 debug_strlcpy(char* to, const char* from, size_t size) 1652 { 1653 if (size == 0) 1654 return 0; 1655 if (from == NULL || to == NULL) 1656 return B_BAD_ADDRESS; 1657 1658 // limit size to avoid address overflows 1659 size_t maxSize = std::min(size, 1660 ~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1); 1661 // NOTE: Since strlcpy() determines the length of \a from, the source 1662 // address might still overflow. 1663 1664 debug_strlcpy_parameters parameters = {to, from, maxSize}; 1665 1666 if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer, 1667 &debug_strlcpy_trampoline, ¶meters) != 0) { 1668 return B_BAD_ADDRESS; 1669 } 1670 1671 // If we hit the address overflow boundary, fail. 1672 if (parameters.result >= maxSize && maxSize < size) 1673 return B_BAD_ADDRESS; 1674 1675 return parameters.result; 1676 } 1677 1678 1679 // #pragma mark - public API 1680 1681 1682 uint64 1683 parse_expression(const char* expression) 1684 { 1685 uint64 result; 1686 return evaluate_debug_expression(expression, &result, true) ? result : 0; 1687 } 1688 1689 1690 void 1691 panic(const char* format, ...) 1692 { 1693 va_list args; 1694 char temp[128]; 1695 1696 va_start(args, format); 1697 vsnprintf(temp, sizeof(temp), format, args); 1698 va_end(args); 1699 1700 kernel_debugger(temp); 1701 } 1702 1703 1704 void 1705 kernel_debugger(const char* message) 1706 { 1707 cpu_status state = disable_interrupts(); 1708 1709 kernel_debugger_internal(message, smp_get_current_cpu()); 1710 1711 restore_interrupts(state); 1712 } 1713 1714 1715 bool 1716 set_dprintf_enabled(bool newState) 1717 { 1718 bool oldState = sSerialDebugEnabled; 1719 sSerialDebugEnabled = newState; 1720 1721 return oldState; 1722 } 1723 1724 1725 void 1726 dprintf(const char* format, ...) 1727 { 1728 va_list args; 1729 1730 if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled) 1731 return; 1732 1733 va_start(args, format); 1734 dprintf_args(format, args, sSyslogOutputEnabled); 1735 va_end(args); 1736 } 1737 1738 1739 void 1740 dprintf_no_syslog(const char* format, ...) 1741 { 1742 va_list args; 1743 1744 if (!sSerialDebugEnabled && !sBlueScreenEnabled) 1745 return; 1746 1747 va_start(args, format); 1748 dprintf_args(format, args, false); 1749 va_end(args); 1750 } 1751 1752 1753 /*! Similar to dprintf() but thought to be used in the kernel 1754 debugger only (it doesn't lock). 1755 */ 1756 void 1757 kprintf(const char* format, ...) 1758 { 1759 if (sDebugOutputFilter != NULL) { 1760 va_list args; 1761 va_start(args, format); 1762 sDebugOutputFilter->Print(format, args); 1763 va_end(args); 1764 } 1765 } 1766 1767 1768 void 1769 kprintf_unfiltered(const char* format, ...) 1770 { 1771 va_list args; 1772 va_start(args, format); 1773 gDefaultDebugOutputFilter.Print(format, args); 1774 va_end(args); 1775 } 1776 1777 1778 const char* 1779 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize, 1780 bool* _isObjectMethod) 1781 { 1782 if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) { 1783 return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize, 1784 _isObjectMethod); 1785 } 1786 1787 if (_isObjectMethod != NULL) 1788 *_isObjectMethod = false; 1789 1790 return symbol; 1791 } 1792 1793 1794 status_t 1795 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol, 1796 char* name, size_t nameSize, int32* _type, size_t* _argumentLength) 1797 { 1798 if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) { 1799 return sDemangleModule->get_next_argument(_cookie, symbol, name, 1800 nameSize, _type, _argumentLength); 1801 } 1802 1803 return B_NOT_SUPPORTED; 1804 } 1805 1806 1807 struct thread* 1808 debug_set_debugged_thread(struct thread* thread) 1809 { 1810 struct thread* previous = sDebuggedThread; 1811 sDebuggedThread = thread; 1812 return previous; 1813 } 1814 1815 1816 struct thread* 1817 debug_get_debugged_thread() 1818 { 1819 return sDebuggedThread != NULL 1820 ? sDebuggedThread : thread_get_current_thread(); 1821 } 1822 1823 1824 // #pragma mark - 1825 // userland syscalls 1826 1827 1828 status_t 1829 _user_kernel_debugger(const char *userMessage) 1830 { 1831 if (geteuid() != 0) 1832 return B_NOT_ALLOWED; 1833 1834 char message[512]; 1835 strcpy(message, "USER: "); 1836 size_t len = strlen(message); 1837 1838 if (userMessage == NULL || !IS_USER_ADDRESS(userMessage) 1839 || user_strlcpy(message + len, userMessage, sizeof(message) - len) 1840 < 0) { 1841 return B_BAD_ADDRESS; 1842 } 1843 1844 kernel_debugger(message); 1845 return B_OK; 1846 } 1847 1848 1849 void 1850 _user_debug_output(const char* userString) 1851 { 1852 char string[512]; 1853 int32 length; 1854 1855 if (!sSerialDebugEnabled && !sSyslogOutputEnabled) 1856 return; 1857 1858 if (!IS_USER_ADDRESS(userString)) 1859 return; 1860 1861 do { 1862 length = user_strlcpy(string, userString, sizeof(string)); 1863 debug_puts(string, length); 1864 userString += sizeof(string) - 1; 1865 } while (length >= (ssize_t)sizeof(string)); 1866 } 1867 1868 1869 void 1870 dump_block(const char* buffer, int size, const char* prefix) 1871 { 1872 const int DUMPED_BLOCK_SIZE = 16; 1873 int i; 1874 1875 for (i = 0; i < size;) { 1876 int start = i; 1877 1878 dprintf("%s%04x ", prefix, i); 1879 for (; i < start + DUMPED_BLOCK_SIZE; i++) { 1880 if (!(i % 4)) 1881 dprintf(" "); 1882 1883 if (i >= size) 1884 dprintf(" "); 1885 else 1886 dprintf("%02x", *(unsigned char*)(buffer + i)); 1887 } 1888 dprintf(" "); 1889 1890 for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) { 1891 if (i < size) { 1892 char c = buffer[i]; 1893 1894 if (c < 30) 1895 dprintf("."); 1896 else 1897 dprintf("%c", c); 1898 } else 1899 break; 1900 } 1901 dprintf("\n"); 1902 } 1903 } 1904