btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / system / kernel / debug / debug.cpp
blob3bd66f44ebb4e4a41b7c6e3ce5384851f7fd4348
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.
6 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
7 * Distributed under the terms of the NewOS License.
8 */
11 /*! This file contains the debugger and debug output facilities */
14 #include "blue_screen.h"
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>
24 #include <algorithm>
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>
44 #include <arch/debug_console.h>
45 #include <arch/debug.h>
46 #include <util/AutoLock.h>
47 #include <util/ring_buffer.h>
49 #include <syslog_daemon.h>
51 #include "debug_builtin_commands.h"
52 #include "debug_commands.h"
53 #include "debug_output_filter.h"
54 #include "debug_variables.h"
57 #if __GNUC__ == 2
58 # define va_copy(to, from) __va_copy(to, from)
59 #endif
62 struct debug_memcpy_parameters {
63 void* to;
64 const void* from;
65 size_t size;
68 struct debug_strlcpy_parameters {
69 char* to;
70 const char* from;
71 size_t size;
72 size_t result;
76 static const char* const kKDLPrompt = "kdebug> ";
77 static const char* const kKDLMessageCommandSeparator = "@!";
78 // separates panic() message from command list to execute
80 extern "C" int kgets(char* buffer, int length);
82 void call_modules_hook(bool enter);
84 static void syslog_write(const char* text, int32 length, bool notify);
86 static arch_debug_registers sDebugRegisters[SMP_MAX_CPUS];
88 static debug_page_fault_info sPageFaultInfo;
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;
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
113 static void* sPreviousSessionSyslogBuffer = NULL;
114 static size_t sPreviousSessionSyslogBufferSize = 0;
116 static const char* sCurrentKernelDebuggerMessagePrefix;
117 static const char* sCurrentKernelDebuggerMessage;
118 static va_list sCurrentKernelDebuggerMessageArgs;
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");
129 static void flush_pending_repeats(bool notifySyslog);
130 static void check_pending_repeats(void* data, int iter);
132 static int64 sMessageRepeatFirstTime = 0;
133 static int64 sMessageRepeatLastTime = 0;
134 static int32 sMessageRepeatCount = 0;
136 static debugger_module_info* sDebuggerModules[8];
137 static const uint32 kMaxDebuggerModules = sizeof(sDebuggerModules)
138 / sizeof(sDebuggerModules[0]);
140 #define LINE_BUFFER_SIZE 1024
141 #define HISTORY_SIZE 16
143 static char sLineBuffer[HISTORY_SIZE][LINE_BUFFER_SIZE] = { "", };
144 static int32 sCurrentLine = 0;
146 static debugger_demangle_module_info* sDemangleModule;
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];
156 #define distance(a, b) ((a) < (b) ? (b) - (a) : (a) - (b))
159 // #pragma mark - DebugOutputFilter
162 DebugOutputFilter::DebugOutputFilter()
167 DebugOutputFilter::~DebugOutputFilter()
172 void
173 DebugOutputFilter::PrintString(const char* string)
178 void
179 DebugOutputFilter::Print(const char* format, va_list args)
184 void
185 DefaultDebugOutputFilter::PrintString(const char* string)
187 size_t length = strlen(string);
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);
196 for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++) {
197 if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
198 sDebuggerModules[i]->debugger_puts(string, length);
203 void
204 DefaultDebugOutputFilter::Print(const char* format, va_list args)
206 vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, format, args);
207 flush_pending_repeats(false);
208 PrintString(sInterruptOutputBuffer);
212 // #pragma mark -
215 DebugOutputFilter*
216 set_debug_output_filter(DebugOutputFilter* filter)
218 DebugOutputFilter* oldFilter = sDebugOutputFilter;
219 sDebugOutputFilter = filter;
220 return oldFilter;
224 static void
225 kputchar(char c)
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));
237 void
238 kputs(const char* s)
240 if (sDebugOutputFilter != NULL)
241 sDebugOutputFilter->PrintString(s);
245 void
246 kputs_unfiltered(const char* s)
248 gDefaultDebugOutputFilter.PrintString(s);
252 static void
253 insert_chars_into_line(char* buffer, int32& position, int32& length,
254 const char* chars, int32 charCount)
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);
262 // insert chars
263 memcpy(buffer + position, chars, charCount);
264 int32 oldPosition = position;
265 position += charCount;
266 length += charCount;
268 // print the new chars (and the following ones)
269 kprintf("%.*s", (int)(length - oldPosition),
270 buffer + oldPosition);
272 // reposition cursor, if necessary
273 if (position < length)
274 kprintf("\x1b[%" B_PRId32 "D", length - position);
278 static void
279 insert_char_into_line(char* buffer, int32& position, int32& length, char c)
281 insert_chars_into_line(buffer, position, length, &c, 1);
285 static void
286 remove_char_from_line(char* buffer, int32& position, int32& length)
288 if (position == length)
289 return;
291 length--;
293 if (position < length) {
294 // move the subsequent chars
295 memmove(buffer + position, buffer + position + 1, length - position);
297 // print the rest of the line again, if necessary
298 for (int32 i = position; i < length; i++)
299 kputchar(buffer[i]);
302 // visually clear the last char
303 kputchar(' ');
305 // reposition the cursor
306 kprintf("\x1b[%" B_PRId32 "D", length - position + 1);
310 class LineEditingHelper {
311 public:
312 virtual ~LineEditingHelper() {}
314 virtual void TabCompletion(char* buffer, int32 capacity, int32& position,
315 int32& length) = 0;
319 class CommandLineEditingHelper : public LineEditingHelper {
320 public:
321 CommandLineEditingHelper()
325 virtual ~CommandLineEditingHelper() {}
327 virtual void TabCompletion(char* buffer, int32 capacity, int32& position,
328 int32& length)
330 // find the first space
331 char tmpChar = buffer[position];
332 buffer[position] = '\0';
333 char* firstSpace = strchr(buffer, ' ');
334 buffer[position] = tmpChar;
336 bool reprintLine = false;
338 if (firstSpace != NULL) {
339 // a complete command -- print its help
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;
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");
358 reprintLine = true;
359 } else {
360 // a partial command -- look for completions
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);
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);
382 for (int32 i = position; i < longestCommonPrefix; i++) {
383 if (previousCommandName[i] != command->name[i]) {
384 longestCommonPrefix = i;
385 break;
390 previousCommandName = command->name;
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);
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;
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
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;
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;
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++;
439 kprintf(" %-*s", (int)longestName, command->name);
441 kputchar('\n');
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);
455 static int
456 read_line(char* buffer, int32 maxLength,
457 LineEditingHelper* editingHelper = NULL)
459 int32 currentHistoryLine = sCurrentLine;
460 int32 position = 0;
461 int32 length = 0;
462 bool done = false;
463 char c = 0;
465 while (!done) {
466 c = kgetc();
468 switch (c) {
469 case '\n':
470 case '\r':
471 buffer[length++] = '\0';
472 kputchar('\n');
473 done = true;
474 break;
475 case '\t':
477 if (editingHelper != NULL) {
478 editingHelper->TabCompletion(buffer, maxLength,
479 position, length);
481 break;
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);
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(' ');
497 // reposition cursor
498 kprintf("\x1b[%" B_PRId32 "D", length - position);
500 length = position;
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.
510 // clear screen
511 blue_screen_clear_screen();
513 // reprint line
514 buffer[length] = '\0';
515 blue_screen_puts(kKDLPrompt);
516 blue_screen_puts(buffer);
518 // reposition cursor
519 if (position < length) {
520 for (int i = length; i > position; i--)
521 blue_screen_puts("\x1b[1D");
524 break;
525 case 27: // escape sequence
526 c = kgetc();
527 if (c != '[') {
528 // ignore broken escape sequence
529 break;
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++;
538 break;
539 case 'D': // left arrow
540 if (position > 0) {
541 kputs("\x1b[1D"); // move to the left one
542 position--;
544 break;
545 case 'A': // up arrow
546 case 'B': // down arrow
548 int32 historyLine = 0;
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;
560 historyLine = currentHistoryLine + 1;
561 if (historyLine >= HISTORY_SIZE)
562 historyLine = 0;
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;
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
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;
584 case '5': // if "5~", it's PAGE UP
585 case '6': // if "6~", it's PAGE DOWN
587 if (kgetc() != '~')
588 break;
590 // PAGE UP: search backward, PAGE DOWN: forward
591 int32 searchDirection = (c == '5' ? -1 : 1);
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;
601 if (strncmp(sLineBuffer[historyLine], buffer,
602 position) == 0) {
603 found = true;
605 } while (!found);
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;
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;
622 break;
624 case 'H': // home
626 if (position > 0) {
627 kprintf("\x1b[%" B_PRId32 "D", position);
628 position = 0;
630 break;
632 case 'F': // end
634 if (position < length) {
635 kprintf("\x1b[%" B_PRId32 "C", length - position);
636 position = length;
638 break;
640 case '3': // if "3~", it's DEL
642 if (kgetc() != '~')
643 break;
645 if (position < length)
646 remove_char_from_line(buffer, position, length);
648 break;
650 default:
651 break;
653 break;
654 case '$':
655 case '+':
656 if (!sBlueScreenOutput) {
657 /* HACK ALERT!!!
659 * If we get a $ at the beginning of the line
660 * we assume we are talking with GDB
662 if (position == 0) {
663 strcpy(buffer, "gdb");
664 position = 4;
665 done = true;
666 break;
669 /* supposed to fall through */
670 default:
671 if (isprint(c))
672 insert_char_into_line(buffer, position, length, c);
673 break;
676 if (length >= maxLength - 2) {
677 buffer[length++] = '\0';
678 kputchar('\n');
679 done = true;
680 break;
684 return length;
688 char
689 kgetc(void)
691 while (true) {
692 // check serial input
693 int c = arch_debug_serial_try_getchar();
694 if (c >= 0)
695 return (char)c;
697 // check blue screen input
698 if (sBlueScreenOutput) {
699 c = blue_screen_try_getchar();
700 if (c >= 0)
701 return (char)c;
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;
713 cpu_pause();
719 kgets(char* buffer, int length)
721 return read_line(buffer, length);
725 static void
726 print_kernel_debugger_message()
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);
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);
758 } else
759 sDebugOutputFilter->Print(sCurrentKernelDebuggerMessage, args);
761 va_end(args);
764 kprintf("\n");
769 static void
770 execute_panic_commands()
772 if (sCurrentKernelDebuggerMessage == NULL
773 || strstr(sCurrentKernelDebuggerMessage,
774 kKDLMessageCommandSeparator) == NULL) {
775 return;
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);
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);
797 va_end(tempArgs);
799 debug_free(commandBuffer);
804 static void
805 stack_trace_trampoline(void*)
807 arch_debug_stack_trace();
811 static void
812 kernel_debugger_loop(const char* messagePrefix, const char* message,
813 va_list args, int32 cpu)
815 DebugAllocPool* allocPool = create_debug_alloc_pool();
817 sCurrentKernelDebuggerMessagePrefix = messagePrefix;
818 sCurrentKernelDebuggerMessage = message;
819 if (sCurrentKernelDebuggerMessage != NULL)
820 va_copy(sCurrentKernelDebuggerMessageArgs, args);
822 sSyslogDebuggerOffset = sSyslogBuffer != NULL
823 ? ring_buffer_readable(sSyslogBuffer) : 0;
825 print_kernel_debugger_message();
827 kprintf("Welcome to Kernel Debugging Land...\n");
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);
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);
846 kprintf("Thread %" B_PRId32 " \"%.64s\" running on CPU %" B_PRId32 "\n",
847 thread->id, thread->name, sDebuggerOnCPU);
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();
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();
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);
885 execute_panic_commands();
887 blue_screen_set_paging(pagingEnabled);
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.
894 for (;;) {
895 CommandLineEditingHelper editingHelper;
896 kprintf(kKDLPrompt);
897 char* line = sLineBuffer[sCurrentLine];
898 read_line(line, LINE_BUFFER_SIZE, &editingHelper);
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;
909 if (whiteSpaceOnly) {
910 if (continuableLine < 0)
911 continue;
913 // the previous command can be repeated
914 sCurrentLine = continuableLine;
915 line = sLineBuffer[sCurrentLine];
918 int rc = evaluate_debug_command(line);
920 if (rc == B_KDEBUG_QUIT) {
921 // okay, exit now.
922 break;
925 // If the command is continuable, remember the current line index.
926 continuableLine = (rc == B_KDEBUG_CONT ? sCurrentLine : -1);
928 int previousLine = sCurrentLine - 1;
929 if (previousLine < 0)
930 previousLine = HISTORY_SIZE - 1;
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;
939 if (sCurrentKernelDebuggerMessage != NULL)
940 va_end(sCurrentKernelDebuggerMessageArgs);
942 delete_debug_alloc_pool(allocPool);
946 static void
947 enter_kernel_debugger(int32 cpu)
949 while (atomic_add(&sInDebugger, 1) > 0) {
950 atomic_add(&sInDebugger, -1);
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;
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);
965 arch_debug_save_registers(&sDebugRegisters[cpu]);
966 sPreviousDprintfState = set_dprintf_enabled(true);
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);
976 if (sBlueScreenOutput) {
977 if (blue_screen_enter(false) == B_OK)
978 sBlueScreenEnabled = true;
981 sDebugOutputFilter = &gDefaultDebugOutputFilter;
983 sDebuggedThread = NULL;
985 // sort the commands
986 sort_debugger_commands();
988 call_modules_hook(true);
992 static void
993 exit_kernel_debugger()
995 call_modules_hook(false);
996 set_dprintf_enabled(sPreviousDprintfState);
998 sDebugOutputFilter = NULL;
1000 sBlueScreenEnabled = false;
1001 if (sDebugScreenEnabled)
1002 blue_screen_enter(true);
1004 atomic_add(&sInDebugger, -1);
1008 static void
1009 hand_over_kernel_debugger()
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);
1022 static void
1023 kernel_debugger_internal(const char* messagePrefix, const char* message,
1024 va_list args, int32 cpu)
1026 while (true) {
1027 if (sHandOverKDLToCPU == cpu) {
1028 sHandOverKDLToCPU = -1;
1029 sHandOverKDL = false;
1030 } else
1031 enter_kernel_debugger(cpu);
1033 // If we're called recursively sDebuggerOnCPU will be != -1.
1034 int32 previousCPU = sDebuggerOnCPU;
1035 sDebuggerOnCPU = cpu;
1037 kernel_debugger_loop(messagePrefix, message, args, cpu);
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();
1045 sDebuggerOnCPU = previousCPU;
1047 if (sHandOverKDLToCPU < 0)
1048 break;
1050 hand_over_kernel_debugger();
1052 debug_trap_cpu_in_kdl(cpu, true);
1054 if (sHandOverKDLToCPU != cpu)
1055 break;
1060 static int
1061 cmd_dump_kdl_message(int argc, char** argv)
1063 print_kernel_debugger_message();
1064 return 0;
1068 static int
1069 cmd_execute_panic_commands(int argc, char** argv)
1071 execute_panic_commands();
1072 return 0;
1076 static int
1077 cmd_dump_syslog(int argc, char** argv)
1079 if (!sSyslogOutputEnabled) {
1080 kprintf("Syslog is not enabled.\n");
1081 return 0;
1084 bool unsentOnly = false;
1085 bool ignoreKDLOutput = true;
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;
1097 if (argi < argc) {
1098 print_debugger_command_usage(argv[0]);
1099 return 0;
1102 size_t debuggerOffset = sSyslogDebuggerOffset;
1103 size_t start = unsentOnly ? sSyslogBufferOffset : 0;
1104 size_t end = ignoreKDLOutput
1105 ? debuggerOffset : ring_buffer_readable(sSyslogBuffer);
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);
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;
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];
1132 if (toPrint > 0) {
1133 newLine = buffer[toPrint - 1] == '\n';
1134 buffer[toPrint] = '\0';
1135 kputs(buffer);
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;
1150 if (!newLine)
1151 kputs("\n");
1153 if (buffer != stackBuffer)
1154 debug_free(buffer);
1156 return 0;
1160 static int
1161 cmd_switch_cpu(int argc, char** argv)
1163 if (argc > 2) {
1164 print_debugger_command_usage(argv[0]);
1165 return 0;
1168 if (argc == 1) {
1169 kprintf("running on CPU %" B_PRId32 "\n", smp_get_current_cpu());
1170 return 0;
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;
1179 if (newCPU == smp_get_current_cpu()) {
1180 kprintf("already running on CPU %" B_PRId32 "\n", newCPU);
1181 return 0;
1184 sHandOverKDLToCPU = newCPU;
1186 return B_KDEBUG_QUIT;
1190 static status_t
1191 syslog_sender(void* data)
1193 bool bufferPending = false;
1194 int32 length = 0;
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.
1209 sSyslogMessage->when = real_time_clock();
1211 if (!bufferPending) {
1212 // We need to have exclusive access to our syslog buffer
1213 cpu_status state = disable_interrupts();
1214 acquire_spinlock(&sSpinlock);
1216 length = ring_buffer_readable(sSyslogBuffer)
1217 - sSyslogBufferOffset;
1218 if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH)
1219 length = SYSLOG_MAX_MESSAGE_LENGTH;
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;
1231 release_spinlock(&sSpinlock);
1232 restore_interrupts(state);
1235 if (length == 0) {
1236 // The buffer we came here for might have been sent already
1237 bufferPending = false;
1238 continue;
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;
1250 if (status != B_OK) {
1251 // Sending has failed - just wait, maybe it'll work later.
1252 bufferPending = true;
1253 continue;
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;
1264 return 0;
1268 static void
1269 syslog_write(const char* text, int32 length, bool notify)
1271 if (sSyslogBuffer == NULL)
1272 return;
1274 if (length > sSyslogBuffer->size) {
1275 text = "<DROP>";
1276 length = 6;
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);
1285 if (toDrop > sSyslogBufferOffset) {
1286 sSyslogBufferOffset = 0;
1287 sSyslogDropped = true;
1288 } else
1289 sSyslogBufferOffset -= toDrop;
1291 sSyslogDebuggerOffset -= std::min(toDrop, sSyslogDebuggerOffset);
1294 ring_buffer_write(sSyslogBuffer, (uint8*)text, length);
1296 if (notify)
1297 release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE);
1301 static status_t
1302 syslog_init_post_threads(void)
1304 if (!sSyslogOutputEnabled)
1305 return B_OK;
1307 sSyslogNotify = create_sem(0, "syslog data");
1308 if (sSyslogNotify >= 0)
1309 return B_OK;
1311 // initializing kernel syslog service failed -- disable it
1313 sSyslogOutputEnabled = false;
1315 if (sSyslogBuffer != NULL) {
1316 if (sDebugSyslog)
1317 delete_area(area_for(sSyslogBuffer));
1318 else
1319 delete_ring_buffer(sSyslogBuffer);
1321 sSyslogBuffer = NULL;
1324 free(sSyslogMessage);
1325 delete_sem(sSyslogNotify);
1327 return B_ERROR;
1331 static status_t
1332 syslog_init_post_vm(struct kernel_args* args)
1334 status_t status;
1335 int32 length = 0;
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;
1344 sSyslogMessage = (syslog_message*)malloc(SYSLOG_MESSAGE_BUFFER_SIZE);
1345 if (sSyslogMessage == NULL) {
1346 status = B_NO_MEMORY;
1347 goto err1;
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;
1364 unload_driver_settings(handle);
1367 sSyslogBuffer = create_ring_buffer(bufferSize);
1369 if (sSyslogBuffer == NULL) {
1370 status = B_NO_MEMORY;
1371 goto err2;
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;
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");
1392 if (args->debug_output != NULL) {
1393 syslog_write((const char*)args->debug_output.Pointer(),
1394 args->debug_size, false);
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);
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);
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);
1421 return B_OK;
1423 err2:
1424 free(sSyslogMessage);
1425 err1:
1426 sSyslogOutputEnabled = false;
1427 sSyslogBuffer = NULL;
1428 return status;
1431 static void
1432 syslog_init_post_modules()
1434 if (sPreviousSessionSyslogBuffer == NULL)
1435 return;
1437 void* buffer = sPreviousSessionSyslogBuffer;
1438 size_t bufferSize = sPreviousSessionSyslogBufferSize;
1439 sPreviousSessionSyslogBuffer = NULL;
1440 sPreviousSessionSyslogBufferSize = 0;
1441 MemoryDeleter bufferDeleter(buffer);
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;
1450 write(fd, buffer, bufferSize);
1451 close(fd);
1454 static status_t
1455 syslog_init(struct kernel_args* args)
1457 if (!args->keep_debug_output_buffer || args->debug_output == NULL)
1458 return B_OK;
1460 sSyslogBuffer = create_ring_buffer_etc(args->debug_output, args->debug_size,
1461 RING_BUFFER_INIT_FROM_BUFFER);
1462 sDebugSyslog = true;
1464 return B_OK;
1468 static void
1469 debug_memcpy_trampoline(void* _parameters)
1471 debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters;
1472 memcpy(parameters->to, parameters->from, parameters->size);
1476 static void
1477 debug_strlcpy_trampoline(void* _parameters)
1479 debug_strlcpy_parameters* parameters
1480 = (debug_strlcpy_parameters*)_parameters;
1481 parameters->result = strlcpy(parameters->to, parameters->from,
1482 parameters->size);
1486 void
1487 call_modules_hook(bool enter)
1489 uint32 index = 0;
1490 while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) {
1491 debugger_module_info* module = sDebuggerModules[index];
1493 if (enter && module->enter_debugger != NULL)
1494 module->enter_debugger();
1495 else if (!enter && module->exit_debugger != NULL)
1496 module->exit_debugger();
1498 index++;
1503 //! Must be called with the sSpinlock held.
1504 static void
1505 debug_output(const char* string, int32 length, bool notifySyslog)
1507 if (length >= OUTPUT_BUFFER_SIZE)
1508 length = OUTPUT_BUFFER_SIZE - 1;
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);
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);
1532 memcpy(sLastOutputBuffer, string, length);
1533 sLastOutputBuffer[length] = 0;
1538 //! Must be called with the sSpinlock held.
1539 static void
1540 flush_pending_repeats(bool notifySyslog)
1542 if (sMessageRepeatCount <= 0)
1543 return;
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);
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);
1563 } else {
1564 // if we only have one repeat just reprint the last buffer
1565 size_t length = strlen(sLastOutputBuffer);
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);
1583 sMessageRepeatFirstTime = 0;
1584 sMessageRepeatCount = 0;
1588 static void
1589 check_pending_repeats(void* /*data*/, int /*iteration*/)
1591 if (sMessageRepeatCount > 0
1592 && (system_time() - sMessageRepeatLastTime > 1000000
1593 || system_time() - sMessageRepeatFirstTime > 3000000)) {
1594 cpu_status state = disable_interrupts();
1595 acquire_spinlock(&sSpinlock);
1597 flush_pending_repeats(true);
1599 release_spinlock(&sSpinlock);
1600 restore_interrupts(state);
1605 static void
1606 dprintf_args(const char* format, va_list args, bool notifySyslog)
1608 if (are_interrupts_enabled()) {
1609 MutexLocker locker(sOutputLock);
1611 int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format,
1612 args);
1613 length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1615 InterruptsSpinLocker _(sSpinlock);
1616 debug_output(sOutputBuffer, length, notifySyslog);
1617 } else {
1618 InterruptsSpinLocker _(sSpinlock);
1620 int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE,
1621 format, args);
1622 length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1624 debug_output(sInterruptOutputBuffer, length, notifySyslog);
1629 // #pragma mark - private kernel API
1632 bool
1633 debug_screen_output_enabled(void)
1635 return sDebugScreenEnabled;
1639 void
1640 debug_stop_screen_debug_output(void)
1642 sDebugScreenEnabled = false;
1646 bool
1647 debug_debugger_running(void)
1649 return sDebuggerOnCPU != -1;
1653 void
1654 debug_puts(const char* string, int32 length)
1656 InterruptsSpinLocker _(sSpinlock);
1657 debug_output(string, length, true);
1661 void
1662 debug_early_boot_message(const char* string)
1664 arch_debug_serial_early_boot_message(string);
1668 void
1669 debug_init(kernel_args* args)
1671 new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter;
1673 syslog_init(args);
1675 debug_paranoia_init();
1676 arch_debug_console_init(args);
1680 void
1681 debug_init_post_vm(kernel_args* args)
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);
1698 debug_builtin_commands_init();
1699 arch_debug_init(args);
1701 debug_heap_init();
1702 debug_variables_init();
1703 frame_buffer_console_init(args);
1704 tracing_init();
1708 void
1709 debug_init_post_settings(struct kernel_args* args)
1711 // get debug settings
1713 sSerialDebugEnabled = get_safemode_boolean("serial_debug_output",
1714 sSerialDebugEnabled);
1715 sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output",
1716 sSyslogOutputEnabled);
1717 sBlueScreenOutput = get_safemode_boolean("bluescreen", true);
1718 sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys",
1719 sEmergencyKeysEnabled);
1720 sDebugScreenEnabled = get_safemode_boolean("debug_screen", false);
1722 if ((sBlueScreenOutput || sDebugScreenEnabled)
1723 && blue_screen_init() != B_OK)
1724 sBlueScreenOutput = sDebugScreenEnabled = false;
1726 if (sDebugScreenEnabled)
1727 blue_screen_enter(true);
1729 arch_debug_console_init_settings(args);
1730 syslog_init_post_vm(args);
1734 void
1735 debug_init_post_modules(struct kernel_args* args)
1737 syslog_init_post_modules();
1739 // check for dupped lines every 10/10 second
1740 register_kernel_daemon(check_pending_repeats, NULL, 10);
1742 syslog_init_post_threads();
1744 // load kernel debugger addons
1746 static const char* kDemanglePrefix = "debugger/demangle/";
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);
1754 if (read_next_module_name(cookie, name, &nameLength) != B_OK)
1755 break;
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;
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);
1770 close_module_list(cookie);
1772 frame_buffer_console_init_post_modules(args);
1776 void
1777 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags)
1779 sPageFaultInfo.fault_address = faultAddress;
1780 sPageFaultInfo.pc = pc;
1781 sPageFaultInfo.flags = flags;
1785 debug_page_fault_info*
1786 debug_get_page_fault_info()
1788 return &sPageFaultInfo;
1792 void
1793 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
1795 InterruptsLocker locker;
1797 // return, if we've been called recursively (we call
1798 // smp_intercpu_int_handler() below)
1799 if (sCPUTrapped[cpu])
1800 return;
1802 arch_debug_save_registers(&sDebugRegisters[cpu]);
1804 sCPUTrapped[cpu] = true;
1806 while (sInDebugger != 0) {
1807 if (sHandOverKDL && sHandOverKDLToCPU == cpu) {
1808 if (returnIfHandedOver)
1809 break;
1811 kernel_debugger_internal(NULL, NULL,
1812 sCurrentKernelDebuggerMessageArgs, cpu);
1813 } else
1814 smp_intercpu_int_handler(cpu);
1817 sCPUTrapped[cpu] = false;
1821 void
1822 debug_double_fault(int32 cpu)
1824 kernel_debugger_internal("Double Fault!", NULL,
1825 sCurrentKernelDebuggerMessageArgs, cpu);
1829 bool
1830 debug_emergency_key_pressed(char key)
1832 if (!sEmergencyKeysEnabled)
1833 return false;
1835 if (key == 'd') {
1836 kernel_debugger("Keyboard Requested Halt.");
1837 return true;
1840 // Broadcast to the kernel debugger modules
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;
1849 return false;
1853 /*! Verifies that the complete given memory range is accessible in the current
1854 context.
1856 Invoked in the kernel debugger only.
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.
1865 bool
1866 debug_is_kernel_memory_accessible(addr_t address, size_t size,
1867 uint32 protection)
1869 addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE);
1870 address = ROUNDDOWN(address, B_PAGE_SIZE);
1872 if (!IS_KERNEL_ADDRESS(address) || endAddress < address)
1873 return false;
1875 for (; address < endAddress; address += B_PAGE_SIZE) {
1876 if (!arch_vm_translation_map_is_kernel_page_accessible(address,
1877 protection)) {
1878 return false;
1882 return true;
1886 /*! Calls a function in a setjmp() + fault handler context.
1887 May only be used in the kernel debugger.
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().
1899 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*),
1900 void* parameter)
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;
1907 int result = setjmp(jumpBuffer);
1908 if (result == 0) {
1909 arch_debug_call_with_fault_handler(cpu, jumpBuffer, function,
1910 parameter);
1913 // restore old fault handler
1914 cpu->fault_handler = oldFaultHandler;
1915 cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer;
1917 return result;
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.
1928 status_t
1929 debug_memcpy(team_id teamID, void* to, const void* from, size_t size)
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;
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};
1941 if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1942 &debug_memcpy_trampoline, &parameters) == 0) {
1943 return B_OK;
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));
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;
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;
1966 from = (const uint8*)from + toCopy;
1967 to = (uint8*)to + toCopy;
1968 size -= toCopy;
1971 return B_OK;
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.
1982 ssize_t
1983 debug_strlcpy(team_id teamID, char* to, const char* from, size_t size)
1985 if (from == NULL || (to == NULL && size > 0))
1986 return B_BAD_ADDRESS;
1988 // limit size to avoid address overflows
1989 size_t maxSize = std::min((addr_t)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.
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};
2000 if (debug_call_with_fault_handler(
2001 gCPU[sDebuggerOnCPU].fault_jump_buffer,
2002 &debug_strlcpy_trampoline, &parameters) == 0) {
2003 // If we hit the address overflow boundary, fail.
2004 if (parameters.result >= maxSize && maxSize < size)
2005 return B_BAD_ADDRESS;
2007 return parameters.result;
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));
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;
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;
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;
2035 from = (const char*)from + toCopy;
2036 totalLength += length;
2037 maxSize -= length;
2039 if (endOfString) {
2040 // only copy the actual string, including the terminating null
2041 toCopy = length + 1;
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;
2054 if (vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
2055 != B_OK) {
2056 return B_BAD_ADDRESS;
2059 to = (char*)to + toCopy;
2060 size -= toCopy;
2063 if (endOfString)
2064 return totalLength;
2067 return totalLength;
2071 // #pragma mark - public API
2074 uint64
2075 parse_expression(const char* expression)
2077 uint64 result;
2078 return evaluate_debug_expression(expression, &result, true) ? result : 0;
2082 void
2083 panic(const char* format, ...)
2085 va_list args;
2086 va_start(args, format);
2088 cpu_status state = disable_interrupts();
2090 kernel_debugger_internal("PANIC: ", format, args,
2091 thread_get_current_thread() ? smp_get_current_cpu() : 0);
2093 restore_interrupts(state);
2095 va_end(args);
2099 void
2100 kernel_debugger(const char* message)
2102 cpu_status state = disable_interrupts();
2104 kernel_debugger_internal(message, NULL, sCurrentKernelDebuggerMessageArgs,
2105 smp_get_current_cpu());
2107 restore_interrupts(state);
2111 bool
2112 set_dprintf_enabled(bool newState)
2114 bool oldState = sSerialDebugEnabled;
2115 sSerialDebugEnabled = newState;
2117 return oldState;
2121 void
2122 dprintf(const char* format, ...)
2124 va_list args;
2126 if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
2127 return;
2129 va_start(args, format);
2130 dprintf_args(format, args, true);
2131 va_end(args);
2135 void
2136 dvprintf(const char* format, va_list args)
2138 if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
2139 return;
2141 dprintf_args(format, args, true);
2145 void
2146 dprintf_no_syslog(const char* format, ...)
2148 va_list args;
2150 if (!sSerialDebugEnabled && !sBlueScreenEnabled)
2151 return;
2153 va_start(args, format);
2154 dprintf_args(format, args, false);
2155 va_end(args);
2159 /*! Similar to dprintf() but thought to be used in the kernel
2160 debugger only (it doesn't lock).
2162 void
2163 kprintf(const char* format, ...)
2165 if (sDebugOutputFilter != NULL) {
2166 va_list args;
2167 va_start(args, format);
2168 sDebugOutputFilter->Print(format, args);
2169 va_end(args);
2174 void
2175 kprintf_unfiltered(const char* format, ...)
2177 va_list args;
2178 va_start(args, format);
2179 gDefaultDebugOutputFilter.Print(format, args);
2180 va_end(args);
2184 const char*
2185 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize,
2186 bool* _isObjectMethod)
2188 if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) {
2189 return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize,
2190 _isObjectMethod);
2193 if (_isObjectMethod != NULL)
2194 *_isObjectMethod = false;
2196 return symbol;
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)
2204 if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) {
2205 return sDemangleModule->get_next_argument(_cookie, symbol, name,
2206 nameSize, _type, _argumentLength);
2209 return B_NOT_SUPPORTED;
2213 struct arch_debug_registers*
2214 debug_get_debug_registers(int32 cpu)
2216 if (cpu < 0 || cpu > smp_get_num_cpus())
2217 return NULL;
2219 return &sDebugRegisters[cpu];
2223 Thread*
2224 debug_set_debugged_thread(Thread* thread)
2226 Thread* previous = sDebuggedThread;
2227 sDebuggedThread = thread;
2228 return previous;
2232 Thread*
2233 debug_get_debugged_thread()
2235 return sDebuggedThread != NULL
2236 ? sDebuggedThread : thread_get_current_thread();
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.
2244 bool
2245 debug_is_debugged_team(team_id teamID)
2247 if (teamID == B_CURRENT_TEAM)
2248 return true;
2250 Thread* thread = debug_get_debugged_thread();
2251 return thread != NULL && thread->team != NULL
2252 && thread->team->id == teamID;
2256 // #pragma mark -
2257 // userland syscalls
2260 status_t
2261 _user_kernel_debugger(const char* userMessage)
2263 if (geteuid() != 0)
2264 return B_NOT_ALLOWED;
2266 char message[512];
2267 strcpy(message, "USER: ");
2268 size_t length = strlen(message);
2270 if (userMessage == NULL || !IS_USER_ADDRESS(userMessage) || user_strlcpy(
2271 message + length, userMessage, sizeof(message) - length) < 0) {
2272 return B_BAD_ADDRESS;
2275 kernel_debugger(message);
2276 return B_OK;
2280 void
2281 _user_register_syslog_daemon(port_id port)
2283 if (geteuid() != 0 || !sSyslogOutputEnabled || sSyslogNotify < 0)
2284 return;
2286 sSyslogPort = port;
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);
2297 void
2298 _user_debug_output(const char* userString)
2300 if (!sSerialDebugEnabled && !sSyslogOutputEnabled)
2301 return;
2303 if (!IS_USER_ADDRESS(userString))
2304 return;
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);
2320 void
2321 dump_block(const char* buffer, int size, const char* prefix)
2323 const int DUMPED_BLOCK_SIZE = 16;
2324 int i;
2326 for (i = 0; i < size;) {
2327 int start = i;
2329 dprintf("%s%04x ", prefix, i);
2330 for (; i < start + DUMPED_BLOCK_SIZE; i++) {
2331 if (!(i % 4))
2332 dprintf(" ");
2334 if (i >= size)
2335 dprintf(" ");
2336 else
2337 dprintf("%02x", *(unsigned char*)(buffer + i));
2339 dprintf(" ");
2341 for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) {
2342 if (i < size) {
2343 char c = buffer[i];
2345 if (c < 30)
2346 dprintf(".");
2347 else
2348 dprintf("%c", c);
2349 } else
2350 break;
2352 dprintf("\n");