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