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