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