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