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