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