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