xref: /haiku/src/system/kernel/debug/debug.cpp (revision 2510baa4685f8f570c607ceedfd73473d69342c4)
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[%" B_PRId32 "D", 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[%" B_PRId32 "D", 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[%" B_PRId32 "D", 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[%" B_PRId32 "D", 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[%" B_PRId32 "D", 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[%" B_PRId32 "D", length - position);
612 							// reposition cursor
613 						currentHistoryLine = historyLine;
614 
615 						break;
616 					}
617 					case 'H': // home
618 					{
619 						if (position > 0) {
620 							kprintf("\x1b[%" B_PRId32 "D", position);
621 							position = 0;
622 						}
623 						break;
624 					}
625 					case 'F': // end
626 					{
627 						if (position < length) {
628 							kprintf("\x1b[%" B_PRId32 "C", 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 %" B_PRId32 "\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 %" B_PRId32 "\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 %" B_PRId32 " \"%.64s\" running on CPU %" B_PRId32 "\n",
840 			thread->id, 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 %" B_PRId32 "\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 %" B_PRId32 "\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)(void *)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.Pointer(),
1406 			args->debug_size, false);
1407 	}
1408 
1409 	char revisionBuffer[64];
1410 	length = snprintf(revisionBuffer, sizeof(revisionBuffer),
1411 		"Welcome to syslog debug output!\nHaiku revision: %s\n",
1412 		get_haiku_revision());
1413 	syslog_write(revisionBuffer,
1414 		std::min(length, (int32)sizeof(revisionBuffer) - 1), false);
1415 
1416 	add_debugger_command_etc("syslog", &cmd_dump_syslog,
1417 		"Dumps the syslog buffer.",
1418 		"[ \"-n\" ] [ \"-k\" ]\n"
1419 		"Dumps the whole syslog buffer, or, if -k is specified, only "
1420 		"the part that hasn't been sent yet.\n", 0);
1421 
1422 	return B_OK;
1423 
1424 err2:
1425 	free(sSyslogMessage);
1426 err1:
1427 	sSyslogOutputEnabled = false;
1428 	sSyslogBuffer = NULL;
1429 	return status;
1430 }
1431 
1432 
1433 static status_t
1434 syslog_init(struct kernel_args* args)
1435 {
1436 	if (!args->keep_debug_output_buffer || args->debug_output == NULL)
1437 		return B_OK;
1438 
1439 	sSyslogBuffer = create_ring_buffer_etc(args->debug_output, args->debug_size,
1440 		RING_BUFFER_INIT_FROM_BUFFER);
1441 	sDebugSyslog = true;
1442 
1443 	return B_OK;
1444 }
1445 
1446 
1447 static void
1448 debug_memcpy_trampoline(void* _parameters)
1449 {
1450 	debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters;
1451 	memcpy(parameters->to, parameters->from, parameters->size);
1452 }
1453 
1454 
1455 static void
1456 debug_strlcpy_trampoline(void* _parameters)
1457 {
1458 	debug_strlcpy_parameters* parameters
1459 		= (debug_strlcpy_parameters*)_parameters;
1460 	parameters->result = strlcpy(parameters->to, parameters->from,
1461 		parameters->size);
1462 }
1463 
1464 
1465 void
1466 call_modules_hook(bool enter)
1467 {
1468 	uint32 index = 0;
1469 	while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) {
1470 		debugger_module_info* module = sDebuggerModules[index];
1471 
1472 		if (enter && module->enter_debugger != NULL)
1473 			module->enter_debugger();
1474 		else if (!enter && module->exit_debugger != NULL)
1475 			module->exit_debugger();
1476 
1477 		index++;
1478 	}
1479 }
1480 
1481 
1482 //!	Must be called with the sSpinlock held.
1483 static void
1484 debug_output(const char* string, int32 length, bool notifySyslog)
1485 {
1486 	if (length >= OUTPUT_BUFFER_SIZE)
1487 		length = OUTPUT_BUFFER_SIZE - 1;
1488 
1489 	if (length > 1 && string[length - 1] == '\n'
1490 		&& strncmp(string, sLastOutputBuffer, length) == 0) {
1491 		sMessageRepeatCount++;
1492 		sMessageRepeatLastTime = system_time();
1493 		if (sMessageRepeatFirstTime == 0)
1494 			sMessageRepeatFirstTime = sMessageRepeatLastTime;
1495 	} else {
1496 		flush_pending_repeats(notifySyslog);
1497 
1498 		if (sSerialDebugEnabled)
1499 			arch_debug_serial_puts(string);
1500 		if (sSyslogOutputEnabled)
1501 			syslog_write(string, length, notifySyslog);
1502 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1503 			blue_screen_puts(string);
1504 		if (sSerialDebugEnabled) {
1505 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1506 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1507 					sDebuggerModules[i]->debugger_puts(string, length);
1508 			}
1509 		}
1510 
1511 		memcpy(sLastOutputBuffer, string, length);
1512 		sLastOutputBuffer[length] = 0;
1513 	}
1514 }
1515 
1516 
1517 //!	Must be called with the sSpinlock held.
1518 static void
1519 flush_pending_repeats(bool notifySyslog)
1520 {
1521 	if (sMessageRepeatCount <= 0)
1522 		return;
1523 
1524 	if (sMessageRepeatCount > 1) {
1525 		static char temp[40];
1526 		size_t length = snprintf(temp, sizeof(temp),
1527 			"Last message repeated %" B_PRId32 " times.\n", sMessageRepeatCount);
1528 		length = std::min(length, sizeof(temp) - 1);
1529 
1530 		if (sSerialDebugEnabled)
1531 			arch_debug_serial_puts(temp);
1532 		if (sSyslogOutputEnabled)
1533 			syslog_write(temp, length, notifySyslog);
1534 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1535 			blue_screen_puts(temp);
1536 		if (sSerialDebugEnabled) {
1537 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1538 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1539 					sDebuggerModules[i]->debugger_puts(temp, length);
1540 			}
1541 		}
1542 	} else {
1543 		// if we only have one repeat just reprint the last buffer
1544 		size_t length = strlen(sLastOutputBuffer);
1545 
1546 		if (sSerialDebugEnabled)
1547 			arch_debug_serial_puts(sLastOutputBuffer);
1548 		if (sSyslogOutputEnabled)
1549 			syslog_write(sLastOutputBuffer, length, notifySyslog);
1550 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1551 			blue_screen_puts(sLastOutputBuffer);
1552 		if (sSerialDebugEnabled) {
1553 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1554 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) {
1555 					sDebuggerModules[i]->debugger_puts(sLastOutputBuffer,
1556 						length);
1557 				}
1558 			}
1559 		}
1560 	}
1561 
1562 	sMessageRepeatFirstTime = 0;
1563 	sMessageRepeatCount = 0;
1564 }
1565 
1566 
1567 static void
1568 check_pending_repeats(void* /*data*/, int /*iteration*/)
1569 {
1570 	if (sMessageRepeatCount > 0
1571 		&& (system_time() - sMessageRepeatLastTime > 1000000
1572 			|| system_time() - sMessageRepeatFirstTime > 3000000)) {
1573 		cpu_status state = disable_interrupts();
1574 		acquire_spinlock(&sSpinlock);
1575 
1576 		flush_pending_repeats(true);
1577 
1578 		release_spinlock(&sSpinlock);
1579 		restore_interrupts(state);
1580 	}
1581 }
1582 
1583 
1584 static void
1585 dprintf_args(const char* format, va_list args, bool notifySyslog)
1586 {
1587 	if (are_interrupts_enabled()) {
1588 		MutexLocker locker(sOutputLock);
1589 
1590 		int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format,
1591 			args);
1592 		length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1593 
1594 		InterruptsSpinLocker _(sSpinlock);
1595 		debug_output(sOutputBuffer, length, notifySyslog);
1596 	} else {
1597 		InterruptsSpinLocker _(sSpinlock);
1598 
1599 		int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE,
1600 			format, args);
1601 		length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1602 
1603 		debug_output(sInterruptOutputBuffer, length, notifySyslog);
1604 	}
1605 }
1606 
1607 
1608 // #pragma mark - private kernel API
1609 
1610 
1611 bool
1612 debug_screen_output_enabled(void)
1613 {
1614 	return sDebugScreenEnabled;
1615 }
1616 
1617 
1618 void
1619 debug_stop_screen_debug_output(void)
1620 {
1621 	sDebugScreenEnabled = false;
1622 }
1623 
1624 
1625 bool
1626 debug_debugger_running(void)
1627 {
1628 	return sDebuggerOnCPU != -1;
1629 }
1630 
1631 
1632 void
1633 debug_puts(const char* string, int32 length)
1634 {
1635 	InterruptsSpinLocker _(sSpinlock);
1636 	debug_output(string, length, true);
1637 }
1638 
1639 
1640 void
1641 debug_early_boot_message(const char* string)
1642 {
1643 	arch_debug_serial_early_boot_message(string);
1644 }
1645 
1646 
1647 void
1648 debug_init(kernel_args* args)
1649 {
1650 	new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter;
1651 
1652 	syslog_init(args);
1653 
1654 	debug_paranoia_init();
1655 	arch_debug_console_init(args);
1656 }
1657 
1658 
1659 void
1660 debug_init_post_vm(kernel_args* args)
1661 {
1662 	add_debugger_command_etc("cpu", &cmd_switch_cpu,
1663 		"Switches to another CPU.",
1664 		"<cpu>\n"
1665 		"Switches to CPU with the index <cpu>.\n", 0);
1666 	add_debugger_command_etc("message", &cmd_dump_kdl_message,
1667 		"Reprint the message printed when entering KDL",
1668 		"\n"
1669 		"Reprints the message printed when entering KDL.\n", 0);
1670 	add_debugger_command_etc("panic_commands", &cmd_execute_panic_commands,
1671 		"Execute commands associated with the panic() that caused "
1672 			"entering KDL",
1673 		"\n"
1674 		"Executes the commands associated with the panic() that caused "
1675 			"entering KDL.\n", 0);
1676 
1677 	debug_builtin_commands_init();
1678 	arch_debug_init(args);
1679 
1680 	debug_heap_init();
1681 	debug_variables_init();
1682 	frame_buffer_console_init(args);
1683 	arch_debug_console_init_settings(args);
1684 	tracing_init();
1685 }
1686 
1687 
1688 void
1689 debug_init_post_settings(struct kernel_args* args)
1690 {
1691 	// get debug settings
1692 
1693 	sSerialDebugEnabled = get_safemode_boolean("serial_debug_output",
1694 		sSerialDebugEnabled);
1695 	sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output",
1696 		sSyslogOutputEnabled);
1697 	sBlueScreenOutput = get_safemode_boolean("bluescreen", true);
1698 	sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys",
1699 		sEmergencyKeysEnabled);
1700 	sDebugScreenEnabled = get_safemode_boolean("debug_screen", false);
1701 
1702 	if ((sBlueScreenOutput || sDebugScreenEnabled)
1703 		&& blue_screen_init() != B_OK)
1704 		sBlueScreenOutput = sDebugScreenEnabled = false;
1705 
1706 	if (sDebugScreenEnabled)
1707 		blue_screen_enter(true);
1708 
1709 	syslog_init_post_vm(args);
1710 }
1711 
1712 
1713 void
1714 debug_init_post_modules(struct kernel_args* args)
1715 {
1716 	void* cookie;
1717 
1718 	// check for dupped lines every 10/10 second
1719 	register_kernel_daemon(check_pending_repeats, NULL, 10);
1720 
1721 	syslog_init_post_threads();
1722 
1723 	// load kernel debugger addons
1724 
1725 	static const char* kDemanglePrefix = "debugger/demangle/";
1726 
1727 	cookie = open_module_list("debugger");
1728 	uint32 count = 0;
1729 	while (count < kMaxDebuggerModules) {
1730 		char name[B_FILE_NAME_LENGTH];
1731 		size_t nameLength = sizeof(name);
1732 
1733 		if (read_next_module_name(cookie, name, &nameLength) != B_OK)
1734 			break;
1735 
1736 		// get demangle module, if any
1737 		if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) {
1738 			if (sDemangleModule == NULL)
1739 				get_module(name, (module_info**)&sDemangleModule);
1740 			continue;
1741 		}
1742 
1743 		if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) {
1744 			dprintf("kernel debugger extension \"%s\": loaded\n", name);
1745 			count++;
1746 		} else
1747 			dprintf("kernel debugger extension \"%s\": failed to load\n", name);
1748 	}
1749 	close_module_list(cookie);
1750 
1751 	frame_buffer_console_init_post_modules(args);
1752 }
1753 
1754 
1755 void
1756 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags)
1757 {
1758 	sPageFaultInfo.fault_address = faultAddress;
1759 	sPageFaultInfo.pc = pc;
1760 	sPageFaultInfo.flags = flags;
1761 }
1762 
1763 
1764 debug_page_fault_info*
1765 debug_get_page_fault_info()
1766 {
1767 	return &sPageFaultInfo;
1768 }
1769 
1770 
1771 void
1772 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
1773 {
1774 	InterruptsLocker locker;
1775 
1776 	// return, if we've been called recursively (we call
1777 	// smp_intercpu_int_handler() below)
1778 	if (sCPUTrapped[cpu])
1779 		return;
1780 
1781 	arch_debug_save_registers(&sDebugRegisters[cpu]);
1782 
1783 	sCPUTrapped[cpu] = true;
1784 
1785 	while (sInDebugger != 0) {
1786 		if (sHandOverKDL && sHandOverKDLToCPU == cpu) {
1787 			if (returnIfHandedOver)
1788 				break;
1789 
1790 			kernel_debugger_internal(NULL, NULL,
1791 				sCurrentKernelDebuggerMessageArgs, cpu);
1792 		} else
1793 			smp_intercpu_int_handler(cpu);
1794 	}
1795 
1796 	sCPUTrapped[cpu] = false;
1797 }
1798 
1799 
1800 void
1801 debug_double_fault(int32 cpu)
1802 {
1803 	kernel_debugger_internal("Double Fault!", NULL,
1804 		sCurrentKernelDebuggerMessageArgs, cpu);
1805 }
1806 
1807 
1808 bool
1809 debug_emergency_key_pressed(char key)
1810 {
1811 	if (!sEmergencyKeysEnabled)
1812 		return false;
1813 
1814 	if (key == 'd') {
1815 		kernel_debugger("Keyboard Requested Halt.");
1816 		return true;
1817 	}
1818 
1819 	// Broadcast to the kernel debugger modules
1820 
1821 	for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1822 		if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) {
1823 			if (sDebuggerModules[i]->emergency_key_pressed(key))
1824 				return true;
1825 		}
1826 	}
1827 
1828 	return false;
1829 }
1830 
1831 
1832 /*!	Verifies that the complete given memory range is accessible in the current
1833 	context.
1834 
1835 	Invoked in the kernel debugger only.
1836 
1837 	\param address The start address of the memory range to be checked.
1838 	\param size The size of the memory range to be checked.
1839 	\param protection The area protection for which to check. Valid is a bitwise
1840 		or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA.
1841 	\return \c true, if the complete memory range can be accessed in all ways
1842 		specified by \a protection, \c false otherwise.
1843 */
1844 bool
1845 debug_is_kernel_memory_accessible(addr_t address, size_t size,
1846 	uint32 protection)
1847 {
1848 	addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE);
1849 	address = ROUNDDOWN(address, B_PAGE_SIZE);
1850 
1851 	if (!IS_KERNEL_ADDRESS(address) || endAddress < address)
1852 		return false;
1853 
1854 	for (; address < endAddress; address += B_PAGE_SIZE) {
1855 		if (!arch_vm_translation_map_is_kernel_page_accessible(address,
1856 				protection)) {
1857 			return false;
1858 		}
1859 	}
1860 
1861 	return true;
1862 }
1863 
1864 
1865 /*!	Calls a function in a setjmp() + fault handler context.
1866 	May only be used in the kernel debugger.
1867 
1868 	\param jumpBuffer Buffer to be used for setjmp()/longjmp().
1869 	\param function The function to be called.
1870 	\param parameter The parameter to be passed to the function to be called.
1871 	\return
1872 		- \c 0, when the function executed without causing a page fault or
1873 		  calling longjmp().
1874 		- \c 1, when the function caused a page fault.
1875 		- Any other value the function passes to longjmp().
1876 */
1877 int
1878 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*),
1879 	void* parameter)
1880 {
1881 	// save current fault handler
1882 	cpu_ent* cpu = gCPU + sDebuggerOnCPU;
1883 	addr_t oldFaultHandler = cpu->fault_handler;
1884 	addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer;
1885 
1886 	int result = setjmp(jumpBuffer);
1887 	if (result == 0) {
1888 		arch_debug_call_with_fault_handler(cpu, jumpBuffer, function,
1889 			parameter);
1890 	}
1891 
1892 	// restore old fault handler
1893 	cpu->fault_handler = oldFaultHandler;
1894 	cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer;
1895 
1896 	return result;
1897 }
1898 
1899 
1900 /*!	Similar to user_memcpy(), but can only be invoked from within the kernel
1901 	debugger (and must not be used outside).
1902 	The supplied \a teamID specifies the address space in which to interpret
1903 	the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(),
1904 	or any valid team ID. If the addresses are both kernel addresses, the
1905 	argument is ignored and the current address space is used.
1906 */
1907 status_t
1908 debug_memcpy(team_id teamID, void* to, const void* from, size_t size)
1909 {
1910 	// don't allow address overflows
1911 	if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to)
1912 		return B_BAD_ADDRESS;
1913 
1914 	// Try standard memcpy() with fault handler, if the addresses can be
1915 	// interpreted in the current address space.
1916 	if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to))
1917 			|| debug_is_debugged_team(teamID)) {
1918 		debug_memcpy_parameters parameters = {to, from, size};
1919 
1920 		if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1921 				&debug_memcpy_trampoline, &parameters) == 0) {
1922 			return B_OK;
1923 		}
1924 	}
1925 
1926 	// Try harder. The pages of the respective memory could be unmapped but
1927 	// still exist in a cache (the page daemon does that with inactive pages).
1928 	while (size > 0) {
1929 		uint8 buffer[32];
1930 		size_t toCopy = std::min(size, sizeof(buffer));
1931 
1932 		// restrict the size so we don't cross page boundaries
1933 		if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy)
1934 			toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE;
1935 		if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy)
1936 			toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE;
1937 
1938 		if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy,
1939 				false) != B_OK
1940 			|| vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
1941 				!= B_OK) {
1942 			return B_BAD_ADDRESS;
1943 		}
1944 
1945 		from = (const uint8*)from + toCopy;
1946 		to = (uint8*)to + toCopy;
1947 		size -= toCopy;
1948 	}
1949 
1950 	return B_OK;
1951 }
1952 
1953 
1954 /*!	Similar to user_strlcpy(), but can only be invoked from within the kernel
1955 	debugger (and must not be used outside).
1956 	The supplied \a teamID specifies the address space in which to interpret
1957 	the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(),
1958 	or any valid team ID. If the addresses are both kernel addresses, the
1959 	argument is ignored and the current address space is used.
1960 */
1961 ssize_t
1962 debug_strlcpy(team_id teamID, char* to, const char* from, size_t size)
1963 {
1964 	if (from == NULL || (to == NULL && size > 0))
1965 		return B_BAD_ADDRESS;
1966 
1967 	// limit size to avoid address overflows
1968 	size_t maxSize = std::min(size,
1969 		~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1);
1970 		// NOTE: Since strlcpy() determines the length of \a from, the source
1971 		// address might still overflow.
1972 
1973 	// Try standard strlcpy() with fault handler, if the addresses can be
1974 	// interpreted in the current address space.
1975 	if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to))
1976 			|| debug_is_debugged_team(teamID)) {
1977 		debug_strlcpy_parameters parameters = {to, from, maxSize};
1978 
1979 		if (debug_call_with_fault_handler(
1980 				gCPU[sDebuggerOnCPU].fault_jump_buffer,
1981 				&debug_strlcpy_trampoline, &parameters) == 0) {
1982 			// If we hit the address overflow boundary, fail.
1983 			if (parameters.result >= maxSize && maxSize < size)
1984 				return B_BAD_ADDRESS;
1985 
1986 			return parameters.result;
1987 		}
1988 	}
1989 
1990 	// Try harder. The pages of the respective memory could be unmapped but
1991 	// still exist in a cache (the page daemon does that with inactive pages).
1992 	size_t totalLength = 0;
1993 	while (maxSize > 0) {
1994 		char buffer[32];
1995 		size_t toCopy = std::min(maxSize, sizeof(buffer));
1996 
1997 		// restrict the size so we don't cross page boundaries
1998 		if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy)
1999 			toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE;
2000 		if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy)
2001 			toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE;
2002 
2003 		// copy the next part of the string from the source
2004 		if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy,
2005 				false) != B_OK) {
2006 			return B_BAD_ADDRESS;
2007 		}
2008 
2009 		// determine the length of the part and whether we've reached the end
2010 		// of the string
2011 		size_t length = strnlen(buffer, toCopy);
2012 		bool endOfString = length < toCopy;
2013 
2014 		from = (const char*)from + toCopy;
2015 		totalLength += length;
2016 		maxSize -= length;
2017 
2018 		if (endOfString) {
2019 			// only copy the actual string, including the terminating null
2020 			toCopy = length + 1;
2021 		}
2022 
2023 		if (size > 0) {
2024 			// We still have space left in the target buffer.
2025 			if (size <= length) {
2026 				// Not enough space for the complete part. Null-terminate it and
2027 				// copy what we can.
2028 				buffer[size - 1] = '\0';
2029 				totalLength += length - size;
2030 				toCopy = size;
2031 			}
2032 
2033 			if (vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
2034 					!= B_OK) {
2035 				return B_BAD_ADDRESS;
2036 			}
2037 
2038 			to = (char*)to + toCopy;
2039 			size -= toCopy;
2040 		}
2041 
2042 		if (endOfString)
2043 			return totalLength;
2044 	}
2045 
2046 	return totalLength;
2047 }
2048 
2049 
2050 // #pragma mark - public API
2051 
2052 
2053 uint64
2054 parse_expression(const char* expression)
2055 {
2056 	uint64 result;
2057 	return evaluate_debug_expression(expression, &result, true) ? result : 0;
2058 }
2059 
2060 
2061 void
2062 panic(const char* format, ...)
2063 {
2064 	va_list args;
2065 	va_start(args, format);
2066 
2067 	cpu_status state = disable_interrupts();
2068 
2069 	kernel_debugger_internal("PANIC: ", format, args,
2070 		thread_get_current_thread() ? smp_get_current_cpu() : 0);
2071 
2072 	restore_interrupts(state);
2073 
2074 	va_end(args);
2075 }
2076 
2077 
2078 void
2079 kernel_debugger(const char* message)
2080 {
2081 	cpu_status state = disable_interrupts();
2082 
2083 	kernel_debugger_internal(message, NULL, sCurrentKernelDebuggerMessageArgs,
2084 		smp_get_current_cpu());
2085 
2086 	restore_interrupts(state);
2087 }
2088 
2089 
2090 bool
2091 set_dprintf_enabled(bool newState)
2092 {
2093 	bool oldState = sSerialDebugEnabled;
2094 	sSerialDebugEnabled = newState;
2095 
2096 	return oldState;
2097 }
2098 
2099 
2100 void
2101 dprintf(const char* format, ...)
2102 {
2103 	va_list args;
2104 
2105 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
2106 		return;
2107 
2108 	va_start(args, format);
2109 	dprintf_args(format, args, true);
2110 	va_end(args);
2111 }
2112 
2113 
2114 void
2115 dprintf_no_syslog(const char* format, ...)
2116 {
2117 	va_list args;
2118 
2119 	if (!sSerialDebugEnabled && !sBlueScreenEnabled)
2120 		return;
2121 
2122 	va_start(args, format);
2123 	dprintf_args(format, args, false);
2124 	va_end(args);
2125 }
2126 
2127 
2128 /*!	Similar to dprintf() but thought to be used in the kernel
2129 	debugger only (it doesn't lock).
2130 */
2131 void
2132 kprintf(const char* format, ...)
2133 {
2134 	if (sDebugOutputFilter != NULL) {
2135 		va_list args;
2136 		va_start(args, format);
2137 		sDebugOutputFilter->Print(format, args);
2138 		va_end(args);
2139 	}
2140 }
2141 
2142 
2143 void
2144 kprintf_unfiltered(const char* format, ...)
2145 {
2146 	va_list args;
2147 	va_start(args, format);
2148 	gDefaultDebugOutputFilter.Print(format, args);
2149 	va_end(args);
2150 }
2151 
2152 
2153 const char*
2154 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize,
2155 	bool* _isObjectMethod)
2156 {
2157 	if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) {
2158 		return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize,
2159 			_isObjectMethod);
2160 	}
2161 
2162 	if (_isObjectMethod != NULL)
2163 		*_isObjectMethod = false;
2164 
2165 	return symbol;
2166 }
2167 
2168 
2169 status_t
2170 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol,
2171 	char* name, size_t nameSize, int32* _type, size_t* _argumentLength)
2172 {
2173 	if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) {
2174 		return sDemangleModule->get_next_argument(_cookie, symbol, name,
2175 			nameSize, _type, _argumentLength);
2176 	}
2177 
2178 	return B_NOT_SUPPORTED;
2179 }
2180 
2181 
2182 struct arch_debug_registers*
2183 debug_get_debug_registers(int32 cpu)
2184 {
2185 	if (cpu < 0 || cpu > smp_get_num_cpus())
2186 		return NULL;
2187 
2188 	return &sDebugRegisters[cpu];
2189 }
2190 
2191 
2192 Thread*
2193 debug_set_debugged_thread(Thread* thread)
2194 {
2195 	Thread* previous = sDebuggedThread;
2196 	sDebuggedThread = thread;
2197 	return previous;
2198 }
2199 
2200 
2201 Thread*
2202 debug_get_debugged_thread()
2203 {
2204 	return sDebuggedThread != NULL
2205 		? sDebuggedThread : thread_get_current_thread();
2206 }
2207 
2208 
2209 /*!	Returns whether the supplied team ID refers to the same team the currently
2210 	debugged thread (debug_get_debugged_thread()) belongs to.
2211 	Always returns \c true, if \c B_CURRENT_TEAM is given.
2212 */
2213 bool
2214 debug_is_debugged_team(team_id teamID)
2215 {
2216 	if (teamID == B_CURRENT_TEAM)
2217 		return true;
2218 
2219 	Thread* thread = debug_get_debugged_thread();
2220 	return thread != NULL && thread->team != NULL
2221 		&& thread->team->id == teamID;
2222 }
2223 
2224 
2225 //	#pragma mark -
2226 //	userland syscalls
2227 
2228 
2229 status_t
2230 _user_kernel_debugger(const char *userMessage)
2231 {
2232 	if (geteuid() != 0)
2233 		return B_NOT_ALLOWED;
2234 
2235 	char message[512];
2236 	strcpy(message, "USER: ");
2237 	size_t len = strlen(message);
2238 
2239 	if (userMessage == NULL || !IS_USER_ADDRESS(userMessage)
2240 		|| 	user_strlcpy(message + len, userMessage, sizeof(message) - len)
2241 			< 0) {
2242 		return B_BAD_ADDRESS;
2243 	}
2244 
2245 	kernel_debugger(message);
2246 	return B_OK;
2247 }
2248 
2249 
2250 void
2251 _user_debug_output(const char* userString)
2252 {
2253 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled)
2254 		return;
2255 
2256 	if (!IS_USER_ADDRESS(userString))
2257 		return;
2258 
2259 	char string[512];
2260 	int32 length;
2261 	do {
2262 		length = user_strlcpy(string, userString, sizeof(string));
2263 		if (length <= 0)
2264 			break;
2265 		debug_puts(string, length);
2266 		userString += sizeof(string) - 1;
2267 	} while (length >= (ssize_t)sizeof(string));
2268 }
2269 
2270 
2271 void
2272 dump_block(const char* buffer, int size, const char* prefix)
2273 {
2274 	const int DUMPED_BLOCK_SIZE = 16;
2275 	int i;
2276 
2277 	for (i = 0; i < size;) {
2278 		int start = i;
2279 
2280 		dprintf("%s%04x ", prefix, i);
2281 		for (; i < start + DUMPED_BLOCK_SIZE; i++) {
2282 			if (!(i % 4))
2283 				dprintf(" ");
2284 
2285 			if (i >= size)
2286 				dprintf("  ");
2287 			else
2288 				dprintf("%02x", *(unsigned char*)(buffer + i));
2289 		}
2290 		dprintf("  ");
2291 
2292 		for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) {
2293 			if (i < size) {
2294 				char c = buffer[i];
2295 
2296 				if (c < 30)
2297 					dprintf(".");
2298 				else
2299 					dprintf("%c", c);
2300 			} else
2301 				break;
2302 		}
2303 		dprintf("\n");
2304 	}
2305 }
2306