1 /* 2 * Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2002-2010, 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 <ctype.h> 17 #include <errno.h> 18 #include <stdarg.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <syslog.h> 23 24 #include <algorithm> 25 26 #include <AutoDeleter.h> 27 #include <boot/kernel_args.h> 28 #include <cpu.h> 29 #include <debug.h> 30 #include <debug_heap.h> 31 #include <debug_paranoia.h> 32 #include <driver_settings.h> 33 #include <frame_buffer_console.h> 34 #include <int.h> 35 #include <kernel.h> 36 #include <ksystem_info.h> 37 #include <safemode.h> 38 #include <smp.h> 39 #include <thread.h> 40 #include <tracing.h> 41 #include <vm/vm.h> 42 #include <vm/VMTranslationMap.h> 43 44 #include <arch/debug_console.h> 45 #include <arch/debug.h> 46 #include <util/AutoLock.h> 47 #include <util/ring_buffer.h> 48 49 #include <syslog_daemon.h> 50 51 #include "debug_builtin_commands.h" 52 #include "debug_commands.h" 53 #include "debug_output_filter.h" 54 #include "debug_variables.h" 55 56 57 #if __GNUC__ == 2 58 # define va_copy(to, from) __va_copy(to, from) 59 #endif 60 61 62 struct debug_memcpy_parameters { 63 void* to; 64 const void* from; 65 size_t size; 66 }; 67 68 struct debug_strlcpy_parameters { 69 char* to; 70 const char* from; 71 size_t size; 72 size_t result; 73 }; 74 75 76 static const char* const kKDLPrompt = "kdebug> "; 77 static const char* const kKDLMessageCommandSeparator = "@!"; 78 // separates panic() message from command list to execute 79 80 extern "C" int kgets(char* buffer, int length); 81 82 void call_modules_hook(bool enter); 83 84 static void syslog_write(const char* text, int32 length, bool notify); 85 86 static arch_debug_registers sDebugRegisters[SMP_MAX_CPUS]; 87 88 static debug_page_fault_info sPageFaultInfo; 89 90 static bool sSerialDebugEnabled = true; 91 static bool sSyslogOutputEnabled = true; 92 static bool sBlueScreenEnabled = false; 93 // must always be false on startup 94 static bool sDebugScreenEnabled = false; 95 static bool sBlueScreenOutput = true; 96 static bool sEmergencyKeysEnabled = true; 97 static spinlock sSpinlock = B_SPINLOCK_INITIALIZER; 98 static int32 sDebuggerOnCPU = -1; 99 100 static sem_id sSyslogNotify = -1; 101 static struct syslog_message* sSyslogMessage; 102 static struct ring_buffer* sSyslogBuffer; 103 static size_t sSyslogBufferOffset = 0; 104 // (relative) buffer offset of the yet unsent syslog messages 105 static bool sSyslogDropped = false; 106 static bool sDebugSyslog = false; 107 static size_t sSyslogDebuggerOffset = 0; 108 // (relative) buffer offset of the kernel debugger messages of the current 109 // KDL session 110 111 static void* sPreviousSessionSyslogBuffer = NULL; 112 static size_t sPreviousSessionSyslogBufferSize = 0; 113 114 static const char* sCurrentKernelDebuggerMessagePrefix; 115 static const char* sCurrentKernelDebuggerMessage; 116 static va_list sCurrentKernelDebuggerMessageArgs; 117 118 #define DEFAULT_SYSLOG_BUFFER_SIZE 65536 119 #define OUTPUT_BUFFER_SIZE 1024 120 static char sOutputBuffer[OUTPUT_BUFFER_SIZE]; 121 static char sInterruptOutputBuffer[OUTPUT_BUFFER_SIZE]; 122 static char sLastOutputBuffer[OUTPUT_BUFFER_SIZE]; 123 static DebugOutputFilter* sDebugOutputFilter = NULL; 124 DefaultDebugOutputFilter gDefaultDebugOutputFilter; 125 static mutex sOutputLock = MUTEX_INITIALIZER("debug output"); 126 127 static void flush_pending_repeats(bool notifySyslog); 128 static void check_pending_repeats(void* data, int iter); 129 130 static int64 sMessageRepeatFirstTime = 0; 131 static int64 sMessageRepeatLastTime = 0; 132 static int32 sMessageRepeatCount = 0; 133 134 static debugger_module_info* sDebuggerModules[8]; 135 static const uint32 kMaxDebuggerModules = sizeof(sDebuggerModules) 136 / sizeof(sDebuggerModules[0]); 137 138 #define LINE_BUFFER_SIZE 1024 139 #define HISTORY_SIZE 16 140 141 static char sLineBuffer[HISTORY_SIZE][LINE_BUFFER_SIZE] = { "", }; 142 static int32 sCurrentLine = 0; 143 144 static debugger_demangle_module_info* sDemangleModule; 145 146 static Thread* sDebuggedThread; 147 static int32 sInDebugger = 0; 148 static bool sPreviousDprintfState; 149 static volatile bool sHandOverKDL = false; 150 static int32 sHandOverKDLToCPU = -1; 151 static bool sCPUTrapped[SMP_MAX_CPUS]; 152 153 154 #define distance(a, b) ((a) < (b) ? (b) - (a) : (a) - (b)) 155 156 157 // #pragma mark - DebugOutputFilter 158 159 160 DebugOutputFilter::DebugOutputFilter() 161 { 162 } 163 164 165 DebugOutputFilter::~DebugOutputFilter() 166 { 167 } 168 169 170 void 171 DebugOutputFilter::PrintString(const char* string) 172 { 173 } 174 175 176 void 177 DebugOutputFilter::Print(const char* format, va_list args) 178 { 179 } 180 181 182 void 183 DefaultDebugOutputFilter::PrintString(const char* string) 184 { 185 size_t length = strlen(string); 186 187 if (sSerialDebugEnabled) 188 arch_debug_serial_puts(string); 189 if (sSyslogOutputEnabled) 190 syslog_write(string, length, false); 191 if (sBlueScreenEnabled || sDebugScreenEnabled) 192 blue_screen_puts(string); 193 194 for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++) { 195 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 196 sDebuggerModules[i]->debugger_puts(string, length); 197 } 198 } 199 200 201 void 202 DefaultDebugOutputFilter::Print(const char* format, va_list args) 203 { 204 vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, format, args); 205 flush_pending_repeats(false); 206 PrintString(sInterruptOutputBuffer); 207 } 208 209 210 // #pragma mark - 211 212 213 DebugOutputFilter* 214 set_debug_output_filter(DebugOutputFilter* filter) 215 { 216 DebugOutputFilter* oldFilter = sDebugOutputFilter; 217 sDebugOutputFilter = filter; 218 return oldFilter; 219 } 220 221 222 static void 223 kputchar(char c) 224 { 225 if (sSerialDebugEnabled) 226 arch_debug_serial_putchar(c); 227 if (sBlueScreenEnabled || sDebugScreenEnabled) 228 blue_screen_putchar(c); 229 for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++) 230 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 231 sDebuggerModules[i]->debugger_puts(&c, sizeof(c)); 232 } 233 234 235 void 236 kputs(const char* s) 237 { 238 if (sDebugOutputFilter != NULL) 239 sDebugOutputFilter->PrintString(s); 240 } 241 242 243 void 244 kputs_unfiltered(const char* s) 245 { 246 gDefaultDebugOutputFilter.PrintString(s); 247 } 248 249 250 static void 251 insert_chars_into_line(char* buffer, int32& position, int32& length, 252 const char* chars, int32 charCount) 253 { 254 // move the following chars to make room for the ones to insert 255 if (position < length) { 256 memmove(buffer + position + charCount, buffer + position, 257 length - position); 258 } 259 260 // insert chars 261 memcpy(buffer + position, chars, charCount); 262 int32 oldPosition = position; 263 position += charCount; 264 length += charCount; 265 266 // print the new chars (and the following ones) 267 kprintf("%.*s", (int)(length - oldPosition), 268 buffer + oldPosition); 269 270 // reposition cursor, if necessary 271 if (position < length) 272 kprintf("\x1b[%" B_PRId32 "D", length - position); 273 } 274 275 276 static void 277 insert_char_into_line(char* buffer, int32& position, int32& length, char c) 278 { 279 insert_chars_into_line(buffer, position, length, &c, 1); 280 } 281 282 283 static void 284 remove_char_from_line(char* buffer, int32& position, int32& length) 285 { 286 if (position == length) 287 return; 288 289 length--; 290 291 if (position < length) { 292 // move the subsequent chars 293 memmove(buffer + position, buffer + position + 1, length - position); 294 295 // print the rest of the line again, if necessary 296 for (int32 i = position; i < length; i++) 297 kputchar(buffer[i]); 298 } 299 300 // visually clear the last char 301 kputchar(' '); 302 303 // reposition the cursor 304 kprintf("\x1b[%" B_PRId32 "D", length - position + 1); 305 } 306 307 308 class LineEditingHelper { 309 public: 310 virtual ~LineEditingHelper() {} 311 312 virtual void TabCompletion(char* buffer, int32 capacity, int32& position, 313 int32& length) = 0; 314 }; 315 316 317 class CommandLineEditingHelper : public LineEditingHelper { 318 public: 319 CommandLineEditingHelper() 320 { 321 } 322 323 virtual ~CommandLineEditingHelper() {} 324 325 virtual void TabCompletion(char* buffer, int32 capacity, int32& position, 326 int32& length) 327 { 328 // find the first space 329 char tmpChar = buffer[position]; 330 buffer[position] = '\0'; 331 char* firstSpace = strchr(buffer, ' '); 332 buffer[position] = tmpChar; 333 334 bool reprintLine = false; 335 336 if (firstSpace != NULL) { 337 // a complete command -- print its help 338 339 // get the command 340 tmpChar = *firstSpace; 341 *firstSpace = '\0'; 342 bool ambiguous; 343 debugger_command* command = find_debugger_command(buffer, true, ambiguous); 344 *firstSpace = tmpChar; 345 346 if (command != NULL) { 347 kputchar('\n'); 348 print_debugger_command_usage(command->name); 349 } else { 350 if (ambiguous) 351 kprintf("\nambiguous command\n"); 352 else 353 kprintf("\nno such command\n"); 354 } 355 356 reprintLine = true; 357 } else { 358 // a partial command -- look for completions 359 360 // check for possible completions 361 int32 count = 0; 362 int32 longestName = 0; 363 debugger_command* command = NULL; 364 int32 longestCommonPrefix = 0; 365 const char* previousCommandName = NULL; 366 while ((command = next_debugger_command(command, buffer, position)) 367 != NULL) { 368 count++; 369 int32 nameLength = strlen(command->name); 370 longestName = max_c(longestName, nameLength); 371 372 // updated the length of the longest common prefix of the 373 // commands 374 if (count == 1) { 375 longestCommonPrefix = longestName; 376 } else { 377 longestCommonPrefix = min_c(longestCommonPrefix, 378 nameLength); 379 380 for (int32 i = position; i < longestCommonPrefix; i++) { 381 if (previousCommandName[i] != command->name[i]) { 382 longestCommonPrefix = i; 383 break; 384 } 385 } 386 } 387 388 previousCommandName = command->name; 389 } 390 391 if (count == 0) { 392 // no possible completions 393 kprintf("\nno completions\n"); 394 reprintLine = true; 395 } else if (count == 1) { 396 // exactly one completion 397 command = next_debugger_command(NULL, buffer, position); 398 399 // check for sufficient space in the buffer 400 int32 neededSpace = longestName - position + 1; 401 // remainder of the name plus one space 402 // also consider the terminating null char 403 if (length + neededSpace + 1 >= capacity) 404 return; 405 406 insert_chars_into_line(buffer, position, length, 407 command->name + position, longestName - position); 408 insert_char_into_line(buffer, position, length, ' '); 409 } else if (longestCommonPrefix > position) { 410 // multiple possible completions with longer common prefix 411 // -- insert the remainder of the common prefix 412 413 // check for sufficient space in the buffer 414 int32 neededSpace = longestCommonPrefix - position; 415 // also consider the terminating null char 416 if (length + neededSpace + 1 >= capacity) 417 return; 418 419 insert_chars_into_line(buffer, position, length, 420 previousCommandName + position, neededSpace); 421 } else { 422 // multiple possible completions without longer common prefix 423 // -- print them all 424 kprintf("\n"); 425 reprintLine = true; 426 427 int columns = 80 / (longestName + 2); 428 debugger_command* command = NULL; 429 int column = 0; 430 while ((command = next_debugger_command(command, buffer, position)) 431 != NULL) { 432 // spacing 433 if (column > 0 && column % columns == 0) 434 kputchar('\n'); 435 column++; 436 437 kprintf(" %-*s", (int)longestName, command->name); 438 } 439 kputchar('\n'); 440 } 441 } 442 443 // reprint the editing line, if necessary 444 if (reprintLine) { 445 kprintf("%s%.*s", kKDLPrompt, (int)length, buffer); 446 if (position < length) 447 kprintf("\x1b[%" B_PRId32 "D", length - position); 448 } 449 } 450 }; 451 452 453 static int 454 read_line(char* buffer, int32 maxLength, 455 LineEditingHelper* editingHelper = NULL) 456 { 457 int32 currentHistoryLine = sCurrentLine; 458 int32 position = 0; 459 int32 length = 0; 460 bool done = false; 461 char c = 0; 462 463 while (!done) { 464 c = kgetc(); 465 466 switch (c) { 467 case '\n': 468 case '\r': 469 buffer[length++] = '\0'; 470 kputchar('\n'); 471 done = true; 472 break; 473 case '\t': 474 { 475 if (editingHelper != NULL) { 476 editingHelper->TabCompletion(buffer, maxLength, 477 position, length); 478 } 479 break; 480 } 481 case 8: // backspace (CTRL-H) 482 case 0x7f: // backspace (xterm) 483 if (position > 0) { 484 kputs("\x1b[1D"); // move to the left one 485 position--; 486 remove_char_from_line(buffer, position, length); 487 } 488 break; 489 case 0x1f & 'K': // CTRL-K -- clear line after current position 490 if (position < length) { 491 // clear chars 492 for (int32 i = position; i < length; i++) 493 kputchar(' '); 494 495 // reposition cursor 496 kprintf("\x1b[%" B_PRId32 "D", length - position); 497 498 length = position; 499 } 500 break; 501 case 0x1f & 'L': // CTRL-L -- clear screen 502 if (sBlueScreenOutput) { 503 // All the following needs to be transparent for the 504 // serial debug output. I.e. after clearing the screen 505 // we have to get the on-screen line into the visual state 506 // it should have. 507 508 // clear screen 509 blue_screen_clear_screen(); 510 511 // reprint line 512 buffer[length] = '\0'; 513 blue_screen_puts(kKDLPrompt); 514 blue_screen_puts(buffer); 515 516 // reposition cursor 517 if (position < length) { 518 for (int i = length; i > position; i--) 519 blue_screen_puts("\x1b[1D"); 520 } 521 } 522 break; 523 case 27: // escape sequence 524 c = kgetc(); 525 if (c != '[') { 526 // ignore broken escape sequence 527 break; 528 } 529 c = kgetc(); 530 switch (c) { 531 case 'C': // right arrow 532 if (position < length) { 533 kputs("\x1b[1C"); // move to the right one 534 position++; 535 } 536 break; 537 case 'D': // left arrow 538 if (position > 0) { 539 kputs("\x1b[1D"); // move to the left one 540 position--; 541 } 542 break; 543 case 'A': // up arrow 544 case 'B': // down arrow 545 { 546 int32 historyLine = 0; 547 548 if (c == 'A') { 549 // up arrow 550 historyLine = currentHistoryLine - 1; 551 if (historyLine < 0) 552 historyLine = HISTORY_SIZE - 1; 553 } else { 554 // down arrow 555 if (currentHistoryLine == sCurrentLine) 556 break; 557 558 historyLine = currentHistoryLine + 1; 559 if (historyLine >= HISTORY_SIZE) 560 historyLine = 0; 561 } 562 563 // clear the history again if we're in the current line again 564 // (the buffer we get just is the current line buffer) 565 if (historyLine == sCurrentLine) { 566 sLineBuffer[historyLine][0] = '\0'; 567 } else if (sLineBuffer[historyLine][0] == '\0') { 568 // empty history lines are unused -- so bail out 569 break; 570 } 571 572 // swap the current line with something from the history 573 if (position > 0) 574 kprintf("\x1b[%" B_PRId32 "D", position); // move to beginning of line 575 576 strcpy(buffer, sLineBuffer[historyLine]); 577 length = position = strlen(buffer); 578 kprintf("%s\x1b[K", buffer); // print the line and clear the rest 579 currentHistoryLine = historyLine; 580 break; 581 } 582 case '5': // if "5~", it's PAGE UP 583 case '6': // if "6~", it's PAGE DOWN 584 { 585 if (kgetc() != '~') 586 break; 587 588 // PAGE UP: search backward, PAGE DOWN: forward 589 int32 searchDirection = (c == '5' ? -1 : 1); 590 591 bool found = false; 592 int32 historyLine = currentHistoryLine; 593 do { 594 historyLine = (historyLine + searchDirection 595 + HISTORY_SIZE) % HISTORY_SIZE; 596 if (historyLine == sCurrentLine) 597 break; 598 599 if (strncmp(sLineBuffer[historyLine], buffer, 600 position) == 0) { 601 found = true; 602 } 603 } while (!found); 604 605 // bail out, if we've found nothing or hit an empty 606 // (i.e. unused) history line 607 if (!found || strlen(sLineBuffer[historyLine]) == 0) 608 break; 609 610 // found a suitable line -- replace the current buffer 611 // content with it 612 strcpy(buffer, sLineBuffer[historyLine]); 613 length = strlen(buffer); 614 kprintf("%s\x1b[K", buffer + position); 615 // print the line and clear the rest 616 kprintf("\x1b[%" B_PRId32 "D", length - position); 617 // reposition cursor 618 currentHistoryLine = historyLine; 619 620 break; 621 } 622 case 'H': // home 623 { 624 if (position > 0) { 625 kprintf("\x1b[%" B_PRId32 "D", position); 626 position = 0; 627 } 628 break; 629 } 630 case 'F': // end 631 { 632 if (position < length) { 633 kprintf("\x1b[%" B_PRId32 "C", length - position); 634 position = length; 635 } 636 break; 637 } 638 case '3': // if "3~", it's DEL 639 { 640 if (kgetc() != '~') 641 break; 642 643 if (position < length) 644 remove_char_from_line(buffer, position, length); 645 646 break; 647 } 648 default: 649 break; 650 } 651 break; 652 case '$': 653 case '+': 654 if (!sBlueScreenOutput) { 655 /* HACK ALERT!!! 656 * 657 * If we get a $ at the beginning of the line 658 * we assume we are talking with GDB 659 */ 660 if (position == 0) { 661 strcpy(buffer, "gdb"); 662 position = 4; 663 done = true; 664 break; 665 } 666 } 667 /* supposed to fall through */ 668 default: 669 if (isprint(c)) 670 insert_char_into_line(buffer, position, length, c); 671 break; 672 } 673 674 if (length >= maxLength - 2) { 675 buffer[length++] = '\0'; 676 kputchar('\n'); 677 done = true; 678 break; 679 } 680 } 681 682 return length; 683 } 684 685 686 char 687 kgetc(void) 688 { 689 while (true) { 690 // check serial input 691 int c = arch_debug_serial_try_getchar(); 692 if (c >= 0) 693 return (char)c; 694 695 // check blue screen input 696 if (sBlueScreenOutput) { 697 c = blue_screen_try_getchar(); 698 if (c >= 0) 699 return (char)c; 700 } 701 702 // give the kernel debugger modules a chance 703 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 704 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_getchar) { 705 int getChar = sDebuggerModules[i]->debugger_getchar(); 706 if (getChar >= 0) 707 return (char)getChar; 708 } 709 } 710 711 cpu_pause(); 712 } 713 } 714 715 716 int 717 kgets(char* buffer, int length) 718 { 719 return read_line(buffer, length); 720 } 721 722 723 static void 724 print_kernel_debugger_message() 725 { 726 if (sCurrentKernelDebuggerMessagePrefix != NULL 727 || sCurrentKernelDebuggerMessage != NULL) { 728 if (sCurrentKernelDebuggerMessagePrefix != NULL) 729 kprintf("%s", sCurrentKernelDebuggerMessagePrefix); 730 if (sCurrentKernelDebuggerMessage != NULL 731 && sDebugOutputFilter != NULL) { 732 va_list args; 733 va_copy(args, sCurrentKernelDebuggerMessageArgs); 734 735 if (const char* commandDelimiter = strstr( 736 sCurrentKernelDebuggerMessage, 737 kKDLMessageCommandSeparator)) { 738 // The message string contains a list of commands to be 739 // executed when entering the kernel debugger. We don't 740 // want to print those, so we copy the interesting part of 741 // the format string. 742 if (commandDelimiter != sCurrentKernelDebuggerMessage) { 743 size_t length = commandDelimiter 744 - sCurrentKernelDebuggerMessage; 745 if (char* format = (char*)debug_malloc(length + 1)) { 746 memcpy(format, sCurrentKernelDebuggerMessage, length); 747 format[length] = '\0'; 748 sDebugOutputFilter->Print(format, args); 749 debug_free(format); 750 } else { 751 // allocation failed -- just print everything 752 sDebugOutputFilter->Print(sCurrentKernelDebuggerMessage, 753 args); 754 } 755 } 756 } else 757 sDebugOutputFilter->Print(sCurrentKernelDebuggerMessage, args); 758 759 va_end(args); 760 } 761 762 kprintf("\n"); 763 } 764 } 765 766 767 static void 768 execute_panic_commands() 769 { 770 if (sCurrentKernelDebuggerMessage == NULL 771 || strstr(sCurrentKernelDebuggerMessage, 772 kKDLMessageCommandSeparator) == NULL) { 773 return; 774 } 775 776 // Indeed there are commands to execute. 777 const size_t kCommandBufferSize = 512; 778 char* commandBuffer = (char*)debug_malloc(kCommandBufferSize); 779 if (commandBuffer != NULL) { 780 va_list tempArgs; 781 va_copy(tempArgs, sCurrentKernelDebuggerMessageArgs); 782 783 if (vsnprintf(commandBuffer, kCommandBufferSize, 784 sCurrentKernelDebuggerMessage, tempArgs) 785 < (int)kCommandBufferSize) { 786 const char* commands = strstr(commandBuffer, 787 kKDLMessageCommandSeparator); 788 if (commands != NULL) { 789 commands += strlen(kKDLMessageCommandSeparator); 790 kprintf("initial commands: %s\n", commands); 791 evaluate_debug_command(commands); 792 } 793 } 794 795 va_end(tempArgs); 796 797 debug_free(commandBuffer); 798 } 799 } 800 801 802 static void 803 stack_trace_trampoline(void*) 804 { 805 arch_debug_stack_trace(); 806 } 807 808 809 static void 810 kernel_debugger_loop(const char* messagePrefix, const char* message, 811 va_list args, int32 cpu) 812 { 813 DebugAllocPool* allocPool = create_debug_alloc_pool(); 814 815 sCurrentKernelDebuggerMessagePrefix = messagePrefix; 816 sCurrentKernelDebuggerMessage = message; 817 if (sCurrentKernelDebuggerMessage != NULL) 818 va_copy(sCurrentKernelDebuggerMessageArgs, args); 819 820 sSyslogDebuggerOffset = sSyslogBuffer != NULL 821 ? ring_buffer_readable(sSyslogBuffer) : 0; 822 823 print_kernel_debugger_message(); 824 825 kprintf("Welcome to Kernel Debugging Land...\n"); 826 827 // Set a few temporary debug variables and print on which CPU and in which 828 // thread we are running. 829 set_debug_variable("_cpu", sDebuggerOnCPU); 830 831 Thread* thread = thread_get_current_thread(); 832 if (thread == NULL) { 833 kprintf("Running on CPU %" B_PRId32 "\n", sDebuggerOnCPU); 834 } else if (!debug_is_kernel_memory_accessible((addr_t)thread, 835 sizeof(Thread), B_KERNEL_READ_AREA)) { 836 kprintf("Running on CPU %" B_PRId32 "\n", sDebuggerOnCPU); 837 kprintf("Current thread pointer is %p, which is an address we " 838 "can't read from.\n", thread); 839 arch_debug_unset_current_thread(); 840 } else { 841 set_debug_variable("_thread", (uint64)(addr_t)thread); 842 set_debug_variable("_threadID", thread->id); 843 844 kprintf("Thread %" B_PRId32 " \"%.64s\" running on CPU %" B_PRId32 "\n", 845 thread->id, thread->name, sDebuggerOnCPU); 846 847 if (thread->cpu != gCPU + cpu) { 848 kprintf("The thread's CPU pointer is %p, but should be %p.\n", 849 thread->cpu, gCPU + cpu); 850 arch_debug_unset_current_thread(); 851 } else if (thread->team != NULL) { 852 if (debug_is_kernel_memory_accessible((addr_t)thread->team, 853 sizeof(Team), B_KERNEL_READ_AREA)) { 854 set_debug_variable("_team", (uint64)(addr_t)thread->team); 855 set_debug_variable("_teamID", thread->team->id); 856 } else { 857 kprintf("The thread's team pointer is %p, which is an " 858 "address we can't read from.\n", thread->team); 859 arch_debug_unset_current_thread(); 860 } 861 } 862 } 863 864 if (!has_debugger_command("help") || message != NULL) { 865 // No commands yet or we came here via a panic(). Always print a stack 866 // trace in these cases. 867 jmp_buf* jumpBuffer = (jmp_buf*)debug_malloc(sizeof(jmp_buf)); 868 if (jumpBuffer != NULL) { 869 debug_call_with_fault_handler(*jumpBuffer, &stack_trace_trampoline, 870 NULL); 871 debug_free(jumpBuffer); 872 } else 873 arch_debug_stack_trace(); 874 } 875 876 if (has_debugger_command("help")) { 877 // Commands are registered already -- execute panic() commands. Do that 878 // with paging disabled, so everything is printed, even if the user 879 // can't use the keyboard. 880 bool pagingEnabled = blue_screen_paging_enabled(); 881 blue_screen_set_paging(false); 882 883 execute_panic_commands(); 884 885 blue_screen_set_paging(pagingEnabled); 886 } 887 888 int32 continuableLine = -1; 889 // Index of the previous command line, if the command returned 890 // B_KDEBUG_CONT, i.e. asked to be repeatable, -1 otherwise. 891 892 for (;;) { 893 CommandLineEditingHelper editingHelper; 894 kprintf(kKDLPrompt); 895 char* line = sLineBuffer[sCurrentLine]; 896 read_line(line, LINE_BUFFER_SIZE, &editingHelper); 897 898 // check, if the line is empty or whitespace only 899 bool whiteSpaceOnly = true; 900 for (int i = 0 ; line[i] != '\0'; i++) { 901 if (!isspace(line[i])) { 902 whiteSpaceOnly = false; 903 break; 904 } 905 } 906 907 if (whiteSpaceOnly) { 908 if (continuableLine < 0) 909 continue; 910 911 // the previous command can be repeated 912 sCurrentLine = continuableLine; 913 line = sLineBuffer[sCurrentLine]; 914 } 915 916 int rc = evaluate_debug_command(line); 917 918 if (rc == B_KDEBUG_QUIT) { 919 // okay, exit now. 920 break; 921 } 922 923 // If the command is continuable, remember the current line index. 924 continuableLine = (rc == B_KDEBUG_CONT ? sCurrentLine : -1); 925 926 int previousLine = sCurrentLine - 1; 927 if (previousLine < 0) 928 previousLine = HISTORY_SIZE - 1; 929 930 // Only use the next slot in the history, if the entries differ 931 if (strcmp(sLineBuffer[sCurrentLine], sLineBuffer[previousLine])) { 932 if (++sCurrentLine >= HISTORY_SIZE) 933 sCurrentLine = 0; 934 } 935 } 936 937 if (sCurrentKernelDebuggerMessage != NULL) 938 va_end(sCurrentKernelDebuggerMessageArgs); 939 940 delete_debug_alloc_pool(allocPool); 941 } 942 943 944 static void 945 enter_kernel_debugger(int32 cpu) 946 { 947 while (atomic_add(&sInDebugger, 1) > 0) { 948 atomic_add(&sInDebugger, -1); 949 950 // The debugger is already running, find out where... 951 if (sDebuggerOnCPU == cpu) { 952 // We are re-entering the debugger on the same CPU. 953 break; 954 } 955 956 // Some other CPU must have entered the debugger and tried to halt 957 // us. Process ICIs to ensure we get the halt request. Then we are 958 // blocking there until everyone leaves the debugger and we can 959 // try to enter it again. 960 smp_intercpu_int_handler(cpu); 961 } 962 963 arch_debug_save_registers(&sDebugRegisters[cpu]); 964 sPreviousDprintfState = set_dprintf_enabled(true); 965 966 if (!gKernelStartup && sDebuggerOnCPU != cpu && smp_get_num_cpus() > 1) { 967 // First entry on a MP system, send a halt request to all of the other 968 // CPUs. Should they try to enter the debugger they will be cought in 969 // the loop above. 970 smp_send_broadcast_ici_interrupts_disabled(cpu, SMP_MSG_CPU_HALT, 0, 0, 971 0, NULL, SMP_MSG_FLAG_SYNC); 972 } 973 974 if (sBlueScreenOutput) { 975 if (blue_screen_enter(false) == B_OK) 976 sBlueScreenEnabled = true; 977 } 978 979 sDebugOutputFilter = &gDefaultDebugOutputFilter; 980 981 sDebuggedThread = NULL; 982 983 // sort the commands 984 sort_debugger_commands(); 985 986 call_modules_hook(true); 987 } 988 989 990 static void 991 exit_kernel_debugger() 992 { 993 call_modules_hook(false); 994 set_dprintf_enabled(sPreviousDprintfState); 995 996 sDebugOutputFilter = NULL; 997 998 sBlueScreenEnabled = false; 999 if (sDebugScreenEnabled) 1000 blue_screen_enter(true); 1001 1002 atomic_add(&sInDebugger, -1); 1003 } 1004 1005 1006 static void 1007 hand_over_kernel_debugger() 1008 { 1009 // Wait until the hand-over is complete. 1010 // The other CPU gets our sInDebugger reference and will release it when 1011 // done. Note, that there's a small race condition: the other CPU could 1012 // hand over to another CPU without us noticing. Since this is only 1013 // initiated by the user, it is harmless, though. 1014 sHandOverKDL = true; 1015 while (atomic_get(&sHandOverKDLToCPU) >= 0) 1016 cpu_wait(&sHandOverKDLToCPU, -1); 1017 } 1018 1019 1020 static void 1021 kernel_debugger_internal(const char* messagePrefix, const char* message, 1022 va_list args, int32 cpu) 1023 { 1024 while (true) { 1025 if (sHandOverKDLToCPU == cpu) { 1026 sHandOverKDLToCPU = -1; 1027 sHandOverKDL = false; 1028 } else 1029 enter_kernel_debugger(cpu); 1030 1031 // If we're called recursively sDebuggerOnCPU will be != -1. 1032 int32 previousCPU = sDebuggerOnCPU; 1033 sDebuggerOnCPU = cpu; 1034 1035 kernel_debugger_loop(messagePrefix, message, args, cpu); 1036 1037 if (sHandOverKDLToCPU < 0 && previousCPU == -1) { 1038 // We're not handing over to a different CPU and we weren't 1039 // called recursively, so we'll exit the debugger. 1040 exit_kernel_debugger(); 1041 } 1042 1043 sDebuggerOnCPU = previousCPU; 1044 1045 if (sHandOverKDLToCPU < 0) 1046 break; 1047 1048 hand_over_kernel_debugger(); 1049 1050 debug_trap_cpu_in_kdl(cpu, true); 1051 1052 if (sHandOverKDLToCPU != cpu) 1053 break; 1054 } 1055 } 1056 1057 1058 static int 1059 cmd_dump_kdl_message(int argc, char** argv) 1060 { 1061 print_kernel_debugger_message(); 1062 return 0; 1063 } 1064 1065 1066 static int 1067 cmd_execute_panic_commands(int argc, char** argv) 1068 { 1069 execute_panic_commands(); 1070 return 0; 1071 } 1072 1073 1074 static int 1075 cmd_dump_syslog(int argc, char** argv) 1076 { 1077 if (!sSyslogOutputEnabled) { 1078 kprintf("Syslog is not enabled.\n"); 1079 return 0; 1080 } 1081 1082 bool unsentOnly = false; 1083 bool ignoreKDLOutput = true; 1084 1085 int argi = 1; 1086 for (; argi < argc; argi++) { 1087 if (strcmp(argv[argi], "-n") == 0) 1088 unsentOnly = true; 1089 else if (strcmp(argv[argi], "-k") == 0) 1090 ignoreKDLOutput = false; 1091 else 1092 break; 1093 } 1094 1095 if (argi < argc) { 1096 print_debugger_command_usage(argv[0]); 1097 return 0; 1098 } 1099 1100 size_t debuggerOffset = sSyslogDebuggerOffset; 1101 size_t start = unsentOnly ? sSyslogBufferOffset : 0; 1102 size_t end = ignoreKDLOutput 1103 ? debuggerOffset : ring_buffer_readable(sSyslogBuffer); 1104 1105 // allocate a buffer for processing the syslog output 1106 size_t bufferSize = 1024; 1107 char* buffer = (char*)debug_malloc(bufferSize); 1108 char stackBuffer[64]; 1109 if (buffer == NULL) { 1110 buffer = stackBuffer; 1111 bufferSize = sizeof(stackBuffer); 1112 } 1113 1114 // filter the output 1115 bool newLine = false; 1116 while (start < end) { 1117 size_t bytesRead = ring_buffer_peek(sSyslogBuffer, start, buffer, 1118 std::min(end - start, bufferSize - 1)); 1119 if (bytesRead == 0) 1120 break; 1121 start += bytesRead; 1122 1123 // remove '\0' and 0xcc 1124 size_t toPrint = 0; 1125 for (size_t i = 0; i < bytesRead; i++) { 1126 if (buffer[i] != '\0' && (uint8)buffer[i] != 0xcc) 1127 buffer[toPrint++] = buffer[i]; 1128 } 1129 1130 if (toPrint > 0) { 1131 newLine = buffer[toPrint - 1] == '\n'; 1132 buffer[toPrint] = '\0'; 1133 kputs(buffer); 1134 } 1135 1136 if (debuggerOffset > sSyslogDebuggerOffset) { 1137 // Our output caused older syslog output to be evicted from the 1138 // syslog buffer. We need to adjust our offsets accordingly. Note, 1139 // this can still go wrong, if the buffer was already full and more 1140 // was written to it than we have processed, but we can't help that. 1141 size_t diff = debuggerOffset - sSyslogDebuggerOffset; 1142 start -= std::min(start, diff); 1143 end -= std::min(end, diff); 1144 debuggerOffset = sSyslogDebuggerOffset; 1145 } 1146 } 1147 1148 if (!newLine) 1149 kputs("\n"); 1150 1151 if (buffer != stackBuffer) 1152 debug_free(buffer); 1153 1154 return 0; 1155 } 1156 1157 1158 static int 1159 cmd_switch_cpu(int argc, char** argv) 1160 { 1161 if (argc > 2) { 1162 print_debugger_command_usage(argv[0]); 1163 return 0; 1164 } 1165 1166 if (argc == 1) { 1167 kprintf("running on CPU %" B_PRId32 "\n", smp_get_current_cpu()); 1168 return 0; 1169 } 1170 1171 int32 newCPU = parse_expression(argv[1]); 1172 if (newCPU < 0 || newCPU >= smp_get_num_cpus()) { 1173 kprintf("invalid CPU index\n"); 1174 return 0; 1175 } 1176 1177 if (newCPU == smp_get_current_cpu()) { 1178 kprintf("already running on CPU %" B_PRId32 "\n", newCPU); 1179 return 0; 1180 } 1181 1182 sHandOverKDLToCPU = newCPU; 1183 1184 return B_KDEBUG_QUIT; 1185 } 1186 1187 1188 static status_t 1189 syslog_sender(void* data) 1190 { 1191 status_t error = B_BAD_PORT_ID; 1192 port_id port = -1; 1193 bool bufferPending = false; 1194 int32 length = 0; 1195 1196 while (true) { 1197 // wait for syslog data to become available 1198 acquire_sem_etc(sSyslogNotify, 1, B_RELATIVE_TIMEOUT, 5000000); 1199 // Note: We time out since in some situations output is added to 1200 // the syslog buffer without being allowed to notify us (e.g. in 1201 // the kernel debugger). 1202 // TODO: A semaphore is rather unhandy here. It is released for 1203 // every single message written to the buffer, but we potentially 1204 // send a lot more than a single message per iteration. On the other 1205 // hand, as long as the syslog daemon is not running, we acquire 1206 // the semaphore anyway. A better solution would be a flag + a 1207 // condition variable. 1208 1209 sSyslogMessage->when = real_time_clock(); 1210 1211 if (error == B_BAD_PORT_ID) { 1212 // last message couldn't be sent, try to locate the syslog_daemon 1213 port = find_port(SYSLOG_PORT_NAME); 1214 if (port < 0) { 1215 // Don't recheck too quickly, since find_port) is rather 1216 // expensive. 1217 // TODO: Maybe using the port notification mechanism would be 1218 // the better option here. Alternatively, and probably even 1219 // better, the syslog daemon could register itself via a syscall 1220 // (like the messaging service). We could even wait with 1221 // starting this thread before that happened (end exit as soon 1222 // as the port is gone). 1223 snooze(1000000); 1224 continue; 1225 } 1226 } 1227 1228 if (port >= B_OK) { 1229 if (!bufferPending) { 1230 // we need to have exclusive access to our syslog buffer 1231 cpu_status state = disable_interrupts(); 1232 acquire_spinlock(&sSpinlock); 1233 1234 length = ring_buffer_readable(sSyslogBuffer) 1235 - sSyslogBufferOffset; 1236 if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH) 1237 length = SYSLOG_MAX_MESSAGE_LENGTH; 1238 1239 length = ring_buffer_peek(sSyslogBuffer, sSyslogBufferOffset, 1240 (uint8*)sSyslogMessage->message, length); 1241 sSyslogBufferOffset += length; 1242 if (sSyslogDropped) { 1243 // Add drop marker - since parts had to be dropped, it's 1244 // guaranteed that we have enough space in the buffer now. 1245 ring_buffer_write(sSyslogBuffer, (uint8*)"<DROP>", 6); 1246 sSyslogDropped = false; 1247 } 1248 1249 release_spinlock(&sSpinlock); 1250 restore_interrupts(state); 1251 } 1252 1253 if (length == 0) { 1254 // the buffer we came here for might have been sent already 1255 bufferPending = false; 1256 continue; 1257 } 1258 1259 error = write_port_etc(port, SYSLOG_MESSAGE, sSyslogMessage, 1260 sizeof(struct syslog_message) + length, B_RELATIVE_TIMEOUT, 0); 1261 1262 if (error < B_OK) { 1263 // sending has failed - just wait, maybe it'll work later. 1264 bufferPending = true; 1265 continue; 1266 } 1267 1268 if (bufferPending) { 1269 // we could write the last pending buffer, try to read more 1270 // from the syslog ring buffer 1271 release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE); 1272 bufferPending = false; 1273 } 1274 } 1275 } 1276 1277 return 0; 1278 } 1279 1280 1281 static void 1282 syslog_write(const char* text, int32 length, bool notify) 1283 { 1284 if (sSyslogBuffer == NULL) 1285 return; 1286 1287 if (length > sSyslogBuffer->size) { 1288 text = "<DROP>"; 1289 length = 6; 1290 } 1291 1292 int32 writable = ring_buffer_writable(sSyslogBuffer); 1293 if (writable < length) { 1294 // drop old data 1295 size_t toDrop = length - writable; 1296 ring_buffer_flush(sSyslogBuffer, toDrop); 1297 1298 if (toDrop > sSyslogBufferOffset) { 1299 sSyslogBufferOffset = 0; 1300 sSyslogDropped = true; 1301 } else 1302 sSyslogBufferOffset -= toDrop; 1303 1304 sSyslogDebuggerOffset -= std::min(toDrop, sSyslogDebuggerOffset); 1305 } 1306 1307 ring_buffer_write(sSyslogBuffer, (uint8*)text, length); 1308 1309 if (notify) 1310 release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE); 1311 } 1312 1313 1314 static status_t 1315 syslog_init_post_threads(void) 1316 { 1317 if (!sSyslogOutputEnabled) 1318 return B_OK; 1319 1320 sSyslogNotify = create_sem(0, "syslog data"); 1321 if (sSyslogNotify >= B_OK) { 1322 thread_id thread = spawn_kernel_thread(syslog_sender, "syslog sender", 1323 B_LOW_PRIORITY, NULL); 1324 if (thread >= B_OK && resume_thread(thread) == B_OK) 1325 return B_OK; 1326 } 1327 1328 // initializing kernel syslog service failed -- disable it 1329 1330 sSyslogOutputEnabled = false; 1331 1332 if (sSyslogBuffer != NULL) { 1333 if (sDebugSyslog) 1334 delete_area(area_for(sSyslogBuffer)); 1335 else 1336 delete_ring_buffer(sSyslogBuffer); 1337 1338 sSyslogBuffer = NULL; 1339 } 1340 1341 free(sSyslogMessage); 1342 delete_sem(sSyslogNotify); 1343 1344 return B_ERROR; 1345 } 1346 1347 1348 static status_t 1349 syslog_init_post_vm(struct kernel_args* args) 1350 { 1351 status_t status; 1352 int32 length = 0; 1353 1354 if (!sSyslogOutputEnabled) { 1355 sSyslogBuffer = NULL; 1356 // Might already have been set in syslog_init(), if the debug syslog 1357 // was enabled. Just drop it -- we'll never create the area. 1358 return B_OK; 1359 } 1360 1361 sSyslogMessage = (syslog_message*)malloc(SYSLOG_MESSAGE_BUFFER_SIZE); 1362 if (sSyslogMessage == NULL) { 1363 status = B_NO_MEMORY; 1364 goto err1; 1365 } 1366 1367 if (sSyslogBuffer == NULL) { 1368 size_t bufferSize = DEFAULT_SYSLOG_BUFFER_SIZE; 1369 void* handle = load_driver_settings("kernel"); 1370 if (handle != NULL) { 1371 const char* sizeString = get_driver_parameter(handle, 1372 "syslog_buffer_size", NULL, NULL); 1373 if (sizeString != NULL) { 1374 bufferSize = strtoul(sizeString, NULL, 0); 1375 if (bufferSize > 262144) 1376 bufferSize = 262144; 1377 else if (bufferSize < SYSLOG_MESSAGE_BUFFER_SIZE) 1378 bufferSize = SYSLOG_MESSAGE_BUFFER_SIZE; 1379 } 1380 1381 unload_driver_settings(handle); 1382 } 1383 1384 sSyslogBuffer = create_ring_buffer(bufferSize); 1385 1386 if (sSyslogBuffer == NULL) { 1387 status = B_NO_MEMORY; 1388 goto err2; 1389 } 1390 } else { 1391 // create an area for the debug syslog buffer 1392 void* base = (void*)ROUNDDOWN((addr_t)(void *)args->debug_output, B_PAGE_SIZE); 1393 size_t size = ROUNDUP(args->debug_size, B_PAGE_SIZE); 1394 area_id area = create_area("syslog debug", &base, B_EXACT_ADDRESS, size, 1395 B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); 1396 if (area < 0) { 1397 status = B_NO_MEMORY; 1398 goto err2; 1399 } 1400 } 1401 1402 // initialize syslog message 1403 sSyslogMessage->from = 0; 1404 sSyslogMessage->options = LOG_KERN; 1405 sSyslogMessage->priority = LOG_DEBUG; 1406 sSyslogMessage->ident[0] = '\0'; 1407 //strcpy(sSyslogMessage->ident, "KERNEL"); 1408 1409 if (args->debug_output != NULL) { 1410 syslog_write((const char*)args->debug_output.Pointer(), 1411 args->debug_size, false); 1412 } 1413 1414 // Allocate memory for the previous session's debug syslog output. In 1415 // syslog_init_post_modules() we'll write it back to disk and free it. 1416 if (args->previous_debug_output != NULL) { 1417 sPreviousSessionSyslogBuffer = malloc(args->previous_debug_size); 1418 if (sPreviousSessionSyslogBuffer != NULL) { 1419 sPreviousSessionSyslogBufferSize = args->previous_debug_size; 1420 memcpy(sPreviousSessionSyslogBuffer, args->previous_debug_output, 1421 sPreviousSessionSyslogBufferSize); 1422 } 1423 } 1424 1425 char revisionBuffer[64]; 1426 length = snprintf(revisionBuffer, sizeof(revisionBuffer), 1427 "Welcome to syslog debug output!\nHaiku revision: %s\n", 1428 get_haiku_revision()); 1429 syslog_write(revisionBuffer, 1430 std::min(length, (int32)sizeof(revisionBuffer) - 1), false); 1431 1432 add_debugger_command_etc("syslog", &cmd_dump_syslog, 1433 "Dumps the syslog buffer.", 1434 "[ \"-n\" ] [ \"-k\" ]\n" 1435 "Dumps the whole syslog buffer, or, if -k is specified, only " 1436 "the part that hasn't been sent yet.\n", 0); 1437 1438 return B_OK; 1439 1440 err2: 1441 free(sSyslogMessage); 1442 err1: 1443 sSyslogOutputEnabled = false; 1444 sSyslogBuffer = NULL; 1445 return status; 1446 } 1447 1448 static void 1449 syslog_init_post_modules() 1450 { 1451 if (sPreviousSessionSyslogBuffer == NULL) 1452 return; 1453 1454 void* buffer = sPreviousSessionSyslogBuffer; 1455 size_t bufferSize = sPreviousSessionSyslogBufferSize; 1456 sPreviousSessionSyslogBuffer = NULL; 1457 sPreviousSessionSyslogBufferSize = 0; 1458 MemoryDeleter bufferDeleter(buffer); 1459 1460 int fd = open("/var/log/previous_syslog", O_WRONLY | O_CREAT | O_TRUNC, 1461 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 1462 if (fd < 0) { 1463 dprintf("Failed to open previous syslog file: %s\n", strerror(errno)); 1464 return; 1465 } 1466 1467 write(fd, buffer, bufferSize); 1468 close(fd); 1469 } 1470 1471 static status_t 1472 syslog_init(struct kernel_args* args) 1473 { 1474 if (!args->keep_debug_output_buffer || args->debug_output == NULL) 1475 return B_OK; 1476 1477 sSyslogBuffer = create_ring_buffer_etc(args->debug_output, args->debug_size, 1478 RING_BUFFER_INIT_FROM_BUFFER); 1479 sDebugSyslog = true; 1480 1481 return B_OK; 1482 } 1483 1484 1485 static void 1486 debug_memcpy_trampoline(void* _parameters) 1487 { 1488 debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters; 1489 memcpy(parameters->to, parameters->from, parameters->size); 1490 } 1491 1492 1493 static void 1494 debug_strlcpy_trampoline(void* _parameters) 1495 { 1496 debug_strlcpy_parameters* parameters 1497 = (debug_strlcpy_parameters*)_parameters; 1498 parameters->result = strlcpy(parameters->to, parameters->from, 1499 parameters->size); 1500 } 1501 1502 1503 void 1504 call_modules_hook(bool enter) 1505 { 1506 uint32 index = 0; 1507 while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) { 1508 debugger_module_info* module = sDebuggerModules[index]; 1509 1510 if (enter && module->enter_debugger != NULL) 1511 module->enter_debugger(); 1512 else if (!enter && module->exit_debugger != NULL) 1513 module->exit_debugger(); 1514 1515 index++; 1516 } 1517 } 1518 1519 1520 //! Must be called with the sSpinlock held. 1521 static void 1522 debug_output(const char* string, int32 length, bool notifySyslog) 1523 { 1524 if (length >= OUTPUT_BUFFER_SIZE) 1525 length = OUTPUT_BUFFER_SIZE - 1; 1526 1527 if (length > 1 && string[length - 1] == '\n' 1528 && strncmp(string, sLastOutputBuffer, length) == 0) { 1529 sMessageRepeatCount++; 1530 sMessageRepeatLastTime = system_time(); 1531 if (sMessageRepeatFirstTime == 0) 1532 sMessageRepeatFirstTime = sMessageRepeatLastTime; 1533 } else { 1534 flush_pending_repeats(notifySyslog); 1535 1536 if (sSerialDebugEnabled) 1537 arch_debug_serial_puts(string); 1538 if (sSyslogOutputEnabled) 1539 syslog_write(string, length, notifySyslog); 1540 if (sBlueScreenEnabled || sDebugScreenEnabled) 1541 blue_screen_puts(string); 1542 if (sSerialDebugEnabled) { 1543 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1544 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 1545 sDebuggerModules[i]->debugger_puts(string, length); 1546 } 1547 } 1548 1549 memcpy(sLastOutputBuffer, string, length); 1550 sLastOutputBuffer[length] = 0; 1551 } 1552 } 1553 1554 1555 //! Must be called with the sSpinlock held. 1556 static void 1557 flush_pending_repeats(bool notifySyslog) 1558 { 1559 if (sMessageRepeatCount <= 0) 1560 return; 1561 1562 if (sMessageRepeatCount > 1) { 1563 static char temp[40]; 1564 size_t length = snprintf(temp, sizeof(temp), 1565 "Last message repeated %" B_PRId32 " times.\n", sMessageRepeatCount); 1566 length = std::min(length, sizeof(temp) - 1); 1567 1568 if (sSerialDebugEnabled) 1569 arch_debug_serial_puts(temp); 1570 if (sSyslogOutputEnabled) 1571 syslog_write(temp, length, notifySyslog); 1572 if (sBlueScreenEnabled || sDebugScreenEnabled) 1573 blue_screen_puts(temp); 1574 if (sSerialDebugEnabled) { 1575 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1576 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 1577 sDebuggerModules[i]->debugger_puts(temp, length); 1578 } 1579 } 1580 } else { 1581 // if we only have one repeat just reprint the last buffer 1582 size_t length = strlen(sLastOutputBuffer); 1583 1584 if (sSerialDebugEnabled) 1585 arch_debug_serial_puts(sLastOutputBuffer); 1586 if (sSyslogOutputEnabled) 1587 syslog_write(sLastOutputBuffer, length, notifySyslog); 1588 if (sBlueScreenEnabled || sDebugScreenEnabled) 1589 blue_screen_puts(sLastOutputBuffer); 1590 if (sSerialDebugEnabled) { 1591 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1592 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) { 1593 sDebuggerModules[i]->debugger_puts(sLastOutputBuffer, 1594 length); 1595 } 1596 } 1597 } 1598 } 1599 1600 sMessageRepeatFirstTime = 0; 1601 sMessageRepeatCount = 0; 1602 } 1603 1604 1605 static void 1606 check_pending_repeats(void* /*data*/, int /*iteration*/) 1607 { 1608 if (sMessageRepeatCount > 0 1609 && (system_time() - sMessageRepeatLastTime > 1000000 1610 || system_time() - sMessageRepeatFirstTime > 3000000)) { 1611 cpu_status state = disable_interrupts(); 1612 acquire_spinlock(&sSpinlock); 1613 1614 flush_pending_repeats(true); 1615 1616 release_spinlock(&sSpinlock); 1617 restore_interrupts(state); 1618 } 1619 } 1620 1621 1622 static void 1623 dprintf_args(const char* format, va_list args, bool notifySyslog) 1624 { 1625 if (are_interrupts_enabled()) { 1626 MutexLocker locker(sOutputLock); 1627 1628 int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format, 1629 args); 1630 length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1); 1631 1632 InterruptsSpinLocker _(sSpinlock); 1633 debug_output(sOutputBuffer, length, notifySyslog); 1634 } else { 1635 InterruptsSpinLocker _(sSpinlock); 1636 1637 int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, 1638 format, args); 1639 length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1); 1640 1641 debug_output(sInterruptOutputBuffer, length, notifySyslog); 1642 } 1643 } 1644 1645 1646 // #pragma mark - private kernel API 1647 1648 1649 bool 1650 debug_screen_output_enabled(void) 1651 { 1652 return sDebugScreenEnabled; 1653 } 1654 1655 1656 void 1657 debug_stop_screen_debug_output(void) 1658 { 1659 sDebugScreenEnabled = false; 1660 } 1661 1662 1663 bool 1664 debug_debugger_running(void) 1665 { 1666 return sDebuggerOnCPU != -1; 1667 } 1668 1669 1670 void 1671 debug_puts(const char* string, int32 length) 1672 { 1673 InterruptsSpinLocker _(sSpinlock); 1674 debug_output(string, length, true); 1675 } 1676 1677 1678 void 1679 debug_early_boot_message(const char* string) 1680 { 1681 arch_debug_serial_early_boot_message(string); 1682 } 1683 1684 1685 void 1686 debug_init(kernel_args* args) 1687 { 1688 new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter; 1689 1690 syslog_init(args); 1691 1692 debug_paranoia_init(); 1693 arch_debug_console_init(args); 1694 } 1695 1696 1697 void 1698 debug_init_post_vm(kernel_args* args) 1699 { 1700 add_debugger_command_etc("cpu", &cmd_switch_cpu, 1701 "Switches to another CPU.", 1702 "<cpu>\n" 1703 "Switches to CPU with the index <cpu>.\n", 0); 1704 add_debugger_command_etc("message", &cmd_dump_kdl_message, 1705 "Reprint the message printed when entering KDL", 1706 "\n" 1707 "Reprints the message printed when entering KDL.\n", 0); 1708 add_debugger_command_etc("panic_commands", &cmd_execute_panic_commands, 1709 "Execute commands associated with the panic() that caused " 1710 "entering KDL", 1711 "\n" 1712 "Executes the commands associated with the panic() that caused " 1713 "entering KDL.\n", 0); 1714 1715 debug_builtin_commands_init(); 1716 arch_debug_init(args); 1717 1718 debug_heap_init(); 1719 debug_variables_init(); 1720 frame_buffer_console_init(args); 1721 arch_debug_console_init_settings(args); 1722 tracing_init(); 1723 } 1724 1725 1726 void 1727 debug_init_post_settings(struct kernel_args* args) 1728 { 1729 // get debug settings 1730 1731 sSerialDebugEnabled = get_safemode_boolean("serial_debug_output", 1732 sSerialDebugEnabled); 1733 sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output", 1734 sSyslogOutputEnabled); 1735 sBlueScreenOutput = get_safemode_boolean("bluescreen", true); 1736 sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys", 1737 sEmergencyKeysEnabled); 1738 sDebugScreenEnabled = get_safemode_boolean("debug_screen", false); 1739 1740 if ((sBlueScreenOutput || sDebugScreenEnabled) 1741 && blue_screen_init() != B_OK) 1742 sBlueScreenOutput = sDebugScreenEnabled = false; 1743 1744 if (sDebugScreenEnabled) 1745 blue_screen_enter(true); 1746 1747 syslog_init_post_vm(args); 1748 } 1749 1750 1751 void 1752 debug_init_post_modules(struct kernel_args* args) 1753 { 1754 syslog_init_post_modules(); 1755 1756 // check for dupped lines every 10/10 second 1757 register_kernel_daemon(check_pending_repeats, NULL, 10); 1758 1759 syslog_init_post_threads(); 1760 1761 // load kernel debugger addons 1762 1763 static const char* kDemanglePrefix = "debugger/demangle/"; 1764 1765 void* cookie = open_module_list("debugger"); 1766 uint32 count = 0; 1767 while (count < kMaxDebuggerModules) { 1768 char name[B_FILE_NAME_LENGTH]; 1769 size_t nameLength = sizeof(name); 1770 1771 if (read_next_module_name(cookie, name, &nameLength) != B_OK) 1772 break; 1773 1774 // get demangle module, if any 1775 if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) { 1776 if (sDemangleModule == NULL) 1777 get_module(name, (module_info**)&sDemangleModule); 1778 continue; 1779 } 1780 1781 if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) { 1782 dprintf("kernel debugger extension \"%s\": loaded\n", name); 1783 count++; 1784 } else 1785 dprintf("kernel debugger extension \"%s\": failed to load\n", name); 1786 } 1787 close_module_list(cookie); 1788 1789 frame_buffer_console_init_post_modules(args); 1790 } 1791 1792 1793 void 1794 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags) 1795 { 1796 sPageFaultInfo.fault_address = faultAddress; 1797 sPageFaultInfo.pc = pc; 1798 sPageFaultInfo.flags = flags; 1799 } 1800 1801 1802 debug_page_fault_info* 1803 debug_get_page_fault_info() 1804 { 1805 return &sPageFaultInfo; 1806 } 1807 1808 1809 void 1810 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver) 1811 { 1812 InterruptsLocker locker; 1813 1814 // return, if we've been called recursively (we call 1815 // smp_intercpu_int_handler() below) 1816 if (sCPUTrapped[cpu]) 1817 return; 1818 1819 arch_debug_save_registers(&sDebugRegisters[cpu]); 1820 1821 sCPUTrapped[cpu] = true; 1822 1823 while (sInDebugger != 0) { 1824 if (sHandOverKDL && sHandOverKDLToCPU == cpu) { 1825 if (returnIfHandedOver) 1826 break; 1827 1828 kernel_debugger_internal(NULL, NULL, 1829 sCurrentKernelDebuggerMessageArgs, cpu); 1830 } else 1831 smp_intercpu_int_handler(cpu); 1832 } 1833 1834 sCPUTrapped[cpu] = false; 1835 } 1836 1837 1838 void 1839 debug_double_fault(int32 cpu) 1840 { 1841 kernel_debugger_internal("Double Fault!", NULL, 1842 sCurrentKernelDebuggerMessageArgs, cpu); 1843 } 1844 1845 1846 bool 1847 debug_emergency_key_pressed(char key) 1848 { 1849 if (!sEmergencyKeysEnabled) 1850 return false; 1851 1852 if (key == 'd') { 1853 kernel_debugger("Keyboard Requested Halt."); 1854 return true; 1855 } 1856 1857 // Broadcast to the kernel debugger modules 1858 1859 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1860 if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) { 1861 if (sDebuggerModules[i]->emergency_key_pressed(key)) 1862 return true; 1863 } 1864 } 1865 1866 return false; 1867 } 1868 1869 1870 /*! Verifies that the complete given memory range is accessible in the current 1871 context. 1872 1873 Invoked in the kernel debugger only. 1874 1875 \param address The start address of the memory range to be checked. 1876 \param size The size of the memory range to be checked. 1877 \param protection The area protection for which to check. Valid is a bitwise 1878 or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA. 1879 \return \c true, if the complete memory range can be accessed in all ways 1880 specified by \a protection, \c false otherwise. 1881 */ 1882 bool 1883 debug_is_kernel_memory_accessible(addr_t address, size_t size, 1884 uint32 protection) 1885 { 1886 addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE); 1887 address = ROUNDDOWN(address, B_PAGE_SIZE); 1888 1889 if (!IS_KERNEL_ADDRESS(address) || endAddress < address) 1890 return false; 1891 1892 for (; address < endAddress; address += B_PAGE_SIZE) { 1893 if (!arch_vm_translation_map_is_kernel_page_accessible(address, 1894 protection)) { 1895 return false; 1896 } 1897 } 1898 1899 return true; 1900 } 1901 1902 1903 /*! Calls a function in a setjmp() + fault handler context. 1904 May only be used in the kernel debugger. 1905 1906 \param jumpBuffer Buffer to be used for setjmp()/longjmp(). 1907 \param function The function to be called. 1908 \param parameter The parameter to be passed to the function to be called. 1909 \return 1910 - \c 0, when the function executed without causing a page fault or 1911 calling longjmp(). 1912 - \c 1, when the function caused a page fault. 1913 - Any other value the function passes to longjmp(). 1914 */ 1915 int 1916 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*), 1917 void* parameter) 1918 { 1919 // save current fault handler 1920 cpu_ent* cpu = gCPU + sDebuggerOnCPU; 1921 addr_t oldFaultHandler = cpu->fault_handler; 1922 addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer; 1923 1924 int result = setjmp(jumpBuffer); 1925 if (result == 0) { 1926 arch_debug_call_with_fault_handler(cpu, jumpBuffer, function, 1927 parameter); 1928 } 1929 1930 // restore old fault handler 1931 cpu->fault_handler = oldFaultHandler; 1932 cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer; 1933 1934 return result; 1935 } 1936 1937 1938 /*! Similar to user_memcpy(), but can only be invoked from within the kernel 1939 debugger (and must not be used outside). 1940 The supplied \a teamID specifies the address space in which to interpret 1941 the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(), 1942 or any valid team ID. If the addresses are both kernel addresses, the 1943 argument is ignored and the current address space is used. 1944 */ 1945 status_t 1946 debug_memcpy(team_id teamID, void* to, const void* from, size_t size) 1947 { 1948 // don't allow address overflows 1949 if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to) 1950 return B_BAD_ADDRESS; 1951 1952 // Try standard memcpy() with fault handler, if the addresses can be 1953 // interpreted in the current address space. 1954 if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to)) 1955 || debug_is_debugged_team(teamID)) { 1956 debug_memcpy_parameters parameters = {to, from, size}; 1957 1958 if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer, 1959 &debug_memcpy_trampoline, ¶meters) == 0) { 1960 return B_OK; 1961 } 1962 } 1963 1964 // Try harder. The pages of the respective memory could be unmapped but 1965 // still exist in a cache (the page daemon does that with inactive pages). 1966 while (size > 0) { 1967 uint8 buffer[32]; 1968 size_t toCopy = std::min(size, sizeof(buffer)); 1969 1970 // restrict the size so we don't cross page boundaries 1971 if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy) 1972 toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE; 1973 if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy) 1974 toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE; 1975 1976 if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy, 1977 false) != B_OK 1978 || vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true) 1979 != B_OK) { 1980 return B_BAD_ADDRESS; 1981 } 1982 1983 from = (const uint8*)from + toCopy; 1984 to = (uint8*)to + toCopy; 1985 size -= toCopy; 1986 } 1987 1988 return B_OK; 1989 } 1990 1991 1992 /*! Similar to user_strlcpy(), but can only be invoked from within the kernel 1993 debugger (and must not be used outside). 1994 The supplied \a teamID specifies the address space in which to interpret 1995 the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(), 1996 or any valid team ID. If the addresses are both kernel addresses, the 1997 argument is ignored and the current address space is used. 1998 */ 1999 ssize_t 2000 debug_strlcpy(team_id teamID, char* to, const char* from, size_t size) 2001 { 2002 if (from == NULL || (to == NULL && size > 0)) 2003 return B_BAD_ADDRESS; 2004 2005 // limit size to avoid address overflows 2006 size_t maxSize = std::min(size, 2007 ~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1); 2008 // NOTE: Since strlcpy() determines the length of \a from, the source 2009 // address might still overflow. 2010 2011 // Try standard strlcpy() with fault handler, if the addresses can be 2012 // interpreted in the current address space. 2013 if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to)) 2014 || debug_is_debugged_team(teamID)) { 2015 debug_strlcpy_parameters parameters = {to, from, maxSize}; 2016 2017 if (debug_call_with_fault_handler( 2018 gCPU[sDebuggerOnCPU].fault_jump_buffer, 2019 &debug_strlcpy_trampoline, ¶meters) == 0) { 2020 // If we hit the address overflow boundary, fail. 2021 if (parameters.result >= maxSize && maxSize < size) 2022 return B_BAD_ADDRESS; 2023 2024 return parameters.result; 2025 } 2026 } 2027 2028 // Try harder. The pages of the respective memory could be unmapped but 2029 // still exist in a cache (the page daemon does that with inactive pages). 2030 size_t totalLength = 0; 2031 while (maxSize > 0) { 2032 char buffer[32]; 2033 size_t toCopy = std::min(maxSize, sizeof(buffer)); 2034 2035 // restrict the size so we don't cross page boundaries 2036 if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy) 2037 toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE; 2038 if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy) 2039 toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE; 2040 2041 // copy the next part of the string from the source 2042 if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy, 2043 false) != B_OK) { 2044 return B_BAD_ADDRESS; 2045 } 2046 2047 // determine the length of the part and whether we've reached the end 2048 // of the string 2049 size_t length = strnlen(buffer, toCopy); 2050 bool endOfString = length < toCopy; 2051 2052 from = (const char*)from + toCopy; 2053 totalLength += length; 2054 maxSize -= length; 2055 2056 if (endOfString) { 2057 // only copy the actual string, including the terminating null 2058 toCopy = length + 1; 2059 } 2060 2061 if (size > 0) { 2062 // We still have space left in the target buffer. 2063 if (size <= length) { 2064 // Not enough space for the complete part. Null-terminate it and 2065 // copy what we can. 2066 buffer[size - 1] = '\0'; 2067 totalLength += length - size; 2068 toCopy = size; 2069 } 2070 2071 if (vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true) 2072 != B_OK) { 2073 return B_BAD_ADDRESS; 2074 } 2075 2076 to = (char*)to + toCopy; 2077 size -= toCopy; 2078 } 2079 2080 if (endOfString) 2081 return totalLength; 2082 } 2083 2084 return totalLength; 2085 } 2086 2087 2088 // #pragma mark - public API 2089 2090 2091 uint64 2092 parse_expression(const char* expression) 2093 { 2094 uint64 result; 2095 return evaluate_debug_expression(expression, &result, true) ? result : 0; 2096 } 2097 2098 2099 void 2100 panic(const char* format, ...) 2101 { 2102 va_list args; 2103 va_start(args, format); 2104 2105 cpu_status state = disable_interrupts(); 2106 2107 kernel_debugger_internal("PANIC: ", format, args, 2108 thread_get_current_thread() ? smp_get_current_cpu() : 0); 2109 2110 restore_interrupts(state); 2111 2112 va_end(args); 2113 } 2114 2115 2116 void 2117 kernel_debugger(const char* message) 2118 { 2119 cpu_status state = disable_interrupts(); 2120 2121 kernel_debugger_internal(message, NULL, sCurrentKernelDebuggerMessageArgs, 2122 smp_get_current_cpu()); 2123 2124 restore_interrupts(state); 2125 } 2126 2127 2128 bool 2129 set_dprintf_enabled(bool newState) 2130 { 2131 bool oldState = sSerialDebugEnabled; 2132 sSerialDebugEnabled = newState; 2133 2134 return oldState; 2135 } 2136 2137 2138 void 2139 dprintf(const char* format, ...) 2140 { 2141 va_list args; 2142 2143 if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled) 2144 return; 2145 2146 va_start(args, format); 2147 dprintf_args(format, args, true); 2148 va_end(args); 2149 } 2150 2151 2152 void 2153 dvprintf(const char* format, va_list args) 2154 { 2155 if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled) 2156 return; 2157 2158 dprintf_args(format, args, true); 2159 } 2160 2161 2162 void 2163 dprintf_no_syslog(const char* format, ...) 2164 { 2165 va_list args; 2166 2167 if (!sSerialDebugEnabled && !sBlueScreenEnabled) 2168 return; 2169 2170 va_start(args, format); 2171 dprintf_args(format, args, false); 2172 va_end(args); 2173 } 2174 2175 2176 /*! Similar to dprintf() but thought to be used in the kernel 2177 debugger only (it doesn't lock). 2178 */ 2179 void 2180 kprintf(const char* format, ...) 2181 { 2182 if (sDebugOutputFilter != NULL) { 2183 va_list args; 2184 va_start(args, format); 2185 sDebugOutputFilter->Print(format, args); 2186 va_end(args); 2187 } 2188 } 2189 2190 2191 void 2192 kprintf_unfiltered(const char* format, ...) 2193 { 2194 va_list args; 2195 va_start(args, format); 2196 gDefaultDebugOutputFilter.Print(format, args); 2197 va_end(args); 2198 } 2199 2200 2201 const char* 2202 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize, 2203 bool* _isObjectMethod) 2204 { 2205 if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) { 2206 return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize, 2207 _isObjectMethod); 2208 } 2209 2210 if (_isObjectMethod != NULL) 2211 *_isObjectMethod = false; 2212 2213 return symbol; 2214 } 2215 2216 2217 status_t 2218 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol, 2219 char* name, size_t nameSize, int32* _type, size_t* _argumentLength) 2220 { 2221 if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) { 2222 return sDemangleModule->get_next_argument(_cookie, symbol, name, 2223 nameSize, _type, _argumentLength); 2224 } 2225 2226 return B_NOT_SUPPORTED; 2227 } 2228 2229 2230 struct arch_debug_registers* 2231 debug_get_debug_registers(int32 cpu) 2232 { 2233 if (cpu < 0 || cpu > smp_get_num_cpus()) 2234 return NULL; 2235 2236 return &sDebugRegisters[cpu]; 2237 } 2238 2239 2240 Thread* 2241 debug_set_debugged_thread(Thread* thread) 2242 { 2243 Thread* previous = sDebuggedThread; 2244 sDebuggedThread = thread; 2245 return previous; 2246 } 2247 2248 2249 Thread* 2250 debug_get_debugged_thread() 2251 { 2252 return sDebuggedThread != NULL 2253 ? sDebuggedThread : thread_get_current_thread(); 2254 } 2255 2256 2257 /*! Returns whether the supplied team ID refers to the same team the currently 2258 debugged thread (debug_get_debugged_thread()) belongs to. 2259 Always returns \c true, if \c B_CURRENT_TEAM is given. 2260 */ 2261 bool 2262 debug_is_debugged_team(team_id teamID) 2263 { 2264 if (teamID == B_CURRENT_TEAM) 2265 return true; 2266 2267 Thread* thread = debug_get_debugged_thread(); 2268 return thread != NULL && thread->team != NULL 2269 && thread->team->id == teamID; 2270 } 2271 2272 2273 // #pragma mark - 2274 // userland syscalls 2275 2276 2277 status_t 2278 _user_kernel_debugger(const char *userMessage) 2279 { 2280 if (geteuid() != 0) 2281 return B_NOT_ALLOWED; 2282 2283 char message[512]; 2284 strcpy(message, "USER: "); 2285 size_t len = strlen(message); 2286 2287 if (userMessage == NULL || !IS_USER_ADDRESS(userMessage) 2288 || user_strlcpy(message + len, userMessage, sizeof(message) - len) 2289 < 0) { 2290 return B_BAD_ADDRESS; 2291 } 2292 2293 kernel_debugger(message); 2294 return B_OK; 2295 } 2296 2297 2298 void 2299 _user_debug_output(const char* userString) 2300 { 2301 if (!sSerialDebugEnabled && !sSyslogOutputEnabled) 2302 return; 2303 2304 if (!IS_USER_ADDRESS(userString)) 2305 return; 2306 2307 char string[512]; 2308 int32 length; 2309 int32 toWrite; 2310 do { 2311 length = user_strlcpy(string, userString, sizeof(string)); 2312 if (length <= 0) 2313 break; 2314 toWrite = std::min(length, (int32)sizeof(string) - 1); 2315 debug_puts(string, toWrite); 2316 userString += toWrite; 2317 } while (length > toWrite); 2318 } 2319 2320 2321 void 2322 dump_block(const char* buffer, int size, const char* prefix) 2323 { 2324 const int DUMPED_BLOCK_SIZE = 16; 2325 int i; 2326 2327 for (i = 0; i < size;) { 2328 int start = i; 2329 2330 dprintf("%s%04x ", prefix, i); 2331 for (; i < start + DUMPED_BLOCK_SIZE; i++) { 2332 if (!(i % 4)) 2333 dprintf(" "); 2334 2335 if (i >= size) 2336 dprintf(" "); 2337 else 2338 dprintf("%02x", *(unsigned char*)(buffer + i)); 2339 } 2340 dprintf(" "); 2341 2342 for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) { 2343 if (i < size) { 2344 char c = buffer[i]; 2345 2346 if (c < 30) 2347 dprintf("."); 2348 else 2349 dprintf("%c", c); 2350 } else 2351 break; 2352 } 2353 dprintf("\n"); 2354 } 2355 } 2356