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, int32& previousCPU) 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 previousCPU = sDebuggerOnCPU; 974 sDebuggerOnCPU = cpu; 975 976 if (sBlueScreenOutput) { 977 if (blue_screen_enter(false) == B_OK) 978 sBlueScreenEnabled = true; 979 } 980 981 sDebugOutputFilter = &gDefaultDebugOutputFilter; 982 983 sDebuggedThread = NULL; 984 985 // sort the commands 986 sort_debugger_commands(); 987 988 call_modules_hook(true); 989 } 990 991 992 static void 993 exit_kernel_debugger() 994 { 995 call_modules_hook(false); 996 set_dprintf_enabled(sPreviousDprintfState); 997 998 sDebugOutputFilter = NULL; 999 1000 sBlueScreenEnabled = false; 1001 if (sDebugScreenEnabled) 1002 blue_screen_enter(true); 1003 1004 atomic_add(&sInDebugger, -1); 1005 } 1006 1007 1008 static void 1009 hand_over_kernel_debugger() 1010 { 1011 // Wait until the hand-over is complete. 1012 // The other CPU gets our sInDebugger reference and will release it when 1013 // done. Note, that there's a small race condition: the other CPU could 1014 // hand over to another CPU without us noticing. Since this is only 1015 // initiated by the user, it is harmless, though. 1016 sHandOverKDL = true; 1017 while (atomic_get(&sHandOverKDLToCPU) >= 0) 1018 cpu_wait(&sHandOverKDLToCPU, -1); 1019 } 1020 1021 1022 static void 1023 kernel_debugger_internal(const char* messagePrefix, const char* message, 1024 va_list args, int32 cpu) 1025 { 1026 while (true) { 1027 // If we're called recursively sDebuggerOnCPU will be != -1. 1028 int32 previousCPU = -1; 1029 1030 if (sHandOverKDLToCPU == cpu) { 1031 sHandOverKDLToCPU = -1; 1032 sHandOverKDL = false; 1033 1034 previousCPU = sDebuggerOnCPU; 1035 sDebuggerOnCPU = cpu; 1036 } else 1037 enter_kernel_debugger(cpu, previousCPU); 1038 1039 kernel_debugger_loop(messagePrefix, message, args, cpu); 1040 1041 if (sHandOverKDLToCPU < 0 && previousCPU == -1) { 1042 // We're not handing over to a different CPU and we weren't 1043 // called recursively, so we'll exit the debugger. 1044 exit_kernel_debugger(); 1045 } 1046 1047 sDebuggerOnCPU = previousCPU; 1048 1049 if (sHandOverKDLToCPU < 0) 1050 break; 1051 1052 hand_over_kernel_debugger(); 1053 1054 debug_trap_cpu_in_kdl(cpu, true); 1055 1056 if (sHandOverKDLToCPU != cpu) 1057 break; 1058 } 1059 } 1060 1061 1062 static int 1063 cmd_dump_kdl_message(int argc, char** argv) 1064 { 1065 print_kernel_debugger_message(); 1066 return 0; 1067 } 1068 1069 1070 static int 1071 cmd_execute_panic_commands(int argc, char** argv) 1072 { 1073 execute_panic_commands(); 1074 return 0; 1075 } 1076 1077 1078 static int 1079 cmd_dump_syslog(int argc, char** argv) 1080 { 1081 if (!sSyslogOutputEnabled) { 1082 kprintf("Syslog is not enabled.\n"); 1083 return 0; 1084 } 1085 1086 bool unsentOnly = false; 1087 bool ignoreKDLOutput = true; 1088 1089 int argi = 1; 1090 for (; argi < argc; argi++) { 1091 if (strcmp(argv[argi], "-n") == 0) 1092 unsentOnly = true; 1093 else if (strcmp(argv[argi], "-k") == 0) 1094 ignoreKDLOutput = false; 1095 else 1096 break; 1097 } 1098 1099 if (argi < argc) { 1100 print_debugger_command_usage(argv[0]); 1101 return 0; 1102 } 1103 1104 size_t debuggerOffset = sSyslogDebuggerOffset; 1105 size_t start = unsentOnly ? sSyslogBufferOffset : 0; 1106 size_t end = ignoreKDLOutput 1107 ? debuggerOffset : ring_buffer_readable(sSyslogBuffer); 1108 1109 // allocate a buffer for processing the syslog output 1110 size_t bufferSize = 1024; 1111 char* buffer = (char*)debug_malloc(bufferSize); 1112 char stackBuffer[64]; 1113 if (buffer == NULL) { 1114 buffer = stackBuffer; 1115 bufferSize = sizeof(stackBuffer); 1116 } 1117 1118 // filter the output 1119 bool newLine = false; 1120 while (start < end) { 1121 size_t bytesRead = ring_buffer_peek(sSyslogBuffer, start, buffer, 1122 std::min(end - start, bufferSize - 1)); 1123 if (bytesRead == 0) 1124 break; 1125 start += bytesRead; 1126 1127 // remove '\0' and 0xcc 1128 size_t toPrint = 0; 1129 for (size_t i = 0; i < bytesRead; i++) { 1130 if (buffer[i] != '\0' && (uint8)buffer[i] != 0xcc) 1131 buffer[toPrint++] = buffer[i]; 1132 } 1133 1134 if (toPrint > 0) { 1135 newLine = buffer[toPrint - 1] == '\n'; 1136 buffer[toPrint] = '\0'; 1137 kputs(buffer); 1138 } 1139 1140 if (debuggerOffset > sSyslogDebuggerOffset) { 1141 // Our output caused older syslog output to be evicted from the 1142 // syslog buffer. We need to adjust our offsets accordingly. Note, 1143 // this can still go wrong, if the buffer was already full and more 1144 // was written to it than we have processed, but we can't help that. 1145 size_t diff = debuggerOffset - sSyslogDebuggerOffset; 1146 start -= std::min(start, diff); 1147 end -= std::min(end, diff); 1148 debuggerOffset = sSyslogDebuggerOffset; 1149 } 1150 } 1151 1152 if (!newLine) 1153 kputs("\n"); 1154 1155 if (buffer != stackBuffer) 1156 debug_free(buffer); 1157 1158 return 0; 1159 } 1160 1161 1162 static int 1163 cmd_switch_cpu(int argc, char** argv) 1164 { 1165 if (argc > 2) { 1166 print_debugger_command_usage(argv[0]); 1167 return 0; 1168 } 1169 1170 if (argc == 1) { 1171 kprintf("running on CPU %" B_PRId32 "\n", smp_get_current_cpu()); 1172 return 0; 1173 } 1174 1175 int32 newCPU = parse_expression(argv[1]); 1176 if (newCPU < 0 || newCPU >= smp_get_num_cpus()) { 1177 kprintf("invalid CPU index\n"); 1178 return 0; 1179 } 1180 1181 if (newCPU == smp_get_current_cpu()) { 1182 kprintf("already running on CPU %" B_PRId32 "\n", newCPU); 1183 return 0; 1184 } 1185 1186 sHandOverKDLToCPU = newCPU; 1187 1188 return B_KDEBUG_QUIT; 1189 } 1190 1191 1192 static status_t 1193 syslog_sender(void* data) 1194 { 1195 bool bufferPending = false; 1196 int32 length = 0; 1197 1198 while (true) { 1199 // wait for syslog data to become available 1200 acquire_sem_etc(sSyslogNotify, 1, B_RELATIVE_TIMEOUT, 5000000); 1201 // Note: We time out since in some situations output is added to 1202 // the syslog buffer without being allowed to notify us (e.g. in 1203 // the kernel debugger). 1204 // TODO: A semaphore is rather unhandy here. It is released for 1205 // every single message written to the buffer, but we potentially 1206 // send a lot more than a single message per iteration. On the other 1207 // hand, as long as the syslog daemon is not running, we acquire 1208 // the semaphore anyway. A better solution would be a flag + a 1209 // condition variable. 1210 1211 sSyslogMessage->when = real_time_clock(); 1212 1213 if (!bufferPending) { 1214 // We need to have exclusive access to our syslog buffer 1215 cpu_status state = disable_interrupts(); 1216 acquire_spinlock(&sSpinlock); 1217 1218 length = ring_buffer_readable(sSyslogBuffer) 1219 - sSyslogBufferOffset; 1220 if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH) 1221 length = SYSLOG_MAX_MESSAGE_LENGTH; 1222 1223 uint8* message = (uint8*)sSyslogMessage->message; 1224 if (sSyslogDropped) { 1225 memcpy(message, "<DROP>", 6); 1226 message += 6; 1227 if ((length + 6) > (int32)SYSLOG_MAX_MESSAGE_LENGTH) 1228 length -= 6; 1229 sSyslogDropped = false; 1230 } 1231 1232 length = ring_buffer_peek(sSyslogBuffer, sSyslogBufferOffset, 1233 message, length); 1234 sSyslogBufferOffset += length; 1235 length += (addr_t)message - (addr_t)sSyslogMessage->message; 1236 1237 release_spinlock(&sSpinlock); 1238 restore_interrupts(state); 1239 } 1240 1241 if (length == 0) { 1242 // The buffer we came here for might have been sent already 1243 bufferPending = false; 1244 continue; 1245 } 1246 1247 status_t status = write_port_etc(sSyslogPort, SYSLOG_MESSAGE, 1248 sSyslogMessage, sizeof(struct syslog_message) + length, 1249 B_RELATIVE_TIMEOUT, 0); 1250 if (status == B_BAD_PORT_ID) { 1251 // The port is gone, there is no need to run anymore 1252 sSyslogWriter = -1; 1253 return status; 1254 } 1255 1256 if (status != B_OK) { 1257 // Sending has failed - just wait, maybe it'll work later. 1258 bufferPending = true; 1259 continue; 1260 } 1261 1262 if (bufferPending) { 1263 // We could write the last pending buffer, try to read more 1264 // from the syslog ring buffer 1265 release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE); 1266 bufferPending = false; 1267 } 1268 } 1269 1270 return 0; 1271 } 1272 1273 1274 static void 1275 syslog_write(const char* text, int32 length, bool notify) 1276 { 1277 if (sSyslogBuffer == NULL) 1278 return; 1279 1280 if (length > sSyslogBuffer->size) { 1281 syslog_write("<TRUNC>", 7, false); 1282 1283 text += length - (sSyslogBuffer->size - 7); 1284 length = sSyslogBuffer->size - 7; 1285 } 1286 1287 int32 writable = ring_buffer_writable(sSyslogBuffer); 1288 if (writable < length) { 1289 // drop old data 1290 size_t toDrop = length - writable; 1291 ring_buffer_flush(sSyslogBuffer, toDrop); 1292 1293 if (toDrop > sSyslogBufferOffset) { 1294 sSyslogBufferOffset = 0; 1295 sSyslogDropped = true; 1296 } else 1297 sSyslogBufferOffset -= toDrop; 1298 1299 sSyslogDebuggerOffset -= std::min(toDrop, sSyslogDebuggerOffset); 1300 } 1301 1302 ring_buffer_write(sSyslogBuffer, (uint8*)text, length); 1303 1304 if (notify) 1305 release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE); 1306 } 1307 1308 1309 static status_t 1310 syslog_init_post_threads(void) 1311 { 1312 if (!sSyslogOutputEnabled) 1313 return B_OK; 1314 1315 sSyslogNotify = create_sem(0, "syslog data"); 1316 if (sSyslogNotify >= 0) 1317 return B_OK; 1318 1319 // initializing kernel syslog service failed -- disable it 1320 1321 sSyslogOutputEnabled = false; 1322 1323 if (sSyslogBuffer != NULL) { 1324 if (sDebugSyslog) 1325 delete_area(area_for(sSyslogBuffer)); 1326 else 1327 delete_ring_buffer(sSyslogBuffer); 1328 1329 sSyslogBuffer = NULL; 1330 } 1331 1332 free(sSyslogMessage); 1333 delete_sem(sSyslogNotify); 1334 1335 return B_ERROR; 1336 } 1337 1338 1339 static status_t 1340 syslog_init_post_vm(struct kernel_args* args) 1341 { 1342 status_t status; 1343 int32 length = 0; 1344 1345 if (!sSyslogOutputEnabled) { 1346 sSyslogBuffer = NULL; 1347 // Might already have been set in syslog_init(), if the debug syslog 1348 // was enabled. Just drop it -- we'll never create the area. 1349 return B_OK; 1350 } 1351 1352 sSyslogMessage = (syslog_message*)malloc(SYSLOG_MESSAGE_BUFFER_SIZE); 1353 if (sSyslogMessage == NULL) { 1354 status = B_NO_MEMORY; 1355 goto err1; 1356 } 1357 1358 if (sSyslogBuffer == NULL) { 1359 size_t bufferSize = DEFAULT_SYSLOG_BUFFER_SIZE; 1360 void* handle = load_driver_settings("kernel"); 1361 if (handle != NULL) { 1362 const char* sizeString = get_driver_parameter(handle, 1363 "syslog_buffer_size", NULL, NULL); 1364 if (sizeString != NULL) { 1365 bufferSize = strtoul(sizeString, NULL, 0); 1366 if (bufferSize > 262144) 1367 bufferSize = 262144; 1368 else if (bufferSize < SYSLOG_MESSAGE_BUFFER_SIZE) 1369 bufferSize = SYSLOG_MESSAGE_BUFFER_SIZE; 1370 } 1371 1372 unload_driver_settings(handle); 1373 } 1374 1375 sSyslogBuffer = create_ring_buffer(bufferSize); 1376 1377 if (sSyslogBuffer == NULL) { 1378 status = B_NO_MEMORY; 1379 goto err2; 1380 } 1381 } else if (args->keep_debug_output_buffer) { 1382 // create an area for the already-existing debug syslog buffer 1383 void* base = (void*)ROUNDDOWN((addr_t)(void *)args->debug_output, B_PAGE_SIZE); 1384 size_t size = ROUNDUP(args->debug_size, B_PAGE_SIZE); 1385 area_id area = create_area("syslog debug", &base, B_EXACT_ADDRESS, size, 1386 B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); 1387 if (area < 0) { 1388 status = B_NO_MEMORY; 1389 goto err2; 1390 } 1391 } 1392 1393 if (!args->keep_debug_output_buffer && args->debug_output != NULL) { 1394 syslog_write((const char*)args->debug_output.Pointer(), 1395 args->debug_size, false); 1396 } 1397 1398 // initialize syslog message 1399 sSyslogMessage->from = 0; 1400 sSyslogMessage->options = LOG_KERN; 1401 sSyslogMessage->priority = LOG_DEBUG; 1402 sSyslogMessage->ident[0] = '\0'; 1403 1404 // Allocate memory for the previous session's debug syslog output. In 1405 // syslog_init_post_modules() we'll write it back to disk and free it. 1406 if (args->previous_debug_output != NULL) { 1407 sPreviousSessionSyslogBuffer = malloc(args->previous_debug_size); 1408 if (sPreviousSessionSyslogBuffer != NULL) { 1409 sPreviousSessionSyslogBufferSize = args->previous_debug_size; 1410 memcpy(sPreviousSessionSyslogBuffer, args->previous_debug_output, 1411 sPreviousSessionSyslogBufferSize); 1412 } 1413 } 1414 1415 char revisionBuffer[64]; 1416 length = snprintf(revisionBuffer, sizeof(revisionBuffer), 1417 "Welcome to syslog debug output!\nHaiku revision: %s\n", 1418 get_haiku_revision()); 1419 syslog_write(revisionBuffer, 1420 std::min(length, (int32)sizeof(revisionBuffer) - 1), false); 1421 1422 add_debugger_command_etc("syslog", &cmd_dump_syslog, 1423 "Dumps the syslog buffer.", 1424 "[ \"-n\" ] [ \"-k\" ]\n" 1425 "Dumps the whole syslog buffer, or, if -k is specified, only " 1426 "the part that hasn't been sent yet.\n", 0); 1427 1428 return B_OK; 1429 1430 err2: 1431 free(sSyslogMessage); 1432 err1: 1433 sSyslogOutputEnabled = false; 1434 sSyslogBuffer = NULL; 1435 return status; 1436 } 1437 1438 static void 1439 syslog_init_post_modules() 1440 { 1441 if (sPreviousSessionSyslogBuffer == NULL) 1442 return; 1443 1444 void* buffer = sPreviousSessionSyslogBuffer; 1445 size_t bufferSize = sPreviousSessionSyslogBufferSize; 1446 sPreviousSessionSyslogBuffer = NULL; 1447 sPreviousSessionSyslogBufferSize = 0; 1448 MemoryDeleter bufferDeleter(buffer); 1449 1450 int fd = open("/var/log/previous_syslog", O_WRONLY | O_CREAT | O_TRUNC, 1451 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 1452 if (fd < 0) { 1453 dprintf("Failed to open previous syslog file: %s\n", strerror(errno)); 1454 return; 1455 } 1456 1457 write(fd, buffer, bufferSize); 1458 close(fd); 1459 } 1460 1461 static status_t 1462 syslog_init(struct kernel_args* args) 1463 { 1464 if (!args->keep_debug_output_buffer || args->debug_output == NULL) 1465 return B_OK; 1466 1467 sSyslogBuffer = create_ring_buffer_etc(args->debug_output, args->debug_size, 1468 RING_BUFFER_INIT_FROM_BUFFER); 1469 sDebugSyslog = true; 1470 1471 return B_OK; 1472 } 1473 1474 1475 static void 1476 debug_memcpy_trampoline(void* _parameters) 1477 { 1478 debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters; 1479 memcpy(parameters->to, parameters->from, parameters->size); 1480 } 1481 1482 1483 static void 1484 debug_strlcpy_trampoline(void* _parameters) 1485 { 1486 debug_strlcpy_parameters* parameters 1487 = (debug_strlcpy_parameters*)_parameters; 1488 parameters->result = strlcpy(parameters->to, parameters->from, 1489 parameters->size); 1490 } 1491 1492 1493 void 1494 call_modules_hook(bool enter) 1495 { 1496 uint32 index = 0; 1497 while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) { 1498 debugger_module_info* module = sDebuggerModules[index]; 1499 1500 if (enter && module->enter_debugger != NULL) 1501 module->enter_debugger(); 1502 else if (!enter && module->exit_debugger != NULL) 1503 module->exit_debugger(); 1504 1505 index++; 1506 } 1507 } 1508 1509 1510 //! Must be called with the sSpinlock held. 1511 static void 1512 debug_output(const char* string, int32 length, bool notifySyslog) 1513 { 1514 if (length >= OUTPUT_BUFFER_SIZE) 1515 length = OUTPUT_BUFFER_SIZE - 1; 1516 1517 if (length > 1 && string[length - 1] == '\n' 1518 && strncmp(string, sLastOutputBuffer, length) == 0) { 1519 sMessageRepeatCount++; 1520 sMessageRepeatLastTime = system_time(); 1521 if (sMessageRepeatFirstTime == 0) 1522 sMessageRepeatFirstTime = sMessageRepeatLastTime; 1523 } else { 1524 flush_pending_repeats(notifySyslog); 1525 1526 if (sSerialDebugEnabled) 1527 arch_debug_serial_puts(string); 1528 if (sSyslogOutputEnabled) 1529 syslog_write(string, length, notifySyslog); 1530 if (sBlueScreenEnabled || sDebugScreenEnabled) 1531 blue_screen_puts(string); 1532 if (sSerialDebugEnabled) { 1533 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1534 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 1535 sDebuggerModules[i]->debugger_puts(string, length); 1536 } 1537 } 1538 1539 memcpy(sLastOutputBuffer, string, length); 1540 sLastOutputBuffer[length] = 0; 1541 } 1542 } 1543 1544 1545 //! Must be called with the sSpinlock held. 1546 static void 1547 flush_pending_repeats(bool notifySyslog) 1548 { 1549 if (sMessageRepeatCount <= 0) 1550 return; 1551 1552 if (sMessageRepeatCount > 1) { 1553 static char temp[40]; 1554 size_t length = snprintf(temp, sizeof(temp), 1555 "Last message repeated %" B_PRId32 " times.\n", sMessageRepeatCount); 1556 length = std::min(length, sizeof(temp) - 1); 1557 1558 if (sSerialDebugEnabled) 1559 arch_debug_serial_puts(temp); 1560 if (sSyslogOutputEnabled) 1561 syslog_write(temp, length, notifySyslog); 1562 if (sBlueScreenEnabled || sDebugScreenEnabled) 1563 blue_screen_puts(temp); 1564 if (sSerialDebugEnabled) { 1565 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1566 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) 1567 sDebuggerModules[i]->debugger_puts(temp, length); 1568 } 1569 } 1570 } else { 1571 // if we only have one repeat just reprint the last buffer 1572 size_t length = strlen(sLastOutputBuffer); 1573 1574 if (sSerialDebugEnabled) 1575 arch_debug_serial_puts(sLastOutputBuffer); 1576 if (sSyslogOutputEnabled) 1577 syslog_write(sLastOutputBuffer, length, notifySyslog); 1578 if (sBlueScreenEnabled || sDebugScreenEnabled) 1579 blue_screen_puts(sLastOutputBuffer); 1580 if (sSerialDebugEnabled) { 1581 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1582 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) { 1583 sDebuggerModules[i]->debugger_puts(sLastOutputBuffer, 1584 length); 1585 } 1586 } 1587 } 1588 } 1589 1590 sMessageRepeatFirstTime = 0; 1591 sMessageRepeatCount = 0; 1592 } 1593 1594 1595 static void 1596 check_pending_repeats(void* /*data*/, int /*iteration*/) 1597 { 1598 if (sMessageRepeatCount > 0 1599 && (system_time() - sMessageRepeatLastTime > 1000000 1600 || system_time() - sMessageRepeatFirstTime > 3000000)) { 1601 cpu_status state = disable_interrupts(); 1602 acquire_spinlock(&sSpinlock); 1603 1604 flush_pending_repeats(true); 1605 1606 release_spinlock(&sSpinlock); 1607 restore_interrupts(state); 1608 } 1609 } 1610 1611 1612 static void 1613 dprintf_args(const char* format, va_list args, bool notifySyslog) 1614 { 1615 if (are_interrupts_enabled()) { 1616 MutexLocker locker(sOutputLock); 1617 1618 int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format, 1619 args); 1620 length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1); 1621 1622 InterruptsSpinLocker _(sSpinlock); 1623 debug_output(sOutputBuffer, length, notifySyslog); 1624 } else { 1625 InterruptsSpinLocker _(sSpinlock); 1626 1627 int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, 1628 format, args); 1629 length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1); 1630 1631 debug_output(sInterruptOutputBuffer, length, notifySyslog); 1632 } 1633 } 1634 1635 1636 // #pragma mark - private kernel API 1637 1638 1639 bool 1640 debug_screen_output_enabled(void) 1641 { 1642 return sDebugScreenEnabled; 1643 } 1644 1645 1646 void 1647 debug_stop_screen_debug_output(void) 1648 { 1649 sDebugScreenEnabled = false; 1650 } 1651 1652 1653 bool 1654 debug_debugger_running(void) 1655 { 1656 return sDebuggerOnCPU != -1; 1657 } 1658 1659 1660 void 1661 debug_puts(const char* string, int32 length) 1662 { 1663 InterruptsSpinLocker _(sSpinlock); 1664 debug_output(string, length, true); 1665 } 1666 1667 1668 void 1669 debug_early_boot_message(const char* string) 1670 { 1671 arch_debug_serial_early_boot_message(string); 1672 } 1673 1674 1675 void 1676 debug_init(kernel_args* args) 1677 { 1678 new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter; 1679 1680 syslog_init(args); 1681 1682 debug_paranoia_init(); 1683 arch_debug_console_init(args); 1684 } 1685 1686 1687 void 1688 debug_init_post_vm(kernel_args* args) 1689 { 1690 add_debugger_command_etc("cpu", &cmd_switch_cpu, 1691 "Switches to another CPU.", 1692 "<cpu>\n" 1693 "Switches to CPU with the index <cpu>.\n", 0); 1694 add_debugger_command_etc("message", &cmd_dump_kdl_message, 1695 "Reprint the message printed when entering KDL", 1696 "\n" 1697 "Reprints the message printed when entering KDL.\n", 0); 1698 add_debugger_command_etc("panic_commands", &cmd_execute_panic_commands, 1699 "Execute commands associated with the panic() that caused " 1700 "entering KDL", 1701 "\n" 1702 "Executes the commands associated with the panic() that caused " 1703 "entering KDL.\n", 0); 1704 1705 debug_builtin_commands_init(); 1706 arch_debug_init(args); 1707 1708 debug_heap_init(); 1709 debug_variables_init(); 1710 frame_buffer_console_init(args); 1711 tracing_init(); 1712 } 1713 1714 1715 void 1716 debug_init_post_settings(struct kernel_args* args) 1717 { 1718 // get debug settings 1719 1720 sSerialDebugEnabled = get_safemode_boolean("serial_debug_output", 1721 sSerialDebugEnabled); 1722 sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output", 1723 sSyslogOutputEnabled); 1724 sBlueScreenOutput = get_safemode_boolean("bluescreen", true); 1725 sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys", 1726 sEmergencyKeysEnabled); 1727 sDebugScreenEnabled = get_safemode_boolean("debug_screen", false); 1728 1729 if ((sBlueScreenOutput || sDebugScreenEnabled) 1730 && blue_screen_init() != B_OK) 1731 sBlueScreenOutput = sDebugScreenEnabled = false; 1732 1733 if (sDebugScreenEnabled) 1734 blue_screen_enter(true); 1735 1736 arch_debug_console_init_settings(args); 1737 syslog_init_post_vm(args); 1738 } 1739 1740 1741 void 1742 debug_init_post_modules(struct kernel_args* args) 1743 { 1744 syslog_init_post_modules(); 1745 1746 // check for dupped lines every 10/10 second 1747 register_kernel_daemon(check_pending_repeats, NULL, 10); 1748 1749 syslog_init_post_threads(); 1750 1751 // load kernel debugger addons 1752 1753 static const char* kDemanglePrefix = "debugger/demangle/"; 1754 1755 void* cookie = open_module_list("debugger"); 1756 uint32 count = 0; 1757 while (count < kMaxDebuggerModules) { 1758 char name[B_FILE_NAME_LENGTH]; 1759 size_t nameLength = sizeof(name); 1760 1761 if (read_next_module_name(cookie, name, &nameLength) != B_OK) 1762 break; 1763 1764 // get demangle module, if any 1765 if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) { 1766 if (sDemangleModule == NULL) 1767 get_module(name, (module_info**)&sDemangleModule); 1768 continue; 1769 } 1770 1771 if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) { 1772 dprintf("kernel debugger extension \"%s\": loaded\n", name); 1773 count++; 1774 } else 1775 dprintf("kernel debugger extension \"%s\": failed to load\n", name); 1776 } 1777 close_module_list(cookie); 1778 1779 frame_buffer_console_init_post_modules(args); 1780 } 1781 1782 1783 void 1784 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags) 1785 { 1786 sPageFaultInfo.fault_address = faultAddress; 1787 sPageFaultInfo.pc = pc; 1788 sPageFaultInfo.flags = flags; 1789 } 1790 1791 1792 debug_page_fault_info* 1793 debug_get_page_fault_info() 1794 { 1795 return &sPageFaultInfo; 1796 } 1797 1798 1799 void 1800 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver) 1801 { 1802 InterruptsLocker locker; 1803 1804 // return, if we've been called recursively (we call 1805 // smp_intercpu_int_handler() below) 1806 if (sCPUTrapped[cpu]) 1807 return; 1808 1809 arch_debug_save_registers(&sDebugRegisters[cpu]); 1810 1811 sCPUTrapped[cpu] = true; 1812 1813 while (sInDebugger != 0) { 1814 if (sHandOverKDL && sHandOverKDLToCPU == cpu) { 1815 if (returnIfHandedOver) 1816 break; 1817 1818 kernel_debugger_internal(NULL, NULL, 1819 sCurrentKernelDebuggerMessageArgs, cpu); 1820 } else 1821 smp_intercpu_int_handler(cpu); 1822 } 1823 1824 sCPUTrapped[cpu] = false; 1825 } 1826 1827 1828 void 1829 debug_double_fault(int32 cpu) 1830 { 1831 kernel_debugger_internal("Double Fault!", NULL, 1832 sCurrentKernelDebuggerMessageArgs, cpu); 1833 } 1834 1835 1836 bool 1837 debug_emergency_key_pressed(char key) 1838 { 1839 if (!sEmergencyKeysEnabled) 1840 return false; 1841 1842 if (key == 'd') { 1843 kernel_debugger("Keyboard Requested Halt."); 1844 return true; 1845 } 1846 1847 // Broadcast to the kernel debugger modules 1848 1849 for (uint32 i = 0; i < kMaxDebuggerModules; i++) { 1850 if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) { 1851 if (sDebuggerModules[i]->emergency_key_pressed(key)) 1852 return true; 1853 } 1854 } 1855 1856 return false; 1857 } 1858 1859 1860 /*! Verifies that the complete given memory range is accessible in the current 1861 context. 1862 1863 Invoked in the kernel debugger only. 1864 1865 \param address The start address of the memory range to be checked. 1866 \param size The size of the memory range to be checked. 1867 \param protection The area protection for which to check. Valid is a bitwise 1868 or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA. 1869 \return \c true, if the complete memory range can be accessed in all ways 1870 specified by \a protection, \c false otherwise. 1871 */ 1872 bool 1873 debug_is_kernel_memory_accessible(addr_t address, size_t size, 1874 uint32 protection) 1875 { 1876 addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE); 1877 address = ROUNDDOWN(address, B_PAGE_SIZE); 1878 1879 if (!IS_KERNEL_ADDRESS(address) || endAddress < address) 1880 return false; 1881 1882 for (; address < endAddress; address += B_PAGE_SIZE) { 1883 if (!arch_vm_translation_map_is_kernel_page_accessible(address, 1884 protection)) { 1885 return false; 1886 } 1887 } 1888 1889 return true; 1890 } 1891 1892 1893 /*! Calls a function in a setjmp() + fault handler context. 1894 May only be used in the kernel debugger. 1895 1896 \param jumpBuffer Buffer to be used for setjmp()/longjmp(). 1897 \param function The function to be called. 1898 \param parameter The parameter to be passed to the function to be called. 1899 \return 1900 - \c 0, when the function executed without causing a page fault or 1901 calling longjmp(). 1902 - \c 1, when the function caused a page fault. 1903 - Any other value the function passes to longjmp(). 1904 */ 1905 int 1906 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*), 1907 void* parameter) 1908 { 1909 // save current fault handler 1910 cpu_ent* cpu = gCPU + sDebuggerOnCPU; 1911 addr_t oldFaultHandler = cpu->fault_handler; 1912 addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer; 1913 1914 int result = setjmp(jumpBuffer); 1915 if (result == 0) { 1916 arch_debug_call_with_fault_handler(cpu, jumpBuffer, function, 1917 parameter); 1918 } 1919 1920 // restore old fault handler 1921 cpu->fault_handler = oldFaultHandler; 1922 cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer; 1923 1924 return result; 1925 } 1926 1927 1928 /*! Similar to user_memcpy(), but can only be invoked from within the kernel 1929 debugger (and must not be used outside). 1930 The supplied \a teamID specifies the address space in which to interpret 1931 the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(), 1932 or any valid team ID. If the addresses are both kernel addresses, the 1933 argument is ignored and the current address space is used. 1934 */ 1935 status_t 1936 debug_memcpy(team_id teamID, void* to, const void* from, size_t size) 1937 { 1938 // don't allow address overflows 1939 if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to) 1940 return B_BAD_ADDRESS; 1941 1942 // Try standard memcpy() with fault handler, if the addresses can be 1943 // interpreted in the current address space. 1944 if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to)) 1945 || debug_is_debugged_team(teamID)) { 1946 debug_memcpy_parameters parameters = {to, from, size}; 1947 1948 if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer, 1949 &debug_memcpy_trampoline, ¶meters) == 0) { 1950 return B_OK; 1951 } 1952 } 1953 1954 // Try harder. The pages of the respective memory could be unmapped but 1955 // still exist in a cache (the page daemon does that with inactive pages). 1956 while (size > 0) { 1957 uint8 buffer[32]; 1958 size_t toCopy = std::min(size, sizeof(buffer)); 1959 1960 // restrict the size so we don't cross page boundaries 1961 if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy) 1962 toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE; 1963 if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy) 1964 toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE; 1965 1966 if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy, 1967 false) != B_OK 1968 || vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true) 1969 != B_OK) { 1970 return B_BAD_ADDRESS; 1971 } 1972 1973 from = (const uint8*)from + toCopy; 1974 to = (uint8*)to + toCopy; 1975 size -= toCopy; 1976 } 1977 1978 return B_OK; 1979 } 1980 1981 1982 /*! Similar to user_strlcpy(), but can only be invoked from within the kernel 1983 debugger (and must not be used outside). 1984 The supplied \a teamID specifies the address space in which to interpret 1985 the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(), 1986 or any valid team ID. If the addresses are both kernel addresses, the 1987 argument is ignored and the current address space is used. 1988 */ 1989 ssize_t 1990 debug_strlcpy(team_id teamID, char* to, const char* from, size_t size) 1991 { 1992 if (from == NULL || (to == NULL && size > 0)) 1993 return B_BAD_ADDRESS; 1994 1995 // limit size to avoid address overflows 1996 size_t maxSize = std::min((addr_t)size, 1997 ~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1); 1998 // NOTE: Since strlcpy() determines the length of \a from, the source 1999 // address might still overflow. 2000 2001 // Try standard strlcpy() with fault handler, if the addresses can be 2002 // interpreted in the current address space. 2003 if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to)) 2004 || debug_is_debugged_team(teamID)) { 2005 debug_strlcpy_parameters parameters = {to, from, maxSize}; 2006 2007 if (debug_call_with_fault_handler( 2008 gCPU[sDebuggerOnCPU].fault_jump_buffer, 2009 &debug_strlcpy_trampoline, ¶meters) == 0) { 2010 // If we hit the address overflow boundary, fail. 2011 if (parameters.result >= maxSize && maxSize < size) 2012 return B_BAD_ADDRESS; 2013 2014 return parameters.result; 2015 } 2016 } 2017 2018 // Try harder. The pages of the respective memory could be unmapped but 2019 // still exist in a cache (the page daemon does that with inactive pages). 2020 size_t totalLength = 0; 2021 while (maxSize > 0) { 2022 char buffer[32]; 2023 size_t toCopy = std::min(maxSize, sizeof(buffer)); 2024 2025 // restrict the size so we don't cross page boundaries 2026 if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy) 2027 toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE; 2028 if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy) 2029 toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE; 2030 2031 // copy the next part of the string from the source 2032 if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy, 2033 false) != B_OK) { 2034 return B_BAD_ADDRESS; 2035 } 2036 2037 // determine the length of the part and whether we've reached the end 2038 // of the string 2039 size_t length = strnlen(buffer, toCopy); 2040 bool endOfString = length < toCopy; 2041 2042 from = (const char*)from + toCopy; 2043 totalLength += length; 2044 maxSize -= length; 2045 2046 if (endOfString) { 2047 // only copy the actual string, including the terminating null 2048 toCopy = length + 1; 2049 } 2050 2051 if (size > 0) { 2052 // We still have space left in the target buffer. 2053 if (size <= length) { 2054 // Not enough space for the complete part. Null-terminate it and 2055 // copy what we can. 2056 buffer[size - 1] = '\0'; 2057 totalLength += length - size; 2058 toCopy = size; 2059 } 2060 2061 if (vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true) 2062 != B_OK) { 2063 return B_BAD_ADDRESS; 2064 } 2065 2066 to = (char*)to + toCopy; 2067 size -= toCopy; 2068 } 2069 2070 if (endOfString) 2071 return totalLength; 2072 } 2073 2074 return totalLength; 2075 } 2076 2077 2078 // #pragma mark - public API 2079 2080 2081 uint64 2082 parse_expression(const char* expression) 2083 { 2084 uint64 result; 2085 return evaluate_debug_expression(expression, &result, true) ? result : 0; 2086 } 2087 2088 2089 void 2090 panic(const char* format, ...) 2091 { 2092 va_list args; 2093 va_start(args, format); 2094 2095 cpu_status state = disable_interrupts(); 2096 2097 kernel_debugger_internal("PANIC: ", format, args, 2098 thread_get_current_thread() ? smp_get_current_cpu() : 0); 2099 2100 restore_interrupts(state); 2101 2102 va_end(args); 2103 } 2104 2105 2106 void 2107 kernel_debugger(const char* message) 2108 { 2109 cpu_status state = disable_interrupts(); 2110 2111 kernel_debugger_internal(message, NULL, sCurrentKernelDebuggerMessageArgs, 2112 smp_get_current_cpu()); 2113 2114 restore_interrupts(state); 2115 } 2116 2117 2118 bool 2119 set_dprintf_enabled(bool newState) 2120 { 2121 bool oldState = sSerialDebugEnabled; 2122 sSerialDebugEnabled = newState; 2123 2124 return oldState; 2125 } 2126 2127 2128 void 2129 dprintf(const char* format, ...) 2130 { 2131 va_list args; 2132 2133 if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled) 2134 return; 2135 2136 va_start(args, format); 2137 dprintf_args(format, args, true); 2138 va_end(args); 2139 } 2140 2141 2142 void 2143 dvprintf(const char* format, va_list args) 2144 { 2145 if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled) 2146 return; 2147 2148 dprintf_args(format, args, true); 2149 } 2150 2151 2152 void 2153 dprintf_no_syslog(const char* format, ...) 2154 { 2155 va_list args; 2156 2157 if (!sSerialDebugEnabled && !sBlueScreenEnabled) 2158 return; 2159 2160 va_start(args, format); 2161 dprintf_args(format, args, false); 2162 va_end(args); 2163 } 2164 2165 2166 /*! Similar to dprintf() but thought to be used in the kernel 2167 debugger only (it doesn't lock). 2168 */ 2169 void 2170 kprintf(const char* format, ...) 2171 { 2172 if (sDebugOutputFilter != NULL) { 2173 va_list args; 2174 va_start(args, format); 2175 sDebugOutputFilter->Print(format, args); 2176 va_end(args); 2177 } 2178 } 2179 2180 2181 void 2182 kprintf_unfiltered(const char* format, ...) 2183 { 2184 va_list args; 2185 va_start(args, format); 2186 gDefaultDebugOutputFilter.Print(format, args); 2187 va_end(args); 2188 } 2189 2190 2191 const char* 2192 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize, 2193 bool* _isObjectMethod) 2194 { 2195 if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) { 2196 return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize, 2197 _isObjectMethod); 2198 } 2199 2200 if (_isObjectMethod != NULL) 2201 *_isObjectMethod = false; 2202 2203 return symbol; 2204 } 2205 2206 2207 status_t 2208 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol, 2209 char* name, size_t nameSize, int32* _type, size_t* _argumentLength) 2210 { 2211 if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) { 2212 return sDemangleModule->get_next_argument(_cookie, symbol, name, 2213 nameSize, _type, _argumentLength); 2214 } 2215 2216 return B_NOT_SUPPORTED; 2217 } 2218 2219 2220 struct arch_debug_registers* 2221 debug_get_debug_registers(int32 cpu) 2222 { 2223 if (cpu < 0 || cpu > smp_get_num_cpus()) 2224 return NULL; 2225 2226 return &sDebugRegisters[cpu]; 2227 } 2228 2229 2230 Thread* 2231 debug_set_debugged_thread(Thread* thread) 2232 { 2233 Thread* previous = sDebuggedThread; 2234 sDebuggedThread = thread; 2235 return previous; 2236 } 2237 2238 2239 Thread* 2240 debug_get_debugged_thread() 2241 { 2242 return sDebuggedThread != NULL 2243 ? sDebuggedThread : thread_get_current_thread(); 2244 } 2245 2246 2247 /*! Returns whether the supplied team ID refers to the same team the currently 2248 debugged thread (debug_get_debugged_thread()) belongs to. 2249 Always returns \c true, if \c B_CURRENT_TEAM is given. 2250 */ 2251 bool 2252 debug_is_debugged_team(team_id teamID) 2253 { 2254 if (teamID == B_CURRENT_TEAM) 2255 return true; 2256 2257 Thread* thread = debug_get_debugged_thread(); 2258 return thread != NULL && thread->team != NULL 2259 && thread->team->id == teamID; 2260 } 2261 2262 2263 // #pragma mark - 2264 // userland syscalls 2265 2266 2267 status_t 2268 _user_kernel_debugger(const char* userMessage) 2269 { 2270 if (geteuid() != 0) 2271 return B_NOT_ALLOWED; 2272 2273 char message[512]; 2274 strcpy(message, "USER: "); 2275 size_t length = strlen(message); 2276 2277 if (userMessage == NULL || !IS_USER_ADDRESS(userMessage) || user_strlcpy( 2278 message + length, userMessage, sizeof(message) - length) < 0) { 2279 return B_BAD_ADDRESS; 2280 } 2281 2282 kernel_debugger(message); 2283 return B_OK; 2284 } 2285 2286 2287 void 2288 _user_register_syslog_daemon(port_id port) 2289 { 2290 if (geteuid() != 0 || !sSyslogOutputEnabled || sSyslogNotify < 0) 2291 return; 2292 2293 sSyslogPort = port; 2294 2295 if (sSyslogWriter < 0) { 2296 sSyslogWriter = spawn_kernel_thread(syslog_sender, "syslog sender", 2297 B_LOW_PRIORITY, NULL); 2298 if (sSyslogWriter >= 0) 2299 resume_thread(sSyslogWriter); 2300 } 2301 } 2302 2303 2304 void 2305 _user_debug_output(const char* userString) 2306 { 2307 if (!sSerialDebugEnabled && !sSyslogOutputEnabled) 2308 return; 2309 2310 if (!IS_USER_ADDRESS(userString)) 2311 return; 2312 2313 char string[512]; 2314 int32 length; 2315 int32 toWrite; 2316 do { 2317 length = user_strlcpy(string, userString, sizeof(string)); 2318 if (length <= 0) 2319 break; 2320 toWrite = std::min(length, (int32)sizeof(string) - 1); 2321 debug_puts(string, toWrite); 2322 userString += toWrite; 2323 } while (length > toWrite); 2324 } 2325 2326 2327 void 2328 dump_block(const char* buffer, int size, const char* prefix) 2329 { 2330 const int DUMPED_BLOCK_SIZE = 16; 2331 int i; 2332 2333 for (i = 0; i < size;) { 2334 int start = i; 2335 2336 dprintf("%s%04x ", prefix, i); 2337 for (; i < start + DUMPED_BLOCK_SIZE; i++) { 2338 if (!(i % 4)) 2339 dprintf(" "); 2340 2341 if (i >= size) 2342 dprintf(" "); 2343 else 2344 dprintf("%02x", *(unsigned char*)(buffer + i)); 2345 } 2346 dprintf(" "); 2347 2348 for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) { 2349 if (i < size) { 2350 char c = buffer[i]; 2351 2352 if (c < 30) 2353 dprintf("."); 2354 else 2355 dprintf("%c", c); 2356 } else 2357 break; 2358 } 2359 dprintf("\n"); 2360 } 2361 } 2362