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