xref: /haiku/src/system/kernel/debug/debug.cpp (revision 830f67ef991407f287dbc1238aa5f5906d90c991)
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, int32& previousCPU)
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 	previousCPU = sDebuggerOnCPU;
974 	sDebuggerOnCPU = cpu;
975 
976 	if (sBlueScreenOutput) {
977 		if (blue_screen_enter(false) == B_OK)
978 			sBlueScreenEnabled = true;
979 	}
980 
981 	sDebugOutputFilter = &gDefaultDebugOutputFilter;
982 
983 	sDebuggedThread = NULL;
984 
985 	// sort the commands
986 	sort_debugger_commands();
987 
988 	call_modules_hook(true);
989 }
990 
991 
992 static void
993 exit_kernel_debugger()
994 {
995 	call_modules_hook(false);
996 	set_dprintf_enabled(sPreviousDprintfState);
997 
998 	sDebugOutputFilter = NULL;
999 
1000 	sBlueScreenEnabled = false;
1001 	if (sDebugScreenEnabled)
1002 		blue_screen_enter(true);
1003 
1004 	atomic_add(&sInDebugger, -1);
1005 }
1006 
1007 
1008 static void
1009 hand_over_kernel_debugger()
1010 {
1011 	// Wait until the hand-over is complete.
1012 	// The other CPU gets our sInDebugger reference and will release it when
1013 	// done. Note, that there's a small race condition: the other CPU could
1014 	// hand over to another CPU without us noticing. Since this is only
1015 	// initiated by the user, it is harmless, though.
1016 	sHandOverKDL = true;
1017 	while (atomic_get(&sHandOverKDLToCPU) >= 0)
1018 		cpu_wait(&sHandOverKDLToCPU, -1);
1019 }
1020 
1021 
1022 static void
1023 kernel_debugger_internal(const char* messagePrefix, const char* message,
1024 	va_list args, int32 cpu)
1025 {
1026 	while (true) {
1027 		// If we're called recursively sDebuggerOnCPU will be != -1.
1028 		int32 previousCPU = -1;
1029 
1030 		if (sHandOverKDLToCPU == cpu) {
1031 			sHandOverKDLToCPU = -1;
1032 			sHandOverKDL = false;
1033 
1034 			previousCPU = sDebuggerOnCPU;
1035 			sDebuggerOnCPU = cpu;
1036 		} else
1037 			enter_kernel_debugger(cpu, previousCPU);
1038 
1039 		kernel_debugger_loop(messagePrefix, message, args, cpu);
1040 
1041 		if (sHandOverKDLToCPU < 0 && previousCPU == -1) {
1042 			// We're not handing over to a different CPU and we weren't
1043 			// called recursively, so we'll exit the debugger.
1044 			exit_kernel_debugger();
1045 		}
1046 
1047 		sDebuggerOnCPU = previousCPU;
1048 
1049 		if (sHandOverKDLToCPU < 0)
1050 			break;
1051 
1052 		hand_over_kernel_debugger();
1053 
1054 		debug_trap_cpu_in_kdl(cpu, true);
1055 
1056 		if (sHandOverKDLToCPU != cpu)
1057 			break;
1058 	}
1059 }
1060 
1061 
1062 static int
1063 cmd_dump_kdl_message(int argc, char** argv)
1064 {
1065 	print_kernel_debugger_message();
1066 	return 0;
1067 }
1068 
1069 
1070 static int
1071 cmd_execute_panic_commands(int argc, char** argv)
1072 {
1073 	execute_panic_commands();
1074 	return 0;
1075 }
1076 
1077 
1078 static int
1079 cmd_dump_syslog(int argc, char** argv)
1080 {
1081 	if (!sSyslogOutputEnabled) {
1082 		kprintf("Syslog is not enabled.\n");
1083 		return 0;
1084 	}
1085 
1086 	bool unsentOnly = false;
1087 	bool ignoreKDLOutput = true;
1088 
1089 	int argi = 1;
1090 	for (; argi < argc; argi++) {
1091 		if (strcmp(argv[argi], "-n") == 0)
1092 			unsentOnly = true;
1093 		else if (strcmp(argv[argi], "-k") == 0)
1094 			ignoreKDLOutput = false;
1095 		else
1096 			break;
1097 	}
1098 
1099 	if (argi < argc) {
1100 		print_debugger_command_usage(argv[0]);
1101 		return 0;
1102 	}
1103 
1104 	size_t debuggerOffset = sSyslogDebuggerOffset;
1105 	size_t start = unsentOnly ? sSyslogBufferOffset : 0;
1106 	size_t end = ignoreKDLOutput
1107 		? debuggerOffset : ring_buffer_readable(sSyslogBuffer);
1108 
1109 	// allocate a buffer for processing the syslog output
1110 	size_t bufferSize = 1024;
1111 	char* buffer = (char*)debug_malloc(bufferSize);
1112 	char stackBuffer[64];
1113 	if (buffer == NULL) {
1114 		buffer = stackBuffer;
1115 		bufferSize = sizeof(stackBuffer);
1116 	}
1117 
1118 	// filter the output
1119 	bool newLine = false;
1120 	while (start < end) {
1121 		size_t bytesRead = ring_buffer_peek(sSyslogBuffer, start, buffer,
1122 			std::min(end - start, bufferSize - 1));
1123 		if (bytesRead == 0)
1124 			break;
1125 		start += bytesRead;
1126 
1127 		// remove '\0' and 0xcc
1128 		size_t toPrint = 0;
1129 		for (size_t i = 0; i < bytesRead; i++) {
1130 			if (buffer[i] != '\0' && (uint8)buffer[i] != 0xcc)
1131 				buffer[toPrint++] = buffer[i];
1132 		}
1133 
1134 		if (toPrint > 0) {
1135 			newLine = buffer[toPrint - 1] == '\n';
1136 			buffer[toPrint] = '\0';
1137 			kputs(buffer);
1138 		}
1139 
1140 		if (debuggerOffset > sSyslogDebuggerOffset) {
1141 			// Our output caused older syslog output to be evicted from the
1142 			// syslog buffer. We need to adjust our offsets accordingly. Note,
1143 			// this can still go wrong, if the buffer was already full and more
1144 			// was written to it than we have processed, but we can't help that.
1145 			size_t diff = debuggerOffset - sSyslogDebuggerOffset;
1146 			start -= std::min(start, diff);
1147 			end -= std::min(end, diff);
1148 			debuggerOffset = sSyslogDebuggerOffset;
1149 		}
1150 	}
1151 
1152 	if (!newLine)
1153 		kputs("\n");
1154 
1155 	if (buffer != stackBuffer)
1156 		debug_free(buffer);
1157 
1158 	return 0;
1159 }
1160 
1161 
1162 static int
1163 cmd_switch_cpu(int argc, char** argv)
1164 {
1165 	if (argc > 2) {
1166 		print_debugger_command_usage(argv[0]);
1167 		return 0;
1168 	}
1169 
1170 	if (argc == 1) {
1171 		kprintf("running on CPU %" B_PRId32 "\n", smp_get_current_cpu());
1172 		return 0;
1173 	}
1174 
1175 	int32 newCPU = parse_expression(argv[1]);
1176 	if (newCPU < 0 || newCPU >= smp_get_num_cpus()) {
1177 		kprintf("invalid CPU index\n");
1178 		return 0;
1179 	}
1180 
1181 	if (newCPU == smp_get_current_cpu()) {
1182 		kprintf("already running on CPU %" B_PRId32 "\n", newCPU);
1183 		return 0;
1184 	}
1185 
1186 	sHandOverKDLToCPU = newCPU;
1187 
1188 	return B_KDEBUG_QUIT;
1189 }
1190 
1191 
1192 static status_t
1193 syslog_sender(void* data)
1194 {
1195 	bool bufferPending = false;
1196 	int32 length = 0;
1197 
1198 	while (true) {
1199 		// wait for syslog data to become available
1200 		acquire_sem_etc(sSyslogNotify, 1, B_RELATIVE_TIMEOUT, 5000000);
1201 			// Note: We time out since in some situations output is added to
1202 			// the syslog buffer without being allowed to notify us (e.g. in
1203 			// the kernel debugger).
1204 			// TODO: A semaphore is rather unhandy here. It is released for
1205 			// every single message written to the buffer, but we potentially
1206 			// send a lot more than a single message per iteration. On the other
1207 			// hand, as long as the syslog daemon is not running, we acquire
1208 			// the semaphore anyway. A better solution would be a flag + a
1209 			// condition variable.
1210 
1211 		sSyslogMessage->when = real_time_clock();
1212 
1213 		if (!bufferPending) {
1214 			// We need to have exclusive access to our syslog buffer
1215 			cpu_status state = disable_interrupts();
1216 			acquire_spinlock(&sSpinlock);
1217 
1218 			length = ring_buffer_readable(sSyslogBuffer)
1219 				- sSyslogBufferOffset;
1220 			if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH)
1221 				length = SYSLOG_MAX_MESSAGE_LENGTH;
1222 
1223 			uint8* message = (uint8*)sSyslogMessage->message;
1224 			if (sSyslogDropped) {
1225 				memcpy(message, "<DROP>", 6);
1226 				message += 6;
1227 				if ((length + 6) > (int32)SYSLOG_MAX_MESSAGE_LENGTH)
1228 					length -= 6;
1229 				sSyslogDropped = false;
1230 			}
1231 
1232 			length = ring_buffer_peek(sSyslogBuffer, sSyslogBufferOffset,
1233 				message, length);
1234 			sSyslogBufferOffset += length;
1235 			length += (addr_t)message - (addr_t)sSyslogMessage->message;
1236 
1237 			release_spinlock(&sSpinlock);
1238 			restore_interrupts(state);
1239 		}
1240 
1241 		if (length == 0) {
1242 			// The buffer we came here for might have been sent already
1243 			bufferPending = false;
1244 			continue;
1245 		}
1246 
1247 		status_t status = write_port_etc(sSyslogPort, SYSLOG_MESSAGE,
1248 			sSyslogMessage, sizeof(struct syslog_message) + length,
1249 			B_RELATIVE_TIMEOUT, 0);
1250 		if (status == B_BAD_PORT_ID) {
1251 			// The port is gone, there is no need to run anymore
1252 			sSyslogWriter = -1;
1253 			return status;
1254 		}
1255 
1256 		if (status != B_OK) {
1257 			// Sending has failed - just wait, maybe it'll work later.
1258 			bufferPending = true;
1259 			continue;
1260 		}
1261 
1262 		if (bufferPending) {
1263 			// We could write the last pending buffer, try to read more
1264 			// from the syslog ring buffer
1265 			release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE);
1266 			bufferPending = false;
1267 		}
1268 	}
1269 
1270 	return 0;
1271 }
1272 
1273 
1274 static void
1275 syslog_write(const char* text, int32 length, bool notify)
1276 {
1277 	if (sSyslogBuffer == NULL)
1278 		return;
1279 
1280 	if (length > sSyslogBuffer->size) {
1281 		syslog_write("<TRUNC>", 7, false);
1282 
1283 		text += length - (sSyslogBuffer->size - 7);
1284 		length = sSyslogBuffer->size - 7;
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 >= 0)
1317 		return B_OK;
1318 
1319 	// initializing kernel syslog service failed -- disable it
1320 
1321 	sSyslogOutputEnabled = false;
1322 
1323 	if (sSyslogBuffer != NULL) {
1324 		if (sDebugSyslog)
1325 			delete_area(area_for(sSyslogBuffer));
1326 		else
1327 			delete_ring_buffer(sSyslogBuffer);
1328 
1329 		sSyslogBuffer = NULL;
1330 	}
1331 
1332 	free(sSyslogMessage);
1333 	delete_sem(sSyslogNotify);
1334 
1335 	return B_ERROR;
1336 }
1337 
1338 
1339 static status_t
1340 syslog_init_post_vm(struct kernel_args* args)
1341 {
1342 	status_t status;
1343 	int32 length = 0;
1344 
1345 	if (!sSyslogOutputEnabled) {
1346 		sSyslogBuffer = NULL;
1347 			// Might already have been set in syslog_init(), if the debug syslog
1348 			// was enabled. Just drop it -- we'll never create the area.
1349 		return B_OK;
1350 	}
1351 
1352 	sSyslogMessage = (syslog_message*)malloc(SYSLOG_MESSAGE_BUFFER_SIZE);
1353 	if (sSyslogMessage == NULL) {
1354 		status = B_NO_MEMORY;
1355 		goto err1;
1356 	}
1357 
1358 	if (sSyslogBuffer == NULL) {
1359 		size_t bufferSize = DEFAULT_SYSLOG_BUFFER_SIZE;
1360 		void* handle = load_driver_settings("kernel");
1361 		if (handle != NULL) {
1362 			const char* sizeString = get_driver_parameter(handle,
1363 				"syslog_buffer_size", NULL, NULL);
1364 			if (sizeString != NULL) {
1365 				bufferSize = strtoul(sizeString, NULL, 0);
1366 				if (bufferSize > 262144)
1367 					bufferSize = 262144;
1368 				else if (bufferSize < SYSLOG_MESSAGE_BUFFER_SIZE)
1369 					bufferSize = SYSLOG_MESSAGE_BUFFER_SIZE;
1370 			}
1371 
1372 			unload_driver_settings(handle);
1373 		}
1374 
1375 		sSyslogBuffer = create_ring_buffer(bufferSize);
1376 
1377 		if (sSyslogBuffer == NULL) {
1378 			status = B_NO_MEMORY;
1379 			goto err2;
1380 		}
1381 	} else if (args->keep_debug_output_buffer) {
1382 		// create an area for the already-existing debug syslog buffer
1383 		void* base = (void*)ROUNDDOWN((addr_t)(void *)args->debug_output, B_PAGE_SIZE);
1384 		size_t size = ROUNDUP(args->debug_size, B_PAGE_SIZE);
1385 		area_id area = create_area("syslog debug", &base, B_EXACT_ADDRESS, size,
1386 			B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
1387 		if (area < 0) {
1388 			status = B_NO_MEMORY;
1389 			goto err2;
1390 		}
1391 	}
1392 
1393 	if (!args->keep_debug_output_buffer && args->debug_output != NULL) {
1394 		syslog_write((const char*)args->debug_output.Pointer(),
1395 			args->debug_size, false);
1396 	}
1397 
1398 	// initialize syslog message
1399 	sSyslogMessage->from = 0;
1400 	sSyslogMessage->options = LOG_KERN;
1401 	sSyslogMessage->priority = LOG_DEBUG;
1402 	sSyslogMessage->ident[0] = '\0';
1403 
1404 	// Allocate memory for the previous session's debug syslog output. In
1405 	// syslog_init_post_modules() we'll write it back to disk and free it.
1406 	if (args->previous_debug_output != NULL) {
1407 		sPreviousSessionSyslogBuffer = malloc(args->previous_debug_size);
1408 		if (sPreviousSessionSyslogBuffer != NULL) {
1409 			sPreviousSessionSyslogBufferSize = args->previous_debug_size;
1410 			memcpy(sPreviousSessionSyslogBuffer, args->previous_debug_output,
1411 				sPreviousSessionSyslogBufferSize);
1412 		}
1413 	}
1414 
1415 	char revisionBuffer[64];
1416 	length = snprintf(revisionBuffer, sizeof(revisionBuffer),
1417 		"Welcome to syslog debug output!\nHaiku revision: %s\n",
1418 		get_haiku_revision());
1419 	syslog_write(revisionBuffer,
1420 		std::min(length, (int32)sizeof(revisionBuffer) - 1), false);
1421 
1422 	add_debugger_command_etc("syslog", &cmd_dump_syslog,
1423 		"Dumps the syslog buffer.",
1424 		"[ \"-n\" ] [ \"-k\" ]\n"
1425 		"Dumps the whole syslog buffer, or, if -k is specified, only "
1426 		"the part that hasn't been sent yet.\n", 0);
1427 
1428 	return B_OK;
1429 
1430 err2:
1431 	free(sSyslogMessage);
1432 err1:
1433 	sSyslogOutputEnabled = false;
1434 	sSyslogBuffer = NULL;
1435 	return status;
1436 }
1437 
1438 static void
1439 syslog_init_post_modules()
1440 {
1441 	if (sPreviousSessionSyslogBuffer == NULL)
1442 		return;
1443 
1444 	void* buffer = sPreviousSessionSyslogBuffer;
1445 	size_t bufferSize = sPreviousSessionSyslogBufferSize;
1446 	sPreviousSessionSyslogBuffer = NULL;
1447 	sPreviousSessionSyslogBufferSize = 0;
1448 	MemoryDeleter bufferDeleter(buffer);
1449 
1450 	int fd = open("/var/log/previous_syslog", O_WRONLY | O_CREAT | O_TRUNC,
1451 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
1452 	if (fd < 0) {
1453 		dprintf("Failed to open previous syslog file: %s\n", strerror(errno));
1454 		return;
1455 	}
1456 
1457 	write(fd, buffer, bufferSize);
1458 	close(fd);
1459 }
1460 
1461 static status_t
1462 syslog_init(struct kernel_args* args)
1463 {
1464 	if (!args->keep_debug_output_buffer || args->debug_output == NULL)
1465 		return B_OK;
1466 
1467 	sSyslogBuffer = create_ring_buffer_etc(args->debug_output, args->debug_size,
1468 		RING_BUFFER_INIT_FROM_BUFFER);
1469 	sDebugSyslog = true;
1470 
1471 	return B_OK;
1472 }
1473 
1474 
1475 static void
1476 debug_memcpy_trampoline(void* _parameters)
1477 {
1478 	debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters;
1479 	memcpy(parameters->to, parameters->from, parameters->size);
1480 }
1481 
1482 
1483 static void
1484 debug_strlcpy_trampoline(void* _parameters)
1485 {
1486 	debug_strlcpy_parameters* parameters
1487 		= (debug_strlcpy_parameters*)_parameters;
1488 	parameters->result = strlcpy(parameters->to, parameters->from,
1489 		parameters->size);
1490 }
1491 
1492 
1493 void
1494 call_modules_hook(bool enter)
1495 {
1496 	uint32 index = 0;
1497 	while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) {
1498 		debugger_module_info* module = sDebuggerModules[index];
1499 
1500 		if (enter && module->enter_debugger != NULL)
1501 			module->enter_debugger();
1502 		else if (!enter && module->exit_debugger != NULL)
1503 			module->exit_debugger();
1504 
1505 		index++;
1506 	}
1507 }
1508 
1509 
1510 //!	Must be called with the sSpinlock held.
1511 static void
1512 debug_output(const char* string, int32 length, bool notifySyslog)
1513 {
1514 	if (length >= OUTPUT_BUFFER_SIZE)
1515 		length = OUTPUT_BUFFER_SIZE - 1;
1516 
1517 	if (length > 1 && string[length - 1] == '\n'
1518 		&& strncmp(string, sLastOutputBuffer, length) == 0) {
1519 		sMessageRepeatCount++;
1520 		sMessageRepeatLastTime = system_time();
1521 		if (sMessageRepeatFirstTime == 0)
1522 			sMessageRepeatFirstTime = sMessageRepeatLastTime;
1523 	} else {
1524 		flush_pending_repeats(notifySyslog);
1525 
1526 		if (sSerialDebugEnabled)
1527 			arch_debug_serial_puts(string);
1528 		if (sSyslogOutputEnabled)
1529 			syslog_write(string, length, notifySyslog);
1530 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1531 			blue_screen_puts(string);
1532 		if (sSerialDebugEnabled) {
1533 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1534 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1535 					sDebuggerModules[i]->debugger_puts(string, length);
1536 			}
1537 		}
1538 
1539 		memcpy(sLastOutputBuffer, string, length);
1540 		sLastOutputBuffer[length] = 0;
1541 	}
1542 }
1543 
1544 
1545 //!	Must be called with the sSpinlock held.
1546 static void
1547 flush_pending_repeats(bool notifySyslog)
1548 {
1549 	if (sMessageRepeatCount <= 0)
1550 		return;
1551 
1552 	if (sMessageRepeatCount > 1) {
1553 		static char temp[40];
1554 		size_t length = snprintf(temp, sizeof(temp),
1555 			"Last message repeated %" B_PRId32 " times.\n", sMessageRepeatCount);
1556 		length = std::min(length, sizeof(temp) - 1);
1557 
1558 		if (sSerialDebugEnabled)
1559 			arch_debug_serial_puts(temp);
1560 		if (sSyslogOutputEnabled)
1561 			syslog_write(temp, length, notifySyslog);
1562 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1563 			blue_screen_puts(temp);
1564 		if (sSerialDebugEnabled) {
1565 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1566 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1567 					sDebuggerModules[i]->debugger_puts(temp, length);
1568 			}
1569 		}
1570 	} else {
1571 		// if we only have one repeat just reprint the last buffer
1572 		size_t length = strlen(sLastOutputBuffer);
1573 
1574 		if (sSerialDebugEnabled)
1575 			arch_debug_serial_puts(sLastOutputBuffer);
1576 		if (sSyslogOutputEnabled)
1577 			syslog_write(sLastOutputBuffer, length, notifySyslog);
1578 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1579 			blue_screen_puts(sLastOutputBuffer);
1580 		if (sSerialDebugEnabled) {
1581 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1582 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) {
1583 					sDebuggerModules[i]->debugger_puts(sLastOutputBuffer,
1584 						length);
1585 				}
1586 			}
1587 		}
1588 	}
1589 
1590 	sMessageRepeatFirstTime = 0;
1591 	sMessageRepeatCount = 0;
1592 }
1593 
1594 
1595 static void
1596 check_pending_repeats(void* /*data*/, int /*iteration*/)
1597 {
1598 	if (sMessageRepeatCount > 0
1599 		&& (system_time() - sMessageRepeatLastTime > 1000000
1600 			|| system_time() - sMessageRepeatFirstTime > 3000000)) {
1601 		cpu_status state = disable_interrupts();
1602 		acquire_spinlock(&sSpinlock);
1603 
1604 		flush_pending_repeats(true);
1605 
1606 		release_spinlock(&sSpinlock);
1607 		restore_interrupts(state);
1608 	}
1609 }
1610 
1611 
1612 static void
1613 dprintf_args(const char* format, va_list args, bool notifySyslog)
1614 {
1615 	if (are_interrupts_enabled()) {
1616 		MutexLocker locker(sOutputLock);
1617 
1618 		int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format,
1619 			args);
1620 		length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1621 
1622 		InterruptsSpinLocker _(sSpinlock);
1623 		debug_output(sOutputBuffer, length, notifySyslog);
1624 	} else {
1625 		InterruptsSpinLocker _(sSpinlock);
1626 
1627 		int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE,
1628 			format, args);
1629 		length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1630 
1631 		debug_output(sInterruptOutputBuffer, length, notifySyslog);
1632 	}
1633 }
1634 
1635 
1636 // #pragma mark - private kernel API
1637 
1638 
1639 bool
1640 debug_screen_output_enabled(void)
1641 {
1642 	return sDebugScreenEnabled;
1643 }
1644 
1645 
1646 void
1647 debug_stop_screen_debug_output(void)
1648 {
1649 	sDebugScreenEnabled = false;
1650 }
1651 
1652 
1653 bool
1654 debug_debugger_running(void)
1655 {
1656 	return sDebuggerOnCPU != -1;
1657 }
1658 
1659 
1660 void
1661 debug_puts(const char* string, int32 length)
1662 {
1663 	InterruptsSpinLocker _(sSpinlock);
1664 	debug_output(string, length, true);
1665 }
1666 
1667 
1668 void
1669 debug_early_boot_message(const char* string)
1670 {
1671 	arch_debug_serial_early_boot_message(string);
1672 }
1673 
1674 
1675 void
1676 debug_init(kernel_args* args)
1677 {
1678 	new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter;
1679 
1680 	syslog_init(args);
1681 
1682 	debug_paranoia_init();
1683 	arch_debug_console_init(args);
1684 }
1685 
1686 
1687 void
1688 debug_init_post_vm(kernel_args* args)
1689 {
1690 	add_debugger_command_etc("cpu", &cmd_switch_cpu,
1691 		"Switches to another CPU.",
1692 		"<cpu>\n"
1693 		"Switches to CPU with the index <cpu>.\n", 0);
1694 	add_debugger_command_etc("message", &cmd_dump_kdl_message,
1695 		"Reprint the message printed when entering KDL",
1696 		"\n"
1697 		"Reprints the message printed when entering KDL.\n", 0);
1698 	add_debugger_command_etc("panic_commands", &cmd_execute_panic_commands,
1699 		"Execute commands associated with the panic() that caused "
1700 			"entering KDL",
1701 		"\n"
1702 		"Executes the commands associated with the panic() that caused "
1703 			"entering KDL.\n", 0);
1704 
1705 	debug_builtin_commands_init();
1706 	arch_debug_init(args);
1707 
1708 	debug_heap_init();
1709 	debug_variables_init();
1710 	frame_buffer_console_init(args);
1711 	tracing_init();
1712 }
1713 
1714 
1715 void
1716 debug_init_post_settings(struct kernel_args* args)
1717 {
1718 	// get debug settings
1719 
1720 	sSerialDebugEnabled = get_safemode_boolean("serial_debug_output",
1721 		sSerialDebugEnabled);
1722 	sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output",
1723 		sSyslogOutputEnabled);
1724 	sBlueScreenOutput = get_safemode_boolean("bluescreen", true);
1725 	sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys",
1726 		sEmergencyKeysEnabled);
1727 	sDebugScreenEnabled = get_safemode_boolean("debug_screen", false);
1728 
1729 	if ((sBlueScreenOutput || sDebugScreenEnabled)
1730 		&& blue_screen_init() != B_OK)
1731 		sBlueScreenOutput = sDebugScreenEnabled = false;
1732 
1733 	if (sDebugScreenEnabled)
1734 		blue_screen_enter(true);
1735 
1736 	arch_debug_console_init_settings(args);
1737 	syslog_init_post_vm(args);
1738 }
1739 
1740 
1741 void
1742 debug_init_post_modules(struct kernel_args* args)
1743 {
1744 	syslog_init_post_modules();
1745 
1746 	// check for dupped lines every 10/10 second
1747 	register_kernel_daemon(check_pending_repeats, NULL, 10);
1748 
1749 	syslog_init_post_threads();
1750 
1751 	// load kernel debugger addons
1752 
1753 	static const char* kDemanglePrefix = "debugger/demangle/";
1754 
1755 	void* cookie = open_module_list("debugger");
1756 	uint32 count = 0;
1757 	while (count < kMaxDebuggerModules) {
1758 		char name[B_FILE_NAME_LENGTH];
1759 		size_t nameLength = sizeof(name);
1760 
1761 		if (read_next_module_name(cookie, name, &nameLength) != B_OK)
1762 			break;
1763 
1764 		// get demangle module, if any
1765 		if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) {
1766 			if (sDemangleModule == NULL)
1767 				get_module(name, (module_info**)&sDemangleModule);
1768 			continue;
1769 		}
1770 
1771 		if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) {
1772 			dprintf("kernel debugger extension \"%s\": loaded\n", name);
1773 			count++;
1774 		} else
1775 			dprintf("kernel debugger extension \"%s\": failed to load\n", name);
1776 	}
1777 	close_module_list(cookie);
1778 
1779 	frame_buffer_console_init_post_modules(args);
1780 }
1781 
1782 
1783 void
1784 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags)
1785 {
1786 	sPageFaultInfo.fault_address = faultAddress;
1787 	sPageFaultInfo.pc = pc;
1788 	sPageFaultInfo.flags = flags;
1789 }
1790 
1791 
1792 debug_page_fault_info*
1793 debug_get_page_fault_info()
1794 {
1795 	return &sPageFaultInfo;
1796 }
1797 
1798 
1799 void
1800 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
1801 {
1802 	InterruptsLocker locker;
1803 
1804 	// return, if we've been called recursively (we call
1805 	// smp_intercpu_int_handler() below)
1806 	if (sCPUTrapped[cpu])
1807 		return;
1808 
1809 	arch_debug_save_registers(&sDebugRegisters[cpu]);
1810 
1811 	sCPUTrapped[cpu] = true;
1812 
1813 	while (sInDebugger != 0) {
1814 		if (sHandOverKDL && sHandOverKDLToCPU == cpu) {
1815 			if (returnIfHandedOver)
1816 				break;
1817 
1818 			kernel_debugger_internal(NULL, NULL,
1819 				sCurrentKernelDebuggerMessageArgs, cpu);
1820 		} else
1821 			smp_intercpu_int_handler(cpu);
1822 	}
1823 
1824 	sCPUTrapped[cpu] = false;
1825 }
1826 
1827 
1828 void
1829 debug_double_fault(int32 cpu)
1830 {
1831 	kernel_debugger_internal("Double Fault!", NULL,
1832 		sCurrentKernelDebuggerMessageArgs, cpu);
1833 }
1834 
1835 
1836 bool
1837 debug_emergency_key_pressed(char key)
1838 {
1839 	if (!sEmergencyKeysEnabled)
1840 		return false;
1841 
1842 	if (key == 'd') {
1843 		kernel_debugger("Keyboard Requested Halt.");
1844 		return true;
1845 	}
1846 
1847 	// Broadcast to the kernel debugger modules
1848 
1849 	for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1850 		if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) {
1851 			if (sDebuggerModules[i]->emergency_key_pressed(key))
1852 				return true;
1853 		}
1854 	}
1855 
1856 	return false;
1857 }
1858 
1859 
1860 /*!	Verifies that the complete given memory range is accessible in the current
1861 	context.
1862 
1863 	Invoked in the kernel debugger only.
1864 
1865 	\param address The start address of the memory range to be checked.
1866 	\param size The size of the memory range to be checked.
1867 	\param protection The area protection for which to check. Valid is a bitwise
1868 		or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA.
1869 	\return \c true, if the complete memory range can be accessed in all ways
1870 		specified by \a protection, \c false otherwise.
1871 */
1872 bool
1873 debug_is_kernel_memory_accessible(addr_t address, size_t size,
1874 	uint32 protection)
1875 {
1876 	addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE);
1877 	address = ROUNDDOWN(address, B_PAGE_SIZE);
1878 
1879 	if (!IS_KERNEL_ADDRESS(address) || endAddress < address)
1880 		return false;
1881 
1882 	for (; address < endAddress; address += B_PAGE_SIZE) {
1883 		if (!arch_vm_translation_map_is_kernel_page_accessible(address,
1884 				protection)) {
1885 			return false;
1886 		}
1887 	}
1888 
1889 	return true;
1890 }
1891 
1892 
1893 /*!	Calls a function in a setjmp() + fault handler context.
1894 	May only be used in the kernel debugger.
1895 
1896 	\param jumpBuffer Buffer to be used for setjmp()/longjmp().
1897 	\param function The function to be called.
1898 	\param parameter The parameter to be passed to the function to be called.
1899 	\return
1900 		- \c 0, when the function executed without causing a page fault or
1901 		  calling longjmp().
1902 		- \c 1, when the function caused a page fault.
1903 		- Any other value the function passes to longjmp().
1904 */
1905 int
1906 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*),
1907 	void* parameter)
1908 {
1909 	// save current fault handler
1910 	cpu_ent* cpu = gCPU + sDebuggerOnCPU;
1911 	addr_t oldFaultHandler = cpu->fault_handler;
1912 	addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer;
1913 
1914 	int result = setjmp(jumpBuffer);
1915 	if (result == 0) {
1916 		arch_debug_call_with_fault_handler(cpu, jumpBuffer, function,
1917 			parameter);
1918 	}
1919 
1920 	// restore old fault handler
1921 	cpu->fault_handler = oldFaultHandler;
1922 	cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer;
1923 
1924 	return result;
1925 }
1926 
1927 
1928 /*!	Similar to user_memcpy(), but can only be invoked from within the kernel
1929 	debugger (and must not be used outside).
1930 	The supplied \a teamID specifies the address space in which to interpret
1931 	the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(),
1932 	or any valid team ID. If the addresses are both kernel addresses, the
1933 	argument is ignored and the current address space is used.
1934 */
1935 status_t
1936 debug_memcpy(team_id teamID, void* to, const void* from, size_t size)
1937 {
1938 	// don't allow address overflows
1939 	if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to)
1940 		return B_BAD_ADDRESS;
1941 
1942 	// Try standard memcpy() with fault handler, if the addresses can be
1943 	// interpreted in the current address space.
1944 	if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to))
1945 			|| debug_is_debugged_team(teamID)) {
1946 		debug_memcpy_parameters parameters = {to, from, size};
1947 
1948 		if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1949 				&debug_memcpy_trampoline, &parameters) == 0) {
1950 			return B_OK;
1951 		}
1952 	}
1953 
1954 	// Try harder. The pages of the respective memory could be unmapped but
1955 	// still exist in a cache (the page daemon does that with inactive pages).
1956 	while (size > 0) {
1957 		uint8 buffer[32];
1958 		size_t toCopy = std::min(size, sizeof(buffer));
1959 
1960 		// restrict the size so we don't cross page boundaries
1961 		if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy)
1962 			toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE;
1963 		if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy)
1964 			toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE;
1965 
1966 		if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy,
1967 				false) != B_OK
1968 			|| vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
1969 				!= B_OK) {
1970 			return B_BAD_ADDRESS;
1971 		}
1972 
1973 		from = (const uint8*)from + toCopy;
1974 		to = (uint8*)to + toCopy;
1975 		size -= toCopy;
1976 	}
1977 
1978 	return B_OK;
1979 }
1980 
1981 
1982 /*!	Similar to user_strlcpy(), but can only be invoked from within the kernel
1983 	debugger (and must not be used outside).
1984 	The supplied \a teamID specifies the address space in which to interpret
1985 	the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(),
1986 	or any valid team ID. If the addresses are both kernel addresses, the
1987 	argument is ignored and the current address space is used.
1988 */
1989 ssize_t
1990 debug_strlcpy(team_id teamID, char* to, const char* from, size_t size)
1991 {
1992 	if (from == NULL || (to == NULL && size > 0))
1993 		return B_BAD_ADDRESS;
1994 
1995 	// limit size to avoid address overflows
1996 	size_t maxSize = std::min((addr_t)size,
1997 		~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1);
1998 		// NOTE: Since strlcpy() determines the length of \a from, the source
1999 		// address might still overflow.
2000 
2001 	// Try standard strlcpy() with fault handler, if the addresses can be
2002 	// interpreted in the current address space.
2003 	if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to))
2004 			|| debug_is_debugged_team(teamID)) {
2005 		debug_strlcpy_parameters parameters = {to, from, maxSize};
2006 
2007 		if (debug_call_with_fault_handler(
2008 				gCPU[sDebuggerOnCPU].fault_jump_buffer,
2009 				&debug_strlcpy_trampoline, &parameters) == 0) {
2010 			// If we hit the address overflow boundary, fail.
2011 			if (parameters.result >= maxSize && maxSize < size)
2012 				return B_BAD_ADDRESS;
2013 
2014 			return parameters.result;
2015 		}
2016 	}
2017 
2018 	// Try harder. The pages of the respective memory could be unmapped but
2019 	// still exist in a cache (the page daemon does that with inactive pages).
2020 	size_t totalLength = 0;
2021 	while (maxSize > 0) {
2022 		char buffer[32];
2023 		size_t toCopy = std::min(maxSize, sizeof(buffer));
2024 
2025 		// restrict the size so we don't cross page boundaries
2026 		if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy)
2027 			toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE;
2028 		if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy)
2029 			toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE;
2030 
2031 		// copy the next part of the string from the source
2032 		if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy,
2033 				false) != B_OK) {
2034 			return B_BAD_ADDRESS;
2035 		}
2036 
2037 		// determine the length of the part and whether we've reached the end
2038 		// of the string
2039 		size_t length = strnlen(buffer, toCopy);
2040 		bool endOfString = length < toCopy;
2041 
2042 		from = (const char*)from + toCopy;
2043 		totalLength += length;
2044 		maxSize -= length;
2045 
2046 		if (endOfString) {
2047 			// only copy the actual string, including the terminating null
2048 			toCopy = length + 1;
2049 		}
2050 
2051 		if (size > 0) {
2052 			// We still have space left in the target buffer.
2053 			if (size <= length) {
2054 				// Not enough space for the complete part. Null-terminate it and
2055 				// copy what we can.
2056 				buffer[size - 1] = '\0';
2057 				totalLength += length - size;
2058 				toCopy = size;
2059 			}
2060 
2061 			if (vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
2062 					!= B_OK) {
2063 				return B_BAD_ADDRESS;
2064 			}
2065 
2066 			to = (char*)to + toCopy;
2067 			size -= toCopy;
2068 		}
2069 
2070 		if (endOfString)
2071 			return totalLength;
2072 	}
2073 
2074 	return totalLength;
2075 }
2076 
2077 
2078 // #pragma mark - public API
2079 
2080 
2081 uint64
2082 parse_expression(const char* expression)
2083 {
2084 	uint64 result;
2085 	return evaluate_debug_expression(expression, &result, true) ? result : 0;
2086 }
2087 
2088 
2089 void
2090 panic(const char* format, ...)
2091 {
2092 	va_list args;
2093 	va_start(args, format);
2094 
2095 	cpu_status state = disable_interrupts();
2096 
2097 	kernel_debugger_internal("PANIC: ", format, args,
2098 		thread_get_current_thread() ? smp_get_current_cpu() : 0);
2099 
2100 	restore_interrupts(state);
2101 
2102 	va_end(args);
2103 }
2104 
2105 
2106 void
2107 kernel_debugger(const char* message)
2108 {
2109 	cpu_status state = disable_interrupts();
2110 
2111 	kernel_debugger_internal(message, NULL, sCurrentKernelDebuggerMessageArgs,
2112 		smp_get_current_cpu());
2113 
2114 	restore_interrupts(state);
2115 }
2116 
2117 
2118 bool
2119 set_dprintf_enabled(bool newState)
2120 {
2121 	bool oldState = sSerialDebugEnabled;
2122 	sSerialDebugEnabled = newState;
2123 
2124 	return oldState;
2125 }
2126 
2127 
2128 void
2129 dprintf(const char* format, ...)
2130 {
2131 	va_list args;
2132 
2133 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
2134 		return;
2135 
2136 	va_start(args, format);
2137 	dprintf_args(format, args, true);
2138 	va_end(args);
2139 }
2140 
2141 
2142 void
2143 dvprintf(const char* format, va_list args)
2144 {
2145 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
2146 		return;
2147 
2148 	dprintf_args(format, args, true);
2149 }
2150 
2151 
2152 void
2153 dprintf_no_syslog(const char* format, ...)
2154 {
2155 	va_list args;
2156 
2157 	if (!sSerialDebugEnabled && !sBlueScreenEnabled)
2158 		return;
2159 
2160 	va_start(args, format);
2161 	dprintf_args(format, args, false);
2162 	va_end(args);
2163 }
2164 
2165 
2166 /*!	Similar to dprintf() but thought to be used in the kernel
2167 	debugger only (it doesn't lock).
2168 */
2169 void
2170 kprintf(const char* format, ...)
2171 {
2172 	if (sDebugOutputFilter != NULL) {
2173 		va_list args;
2174 		va_start(args, format);
2175 		sDebugOutputFilter->Print(format, args);
2176 		va_end(args);
2177 	}
2178 }
2179 
2180 
2181 void
2182 kprintf_unfiltered(const char* format, ...)
2183 {
2184 	va_list args;
2185 	va_start(args, format);
2186 	gDefaultDebugOutputFilter.Print(format, args);
2187 	va_end(args);
2188 }
2189 
2190 
2191 const char*
2192 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize,
2193 	bool* _isObjectMethod)
2194 {
2195 	if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) {
2196 		return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize,
2197 			_isObjectMethod);
2198 	}
2199 
2200 	if (_isObjectMethod != NULL)
2201 		*_isObjectMethod = false;
2202 
2203 	return symbol;
2204 }
2205 
2206 
2207 status_t
2208 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol,
2209 	char* name, size_t nameSize, int32* _type, size_t* _argumentLength)
2210 {
2211 	if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) {
2212 		return sDemangleModule->get_next_argument(_cookie, symbol, name,
2213 			nameSize, _type, _argumentLength);
2214 	}
2215 
2216 	return B_NOT_SUPPORTED;
2217 }
2218 
2219 
2220 struct arch_debug_registers*
2221 debug_get_debug_registers(int32 cpu)
2222 {
2223 	if (cpu < 0 || cpu > smp_get_num_cpus())
2224 		return NULL;
2225 
2226 	return &sDebugRegisters[cpu];
2227 }
2228 
2229 
2230 Thread*
2231 debug_set_debugged_thread(Thread* thread)
2232 {
2233 	Thread* previous = sDebuggedThread;
2234 	sDebuggedThread = thread;
2235 	return previous;
2236 }
2237 
2238 
2239 Thread*
2240 debug_get_debugged_thread()
2241 {
2242 	return sDebuggedThread != NULL
2243 		? sDebuggedThread : thread_get_current_thread();
2244 }
2245 
2246 
2247 /*!	Returns whether the supplied team ID refers to the same team the currently
2248 	debugged thread (debug_get_debugged_thread()) belongs to.
2249 	Always returns \c true, if \c B_CURRENT_TEAM is given.
2250 */
2251 bool
2252 debug_is_debugged_team(team_id teamID)
2253 {
2254 	if (teamID == B_CURRENT_TEAM)
2255 		return true;
2256 
2257 	Thread* thread = debug_get_debugged_thread();
2258 	return thread != NULL && thread->team != NULL
2259 		&& thread->team->id == teamID;
2260 }
2261 
2262 
2263 //	#pragma mark -
2264 //	userland syscalls
2265 
2266 
2267 status_t
2268 _user_kernel_debugger(const char* userMessage)
2269 {
2270 	if (geteuid() != 0)
2271 		return B_NOT_ALLOWED;
2272 
2273 	char message[512];
2274 	strcpy(message, "USER: ");
2275 	size_t length = strlen(message);
2276 
2277 	if (userMessage == NULL || !IS_USER_ADDRESS(userMessage) || user_strlcpy(
2278 			message + length, userMessage, sizeof(message) - length) < 0) {
2279 		return B_BAD_ADDRESS;
2280 	}
2281 
2282 	kernel_debugger(message);
2283 	return B_OK;
2284 }
2285 
2286 
2287 void
2288 _user_register_syslog_daemon(port_id port)
2289 {
2290 	if (geteuid() != 0 || !sSyslogOutputEnabled || sSyslogNotify < 0)
2291 		return;
2292 
2293 	sSyslogPort = port;
2294 
2295 	if (sSyslogWriter < 0) {
2296 		sSyslogWriter = spawn_kernel_thread(syslog_sender, "syslog sender",
2297 			B_LOW_PRIORITY, NULL);
2298 		if (sSyslogWriter >= 0)
2299 			resume_thread(sSyslogWriter);
2300 	}
2301 }
2302 
2303 
2304 void
2305 _user_debug_output(const char* userString)
2306 {
2307 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled)
2308 		return;
2309 
2310 	if (!IS_USER_ADDRESS(userString))
2311 		return;
2312 
2313 	char string[512];
2314 	int32 length;
2315 	int32 toWrite;
2316 	do {
2317 		length = user_strlcpy(string, userString, sizeof(string));
2318 		if (length <= 0)
2319 			break;
2320 		toWrite = std::min(length, (int32)sizeof(string) - 1);
2321 		debug_puts(string, toWrite);
2322 		userString += toWrite;
2323 	} while (length > toWrite);
2324 }
2325 
2326 
2327 void
2328 dump_block(const char* buffer, int size, const char* prefix)
2329 {
2330 	const int DUMPED_BLOCK_SIZE = 16;
2331 	int i;
2332 
2333 	for (i = 0; i < size;) {
2334 		int start = i;
2335 
2336 		dprintf("%s%04x ", prefix, i);
2337 		for (; i < start + DUMPED_BLOCK_SIZE; i++) {
2338 			if (!(i % 4))
2339 				dprintf(" ");
2340 
2341 			if (i >= size)
2342 				dprintf("  ");
2343 			else
2344 				dprintf("%02x", *(unsigned char*)(buffer + i));
2345 		}
2346 		dprintf("  ");
2347 
2348 		for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) {
2349 			if (i < size) {
2350 				char c = buffer[i];
2351 
2352 				if (c < 30)
2353 					dprintf(".");
2354 				else
2355 					dprintf("%c", c);
2356 			} else
2357 				break;
2358 		}
2359 		dprintf("\n");
2360 	}
2361 }
2362