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