xref: /haiku/src/system/kernel/debug/debug.cpp (revision c9ad965c81b08802fed0827fd1dd16f45297928a)
1 /*
2  * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
4  * Distributed under the terms of the MIT License.
5  *
6  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
7  * Distributed under the terms of the NewOS License.
8  */
9 
10 
11 /*! This file contains the debugger and debug output facilities */
12 
13 
14 #include "blue_screen.h"
15 
16 #include <algorithm>
17 
18 #include <cpu.h>
19 #include <debug.h>
20 #include <debug_heap.h>
21 #include <debug_paranoia.h>
22 #include <driver_settings.h>
23 #include <frame_buffer_console.h>
24 #include <int.h>
25 #include <kernel.h>
26 #include <ksystem_info.h>
27 #include <safemode.h>
28 #include <smp.h>
29 #include <thread.h>
30 #include <tracing.h>
31 #include <vm.h>
32 #include <vm_translation_map.h>
33 
34 #include <arch/debug_console.h>
35 #include <arch/debug.h>
36 #include <util/AutoLock.h>
37 #include <util/ring_buffer.h>
38 
39 #include <syslog_daemon.h>
40 
41 #include <ctype.h>
42 #include <stdarg.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <syslog.h>
47 
48 #include "debug_builtin_commands.h"
49 #include "debug_commands.h"
50 #include "debug_output_filter.h"
51 #include "debug_variables.h"
52 
53 
54 struct debug_memcpy_parameters {
55 	void*		to;
56 	const void*	from;
57 	size_t		size;
58 };
59 
60 struct debug_strlcpy_parameters {
61 	char*		to;
62 	const char*	from;
63 	size_t		size;
64 	size_t		result;
65 };
66 
67 
68 static const char* const kKDLPrompt = "kdebug> ";
69 
70 extern "C" int kgets(char* buffer, int length);
71 
72 void call_modules_hook(bool enter);
73 
74 
75 int dbg_register_file[B_MAX_CPU_COUNT][14];
76 	/* XXXmpetit -- must be made generic */
77 
78 static debug_page_fault_info sPageFaultInfo;
79 
80 static bool sSerialDebugEnabled = true;
81 static bool sSyslogOutputEnabled = true;
82 static bool sBlueScreenEnabled = false;
83 	// must always be false on startup
84 static bool sDebugScreenEnabled = false;
85 static bool sBlueScreenOutput = true;
86 static bool sEmergencyKeysEnabled = true;
87 static spinlock sSpinlock = B_SPINLOCK_INITIALIZER;
88 static int32 sDebuggerOnCPU = -1;
89 
90 static sem_id sSyslogNotify = -1;
91 static struct syslog_message* sSyslogMessage;
92 static struct ring_buffer* sSyslogBuffer;
93 static bool sSyslogDropped = false;
94 
95 static const char* sCurrentKernelDebuggerMessage;
96 
97 #define DEFAULT_SYSLOG_BUFFER_SIZE 65536
98 #define OUTPUT_BUFFER_SIZE 1024
99 static char sOutputBuffer[OUTPUT_BUFFER_SIZE];
100 static char sInterruptOutputBuffer[OUTPUT_BUFFER_SIZE];
101 static char sLastOutputBuffer[OUTPUT_BUFFER_SIZE];
102 static DebugOutputFilter* sDebugOutputFilter = NULL;
103 DefaultDebugOutputFilter gDefaultDebugOutputFilter;
104 static mutex sOutputLock = MUTEX_INITIALIZER("debug output");
105 
106 static void flush_pending_repeats(bool syslogOutput);
107 static void check_pending_repeats(void* data, int iter);
108 
109 static int64 sMessageRepeatFirstTime = 0;
110 static int64 sMessageRepeatLastTime = 0;
111 static int32 sMessageRepeatCount = 0;
112 
113 static debugger_module_info* sDebuggerModules[8];
114 static const uint32 kMaxDebuggerModules = sizeof(sDebuggerModules)
115 	/ sizeof(sDebuggerModules[0]);
116 
117 #define LINE_BUFFER_SIZE 1024
118 #define HISTORY_SIZE 16
119 
120 static char sLineBuffer[HISTORY_SIZE][LINE_BUFFER_SIZE] = { "", };
121 static int32 sCurrentLine = 0;
122 
123 static debugger_demangle_module_info* sDemangleModule;
124 
125 static struct thread* sDebuggedThread;
126 static vint32 sInDebugger = 0;
127 static bool sPreviousDprintfState;
128 static volatile bool sHandOverKDL = false;
129 static vint32 sHandOverKDLToCPU = -1;
130 static bool sCPUTrapped[B_MAX_CPU_COUNT];
131 
132 
133 #define distance(a, b) ((a) < (b) ? (b) - (a) : (a) - (b))
134 
135 
136 // #pragma mark - DebugOutputFilter
137 
138 
139 DebugOutputFilter::DebugOutputFilter()
140 {
141 }
142 
143 
144 DebugOutputFilter::~DebugOutputFilter()
145 {
146 }
147 
148 
149 void
150 DebugOutputFilter::PrintString(const char* string)
151 {
152 }
153 
154 
155 void
156 DebugOutputFilter::Print(const char* format, va_list args)
157 {
158 }
159 
160 
161 void
162 DefaultDebugOutputFilter::PrintString(const char* string)
163 {
164 	if (sSerialDebugEnabled)
165 		arch_debug_serial_puts(string);
166 	if (sBlueScreenEnabled || sDebugScreenEnabled)
167 		blue_screen_puts(string);
168 
169 	for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++) {
170 		if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
171 			sDebuggerModules[i]->debugger_puts(string, strlen(string));
172 	}
173 }
174 
175 
176 void
177 DefaultDebugOutputFilter::Print(const char* format, va_list args)
178 {
179 	vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, format, args);
180 	flush_pending_repeats(sInDebugger == 0);
181 	PrintString(sInterruptOutputBuffer);
182 }
183 
184 
185 // #pragma mark -
186 
187 
188 DebugOutputFilter*
189 set_debug_output_filter(DebugOutputFilter* filter)
190 {
191 	DebugOutputFilter* oldFilter = sDebugOutputFilter;
192 	sDebugOutputFilter = filter;
193 	return oldFilter;
194 }
195 
196 
197 static void
198 kputchar(char c)
199 {
200 	if (sSerialDebugEnabled)
201 		arch_debug_serial_putchar(c);
202 	if (sBlueScreenEnabled || sDebugScreenEnabled)
203 		blue_screen_putchar(c);
204 	for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++)
205 		if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
206 			sDebuggerModules[i]->debugger_puts(&c, sizeof(c));
207 }
208 
209 
210 void
211 kputs(const char* s)
212 {
213 	if (sDebugOutputFilter != NULL)
214 		sDebugOutputFilter->PrintString(s);
215 }
216 
217 
218 void
219 kputs_unfiltered(const char* s)
220 {
221 	gDefaultDebugOutputFilter.PrintString(s);
222 }
223 
224 
225 static void
226 insert_chars_into_line(char* buffer, int32& position, int32& length,
227 	const char* chars, int32 charCount)
228 {
229 	// move the following chars to make room for the ones to insert
230 	if (position < length) {
231 		memmove(buffer + position + charCount, buffer + position,
232 			length - position);
233 	}
234 
235 	// insert chars
236 	memcpy(buffer + position, chars, charCount);
237 	int32 oldPosition = position;
238 	position += charCount;
239 	length += charCount;
240 
241 	// print the new chars (and the following ones)
242 	kprintf("%.*s", (int)(length - oldPosition),
243 		buffer + oldPosition);
244 
245 	// reposition cursor, if necessary
246 	if (position < length)
247 		kprintf("\x1b[%ldD", length - position);
248 }
249 
250 
251 static void
252 insert_char_into_line(char* buffer, int32& position, int32& length, char c)
253 {
254 	insert_chars_into_line(buffer, position, length, &c, 1);
255 }
256 
257 
258 static void
259 remove_char_from_line(char* buffer, int32& position, int32& length)
260 {
261 	if (position == length)
262 		return;
263 
264 	length--;
265 
266 	if (position < length) {
267 		// move the subsequent chars
268 		memmove(buffer + position, buffer + position + 1, length - position);
269 
270 		// print the rest of the line again, if necessary
271 		for (int32 i = position; i < length; i++)
272 			kputchar(buffer[i]);
273 	}
274 
275 	// visually clear the last char
276 	kputchar(' ');
277 
278 	// reposition the cursor
279 	kprintf("\x1b[%ldD", length - position + 1);
280 }
281 
282 
283 class LineEditingHelper {
284 public:
285 	virtual	~LineEditingHelper() {}
286 
287 	virtual	void TabCompletion(char* buffer, int32 capacity, int32& position,
288 		int32& length) = 0;
289 };
290 
291 
292 class CommandLineEditingHelper : public LineEditingHelper {
293 public:
294 	CommandLineEditingHelper()
295 	{
296 	}
297 
298 	virtual	~CommandLineEditingHelper() {}
299 
300 	virtual	void TabCompletion(char* buffer, int32 capacity, int32& position,
301 		int32& length)
302 	{
303 		// find the first space
304 		char tmpChar = buffer[position];
305 		buffer[position] = '\0';
306 		char* firstSpace = strchr(buffer, ' ');
307 		buffer[position] = tmpChar;
308 
309 		bool reprintLine = false;
310 
311 		if (firstSpace != NULL) {
312 			// a complete command -- print its help
313 
314 			// get the command
315 			tmpChar = *firstSpace;
316 			*firstSpace = '\0';
317 			bool ambiguous;
318 			debugger_command* command = find_debugger_command(buffer, true, ambiguous);
319 			*firstSpace = tmpChar;
320 
321 			if (command != NULL) {
322 				kputchar('\n');
323 				print_debugger_command_usage(command->name);
324 			} else {
325 				if (ambiguous)
326 					kprintf("\nambiguous command\n");
327 				else
328 					kprintf("\nno such command\n");
329 			}
330 
331 			reprintLine = true;
332 		} else {
333 			// a partial command -- look for completions
334 
335 			// check for possible completions
336 			int32 count = 0;
337 			int32 longestName = 0;
338 			debugger_command* command = NULL;
339 			int32 longestCommonPrefix = 0;
340 			const char* previousCommandName = NULL;
341 			while ((command = next_debugger_command(command, buffer, position))
342 					!= NULL) {
343 				count++;
344 				int32 nameLength = strlen(command->name);
345 				longestName = max_c(longestName, nameLength);
346 
347 				// updated the length of the longest common prefix of the
348 				// commands
349 				if (count == 1) {
350 					longestCommonPrefix = longestName;
351 				} else {
352 					longestCommonPrefix = min_c(longestCommonPrefix,
353 						nameLength);
354 
355 					for (int32 i = position; i < longestCommonPrefix; i++) {
356 						if (previousCommandName[i] != command->name[i]) {
357 							longestCommonPrefix = i;
358 							break;
359 						}
360 					}
361 				}
362 
363 				previousCommandName = command->name;
364 			}
365 
366 			if (count == 0) {
367 				// no possible completions
368 				kprintf("\nno completions\n");
369 				reprintLine = true;
370 			} else if (count == 1) {
371 				// exactly one completion
372 				command = next_debugger_command(NULL, buffer, position);
373 
374 				// check for sufficient space in the buffer
375 				int32 neededSpace = longestName - position + 1;
376 					// remainder of the name plus one space
377 				// also consider the terminating null char
378 				if (length + neededSpace + 1 >= capacity)
379 					return;
380 
381 				insert_chars_into_line(buffer, position, length,
382 					command->name + position, longestName - position);
383 				insert_char_into_line(buffer, position, length, ' ');
384 			} else if (longestCommonPrefix > position) {
385 				// multiple possible completions with longer common prefix
386 				// -- insert the remainder of the common prefix
387 
388 				// check for sufficient space in the buffer
389 				int32 neededSpace = longestCommonPrefix - position;
390 				// also consider the terminating null char
391 				if (length + neededSpace + 1 >= capacity)
392 					return;
393 
394 				insert_chars_into_line(buffer, position, length,
395 					previousCommandName + position, neededSpace);
396 			} else {
397 				// multiple possible completions without longer common prefix
398 				// -- print them all
399 				kprintf("\n");
400 				reprintLine = true;
401 
402 				int columns = 80 / (longestName + 2);
403 				debugger_command* command = NULL;
404 				int column = 0;
405 				while ((command = next_debugger_command(command, buffer, position))
406 						!= NULL) {
407 					// spacing
408 					if (column > 0 && column % columns == 0)
409 						kputchar('\n');
410 					column++;
411 
412 					kprintf("  %-*s", (int)longestName, command->name);
413 				}
414 				kputchar('\n');
415 			}
416 		}
417 
418 		// reprint the editing line, if necessary
419 		if (reprintLine) {
420 			kprintf("%s%.*s", kKDLPrompt, (int)length, buffer);
421 			if (position < length)
422 				kprintf("\x1b[%ldD", length - position);
423 		}
424 	}
425 };
426 
427 
428 static int
429 read_line(char* buffer, int32 maxLength,
430 	LineEditingHelper* editingHelper = NULL)
431 {
432 	int32 currentHistoryLine = sCurrentLine;
433 	int32 position = 0;
434 	int32 length = 0;
435 	bool done = false;
436 	char c = 0;
437 
438 	while (!done) {
439 		c = kgetc();
440 
441 		switch (c) {
442 			case '\n':
443 			case '\r':
444 				buffer[length++] = '\0';
445 				kputchar('\n');
446 				done = true;
447 				break;
448 			case '\t':
449 			{
450 				if (editingHelper != NULL) {
451 					editingHelper->TabCompletion(buffer, maxLength,
452 						position, length);
453 				}
454 				break;
455 			}
456 			case 8: // backspace
457 				if (position > 0) {
458 					kputs("\x1b[1D"); // move to the left one
459 					position--;
460 					remove_char_from_line(buffer, position, length);
461 				}
462 				break;
463 			case 0x1f & 'K':	// CTRL-K -- clear line after current position
464 				if (position < length) {
465 					// clear chars
466 					for (int32 i = position; i < length; i++)
467 						kputchar(' ');
468 
469 					// reposition cursor
470 					kprintf("\x1b[%ldD", length - position);
471 
472 					length = position;
473 				}
474 				break;
475 			case 0x1f & 'L':	// CTRL-L -- clear screen
476 				if (sBlueScreenOutput) {
477 					// All the following needs to be transparent for the
478 					// serial debug output. I.e. after clearing the screen
479 					// we have to get the on-screen line into the visual state
480 					// it should have.
481 
482 					// clear screen
483 					blue_screen_clear_screen();
484 
485 					// reprint line
486 					buffer[length] = '\0';
487 					blue_screen_puts(kKDLPrompt);
488 					blue_screen_puts(buffer);
489 
490 					// reposition cursor
491 					if (position < length) {
492 						for (int i = length; i > position; i--)
493 							blue_screen_puts("\x1b[1D");
494 					}
495 				}
496 				break;
497 			case 27: // escape sequence
498 				c = kgetc();
499 				if (c != '[') {
500 					// ignore broken escape sequence
501 					break;
502 				}
503 				c = kgetc();
504 				switch (c) {
505 					case 'C': // right arrow
506 						if (position < length) {
507 							kputs("\x1b[1C"); // move to the right one
508 							position++;
509 						}
510 						break;
511 					case 'D': // left arrow
512 						if (position > 0) {
513 							kputs("\x1b[1D"); // move to the left one
514 							position--;
515 						}
516 						break;
517 					case 'A': // up arrow
518 					case 'B': // down arrow
519 					{
520 						int32 historyLine = 0;
521 
522 						if (c == 'A') {
523 							// up arrow
524 							historyLine = currentHistoryLine - 1;
525 							if (historyLine < 0)
526 								historyLine = HISTORY_SIZE - 1;
527 						} else {
528 							// down arrow
529 							if (currentHistoryLine == sCurrentLine)
530 								break;
531 
532 							historyLine = currentHistoryLine + 1;
533 							if (historyLine >= HISTORY_SIZE)
534 								historyLine = 0;
535 						}
536 
537 						// clear the history again if we're in the current line again
538 						// (the buffer we get just is the current line buffer)
539 						if (historyLine == sCurrentLine) {
540 							sLineBuffer[historyLine][0] = '\0';
541 						} else if (sLineBuffer[historyLine][0] == '\0') {
542 							// empty history lines are unused -- so bail out
543 							break;
544 						}
545 
546 						// swap the current line with something from the history
547 						if (position > 0)
548 							kprintf("\x1b[%ldD", position); // move to beginning of line
549 
550 						strcpy(buffer, sLineBuffer[historyLine]);
551 						length = position = strlen(buffer);
552 						kprintf("%s\x1b[K", buffer); // print the line and clear the rest
553 						currentHistoryLine = historyLine;
554 						break;
555 					}
556 					case '5':	// if "5~", it's PAGE UP
557 					case '6':	// if "6~", it's PAGE DOWN
558 					{
559 						if (kgetc() != '~')
560 							break;
561 
562 						// PAGE UP: search backward, PAGE DOWN: forward
563 						int32 searchDirection = (c == '5' ? -1 : 1);
564 
565 						bool found = false;
566 						int32 historyLine = currentHistoryLine;
567 						do {
568 							historyLine = (historyLine + searchDirection
569 								+ HISTORY_SIZE) % HISTORY_SIZE;
570 							if (historyLine == sCurrentLine)
571 								break;
572 
573 							if (strncmp(sLineBuffer[historyLine], buffer,
574 									position) == 0) {
575 								found = true;
576 							}
577 						} while (!found);
578 
579 						// bail out, if we've found nothing or hit an empty
580 						// (i.e. unused) history line
581 						if (!found || strlen(sLineBuffer[historyLine]) == 0)
582 							break;
583 
584 						// found a suitable line -- replace the current buffer
585 						// content with it
586 						strcpy(buffer, sLineBuffer[historyLine]);
587 						length = strlen(buffer);
588 						kprintf("%s\x1b[K", buffer + position);
589 							// print the line and clear the rest
590 						kprintf("\x1b[%ldD", length - position);
591 							// reposition cursor
592 						currentHistoryLine = historyLine;
593 
594 						break;
595 					}
596 					case 'H': // home
597 					{
598 						if (position > 0) {
599 							kprintf("\x1b[%ldD", position);
600 							position = 0;
601 						}
602 						break;
603 					}
604 					case 'F': // end
605 					{
606 						if (position < length) {
607 							kprintf("\x1b[%ldC", length - position);
608 							position = length;
609 						}
610 						break;
611 					}
612 					case '3':	// if "3~", it's DEL
613 					{
614 						if (kgetc() != '~')
615 							break;
616 
617 						if (position < length)
618 							remove_char_from_line(buffer, position, length);
619 
620 						break;
621 					}
622 					default:
623 						break;
624 				}
625 				break;
626 			case '$':
627 			case '+':
628 				if (!sBlueScreenOutput) {
629 					/* HACK ALERT!!!
630 					 *
631 					 * If we get a $ at the beginning of the line
632 					 * we assume we are talking with GDB
633 					 */
634 					if (position == 0) {
635 						strcpy(buffer, "gdb");
636 						position = 4;
637 						done = true;
638 						break;
639 					}
640 				}
641 				/* supposed to fall through */
642 			default:
643 				if (isprint(c))
644 					insert_char_into_line(buffer, position, length, c);
645 				break;
646 		}
647 
648 		if (length >= maxLength - 2) {
649 			buffer[length++] = '\0';
650 			kputchar('\n');
651 			done = true;
652 			break;
653 		}
654 	}
655 
656 	return length;
657 }
658 
659 
660 char
661 kgetc(void)
662 {
663 	// give the kernel debugger modules a chance first
664 	for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
665 		if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_getchar) {
666 			int getChar = sDebuggerModules[i]->debugger_getchar();
667 			if (getChar >= 0)
668 				return (char)getChar;
669 		}
670 	}
671 
672 	if (sBlueScreenOutput)
673 		return blue_screen_getchar();
674 
675 	return arch_debug_serial_getchar();
676 }
677 
678 
679 int
680 kgets(char* buffer, int length)
681 {
682 	return read_line(buffer, length);
683 }
684 
685 
686 static void
687 kernel_debugger_loop(const char* message, int32 cpu)
688 {
689 	int32 previousCPU = sDebuggerOnCPU;
690 	sDebuggerOnCPU = cpu;
691 
692 	DebugAllocPool* allocPool = create_debug_alloc_pool();
693 
694 	sCurrentKernelDebuggerMessage = message;
695 
696 	if (message)
697 		kprintf("PANIC: %s\n", message);
698 
699 	kprintf("Welcome to Kernel Debugging Land...\n");
700 
701 	// Set a few temporary debug variables and print on which CPU and in which
702 	// thread we are running.
703 	set_debug_variable("_cpu", sDebuggerOnCPU);
704 
705 	struct thread* thread = thread_get_current_thread();
706 	if (thread == NULL) {
707 		kprintf("Running on CPU %ld\n", sDebuggerOnCPU);
708 	} else if (!debug_is_kernel_memory_accessible((addr_t)thread,
709 			sizeof(struct thread), B_KERNEL_READ_AREA)) {
710 		kprintf("Running on CPU %ld\n", sDebuggerOnCPU);
711 		kprintf("Current thread pointer is %p, which is an address we "
712 			"can't read from.\n", thread);
713 		arch_debug_unset_current_thread();
714 	} else {
715 		set_debug_variable("_thread", (uint64)(addr_t)thread);
716 		set_debug_variable("_threadID", thread->id);
717 
718 		kprintf("Thread %ld \"%.64s\" running on CPU %ld\n", thread->id,
719 			thread->name, sDebuggerOnCPU);
720 
721 		if (thread->cpu != gCPU + cpu) {
722 			kprintf("The thread's CPU pointer is %p, but should be %p.\n",
723 				thread->cpu, gCPU + cpu);
724 			arch_debug_unset_current_thread();
725 		} else if (thread->team != NULL) {
726 			if (debug_is_kernel_memory_accessible((addr_t)thread->team,
727 					sizeof(struct team), B_KERNEL_READ_AREA)) {
728 				set_debug_variable("_team", (uint64)(addr_t)thread->team);
729 				set_debug_variable("_teamID", thread->team->id);
730 			} else {
731 				kprintf("The thread's team pointer is %p, which is an "
732 					"address we can't read from.\n", thread->team);
733 				arch_debug_unset_current_thread();
734 			}
735 		}
736 	}
737 
738 	if (!has_debugger_command("help"))
739 		arch_debug_stack_trace();
740 
741 	int32 continuableLine = -1;
742 		// Index of the previous command line, if the command returned
743 		// B_KDEBUG_CONT, i.e. asked to be repeatable, -1 otherwise.
744 
745 	for (;;) {
746 		CommandLineEditingHelper editingHelper;
747 		kprintf(kKDLPrompt);
748 		char* line = sLineBuffer[sCurrentLine];
749 		read_line(line, LINE_BUFFER_SIZE, &editingHelper);
750 
751 		// check, if the line is empty or whitespace only
752 		bool whiteSpaceOnly = true;
753 		for (int i = 0 ; line[i] != '\0'; i++) {
754 			if (!isspace(line[i])) {
755 				whiteSpaceOnly = false;
756 				break;
757 			}
758 		}
759 
760 		if (whiteSpaceOnly) {
761 			if (continuableLine < 0)
762 				continue;
763 
764 			// the previous command can be repeated
765 			sCurrentLine = continuableLine;
766 			line = sLineBuffer[sCurrentLine];
767 		}
768 
769 		int rc = evaluate_debug_command(line);
770 
771 		if (rc == B_KDEBUG_QUIT) {
772 			// okay, exit now.
773 			break;
774 		}
775 
776 		// If the command is continuable, remember the current line index.
777 		continuableLine = (rc == B_KDEBUG_CONT ? sCurrentLine : -1);
778 
779 		int previousLine = sCurrentLine - 1;
780 		if (previousLine < 0)
781 			previousLine = HISTORY_SIZE - 1;
782 
783 		// Only use the next slot in the history, if the entries differ
784 		if (strcmp(sLineBuffer[sCurrentLine], sLineBuffer[previousLine])) {
785 			if (++sCurrentLine >= HISTORY_SIZE)
786 				sCurrentLine = 0;
787 		}
788 	}
789 
790 	delete_debug_alloc_pool(allocPool);
791 
792 	sDebuggerOnCPU = previousCPU;
793 }
794 
795 
796 static void
797 enter_kernel_debugger(int32 cpu)
798 {
799 	while (atomic_add(&sInDebugger, 1) > 0) {
800 		// The debugger is already running, find out where...
801 		if (sDebuggerOnCPU == cpu) {
802 			// We are re-entering the debugger on the same CPU.
803 			break;
804 		}
805 
806 		// Some other CPU must have entered the debugger and tried to halt
807 		// us. Process ICIs to ensure we get the halt request. Then we are
808 		// blocking there until everyone leaves the debugger and we can
809 		// try to enter it again.
810 		atomic_add(&sInDebugger, -1);
811 		smp_intercpu_int_handler(cpu);
812 	}
813 
814 	arch_debug_save_registers(&dbg_register_file[cpu][0]);
815 	sPreviousDprintfState = set_dprintf_enabled(true);
816 
817 	if (!gKernelStartup && sDebuggerOnCPU != cpu && smp_get_num_cpus() > 1) {
818 		// First entry on a MP system, send a halt request to all of the other
819 		// CPUs. Should they try to enter the debugger they will be cought in
820 		// the loop above.
821 		smp_send_broadcast_ici_interrupts_disabled(cpu, SMP_MSG_CPU_HALT, 0, 0,
822 			0, NULL, SMP_MSG_FLAG_SYNC);
823 	}
824 
825 	if (sBlueScreenOutput) {
826 		if (blue_screen_enter(false) == B_OK)
827 			sBlueScreenEnabled = true;
828 	}
829 
830 	sDebugOutputFilter = &gDefaultDebugOutputFilter;
831 
832 	sDebuggedThread = NULL;
833 
834 	// sort the commands
835 	sort_debugger_commands();
836 
837 	call_modules_hook(true);
838 }
839 
840 
841 static void
842 exit_kernel_debugger()
843 {
844 	call_modules_hook(false);
845 	set_dprintf_enabled(sPreviousDprintfState);
846 
847 	sDebugOutputFilter = NULL;
848 
849 	sBlueScreenEnabled = false;
850 	if (sDebugScreenEnabled)
851 		blue_screen_enter(true);
852 
853 	atomic_add(&sInDebugger, -1);
854 }
855 
856 
857 static void
858 hand_over_kernel_debugger()
859 {
860 	// Wait until the hand-over is complete.
861 	// The other CPU gets our sInDebugger reference and will release it when
862 	// done. Note, that there's a small race condition: the other CPU could
863 	// hand over to another CPU without us noticing. Since this is only
864 	// initiated by the user, it is harmless, though.
865 	sHandOverKDL = true;
866 	while (sHandOverKDLToCPU >= 0)
867 		PAUSE();
868 }
869 
870 
871 static void
872 kernel_debugger_internal(const char* message, int32 cpu)
873 {
874 	while (true) {
875 		if (sHandOverKDLToCPU == cpu) {
876 			sHandOverKDLToCPU = -1;
877 			sHandOverKDL = false;
878 		} else
879 			enter_kernel_debugger(cpu);
880 
881 		kernel_debugger_loop(message, cpu);
882 
883 		if (sHandOverKDLToCPU < 0) {
884 			exit_kernel_debugger();
885 			break;
886 		}
887 
888 		hand_over_kernel_debugger();
889 
890 		debug_trap_cpu_in_kdl(cpu, true);
891 
892 		if (sHandOverKDLToCPU != cpu)
893 			break;
894 	}
895 }
896 
897 
898 static int
899 cmd_dump_kdl_message(int argc, char** argv)
900 {
901 	if (sCurrentKernelDebuggerMessage) {
902 		kputs(sCurrentKernelDebuggerMessage);
903 		kputs("\n");
904 	}
905 
906 	return 0;
907 }
908 
909 
910 static int
911 cmd_dump_syslog(int argc, char** argv)
912 {
913 	if (!sSyslogOutputEnabled) {
914 		kprintf("Syslog is not enabled.\n");
915 		return 0;
916 	}
917 
918 	bool currentOnly = false;
919 	if (argc > 1) {
920 		if (!strcmp(argv[1], "-n"))
921 			currentOnly = true;
922 		else {
923 			print_debugger_command_usage(argv[0]);
924 			return 0;
925 		}
926 	}
927 
928 	uint32 start = sSyslogBuffer->first;
929 	size_t end = start + sSyslogBuffer->in;
930 	if (!currentOnly) {
931 		// Start the buffer after the current end (we don't really know if
932 		// this part has been written to already).
933 		start = (start + sSyslogBuffer->in) % sSyslogBuffer->size;
934 		end = start + sSyslogBuffer->size;
935 	} else if (!ring_buffer_readable(sSyslogBuffer)) {
936 		kprintf("Syslog is empty.\n");
937 		return 0;
938 	}
939 
940 	// break it down to lines to make it grep'able
941 
942 	bool newLine = false;
943 	char line[256];
944 	size_t linePos = 0;
945 	for (uint32 i = start; i < end; i++) {
946 		char c = sSyslogBuffer->buffer[i % sSyslogBuffer->size];
947 		if (c == '\0' || (uint8)c == 0xcc)
948 			continue;
949 
950 		line[linePos++] = c;
951 		newLine = false;
952 
953 		if (c == '\n' || linePos == sizeof(line) - 1) {
954 			newLine = c == '\n';
955 			line[linePos] = '\0';
956 			linePos = 0;
957 			kprintf(line);
958 		}
959 	}
960 	if (!newLine)
961 		kprintf("\n");
962 
963 	return 0;
964 }
965 
966 
967 static int
968 cmd_switch_cpu(int argc, char** argv)
969 {
970 	if (argc > 2) {
971 		print_debugger_command_usage(argv[0]);
972 		return 0;
973 	}
974 
975 	if (argc == 1) {
976 		kprintf("running on CPU %ld\n", smp_get_current_cpu());
977 		return 0;
978 	}
979 
980 	int32 newCPU = parse_expression(argv[1]);
981 	if (newCPU < 0 || newCPU >= smp_get_num_cpus()) {
982 		kprintf("invalid CPU index\n");
983 		return 0;
984 	}
985 
986 	if (newCPU == smp_get_current_cpu()) {
987 		kprintf("already running on CPU %ld\n", newCPU);
988 		return 0;
989 	}
990 
991 	sHandOverKDLToCPU = newCPU;
992 
993 	return B_KDEBUG_QUIT;
994 }
995 
996 
997 static status_t
998 syslog_sender(void* data)
999 {
1000 	status_t error = B_BAD_PORT_ID;
1001 	port_id port = -1;
1002 	bool bufferPending = false;
1003 	int32 length = 0;
1004 
1005 	while (true) {
1006 		// wait for syslog data to become available
1007 		acquire_sem(sSyslogNotify);
1008 
1009 		sSyslogMessage->when = real_time_clock();
1010 
1011 		if (error == B_BAD_PORT_ID) {
1012 			// last message couldn't be sent, try to locate the syslog_daemon
1013 			port = find_port(SYSLOG_PORT_NAME);
1014 		}
1015 
1016 		if (port >= B_OK) {
1017 			if (!bufferPending) {
1018 				// we need to have exclusive access to our syslog buffer
1019 				cpu_status state = disable_interrupts();
1020 				acquire_spinlock(&sSpinlock);
1021 
1022 				length = ring_buffer_readable(sSyslogBuffer);
1023 				if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH)
1024 					length = SYSLOG_MAX_MESSAGE_LENGTH;
1025 
1026 				length = ring_buffer_read(sSyslogBuffer,
1027 					(uint8*)sSyslogMessage->message, length);
1028 				if (sSyslogDropped) {
1029 					// Add drop marker - since parts had to be dropped, it's
1030 					// guaranteed that we have enough space in the buffer now.
1031 					ring_buffer_write(sSyslogBuffer, (uint8*)"<DROP>", 6);
1032 					sSyslogDropped = false;
1033 				}
1034 
1035 				release_spinlock(&sSpinlock);
1036 				restore_interrupts(state);
1037 			}
1038 
1039 			if (length == 0) {
1040 				// the buffer we came here for might have been sent already
1041 				bufferPending = false;
1042 				continue;
1043 			}
1044 
1045 			error = write_port_etc(port, SYSLOG_MESSAGE, sSyslogMessage,
1046 				sizeof(struct syslog_message) + length, B_RELATIVE_TIMEOUT, 0);
1047 
1048 			if (error < B_OK) {
1049 				// sending has failed - just wait, maybe it'll work later.
1050 				bufferPending = true;
1051 				continue;
1052 			}
1053 
1054 			if (bufferPending) {
1055 				// we could write the last pending buffer, try to read more
1056 				// from the syslog ring buffer
1057 				release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE);
1058 				bufferPending = false;
1059 			}
1060 		}
1061 	}
1062 
1063 	return 0;
1064 }
1065 
1066 
1067 static void
1068 syslog_write(const char* text, int32 length)
1069 {
1070 	bool trunc = false;
1071 
1072 	if (sSyslogBuffer == NULL)
1073 		return;
1074 
1075 	if ((int32)ring_buffer_writable(sSyslogBuffer) < length) {
1076 		// truncate data
1077 		length = ring_buffer_writable(sSyslogBuffer);
1078 
1079 		if (length > 8) {
1080 			trunc = true;
1081 			length -= 8;
1082 		} else
1083 			sSyslogDropped = true;
1084 	}
1085 
1086 	ring_buffer_write(sSyslogBuffer, (uint8*)text, length);
1087 	if (trunc)
1088 		ring_buffer_write(sSyslogBuffer, (uint8*)"<TRUNC>", 7);
1089 
1090 	release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE);
1091 }
1092 
1093 
1094 static status_t
1095 syslog_init_post_threads(void)
1096 {
1097 	if (!sSyslogOutputEnabled)
1098 		return B_OK;
1099 
1100 	sSyslogNotify = create_sem(0, "syslog data");
1101 	if (sSyslogNotify >= B_OK) {
1102 		thread_id thread = spawn_kernel_thread(syslog_sender, "syslog sender",
1103 			B_LOW_PRIORITY, NULL);
1104 		if (thread >= B_OK && resume_thread(thread) == B_OK)
1105 			return B_OK;
1106 	}
1107 
1108 	// initializing kernel syslog service failed -- disable it
1109 
1110 	sSyslogOutputEnabled = false;
1111 	free(sSyslogMessage);
1112 	free(sSyslogBuffer);
1113 	delete_sem(sSyslogNotify);
1114 
1115 	return B_ERROR;
1116 }
1117 
1118 
1119 static status_t
1120 syslog_init(struct kernel_args* args)
1121 {
1122 	status_t status;
1123 	int32 length = 0;
1124 
1125 	if (!sSyslogOutputEnabled)
1126 		return B_OK;
1127 
1128 	sSyslogMessage = (syslog_message*)malloc(SYSLOG_MESSAGE_BUFFER_SIZE);
1129 	if (sSyslogMessage == NULL) {
1130 		status = B_NO_MEMORY;
1131 		goto err1;
1132 	}
1133 
1134 	{
1135 		size_t bufferSize = DEFAULT_SYSLOG_BUFFER_SIZE;
1136 		void* handle = load_driver_settings("kernel");
1137 		if (handle != NULL) {
1138 			const char* sizeString = get_driver_parameter(handle,
1139 				"syslog_buffer_size", NULL, NULL);
1140 			if (sizeString != NULL) {
1141 				bufferSize = strtoul(sizeString, NULL, 0);
1142 				if (bufferSize > 262144)
1143 					bufferSize = 262144;
1144 				else if (bufferSize < SYSLOG_MESSAGE_BUFFER_SIZE)
1145 					bufferSize = SYSLOG_MESSAGE_BUFFER_SIZE;
1146 			}
1147 
1148 			unload_driver_settings(handle);
1149 		}
1150 
1151 		sSyslogBuffer = create_ring_buffer(bufferSize);
1152 	}
1153 	if (sSyslogBuffer == NULL) {
1154 		status = B_NO_MEMORY;
1155 		goto err2;
1156 	}
1157 
1158 	// initialize syslog message
1159 	sSyslogMessage->from = 0;
1160 	sSyslogMessage->options = LOG_KERN;
1161 	sSyslogMessage->priority = LOG_DEBUG;
1162 	sSyslogMessage->ident[0] = '\0';
1163 	//strcpy(sSyslogMessage->ident, "KERNEL");
1164 
1165 	if (args->debug_output != NULL)
1166 		syslog_write((const char*)args->debug_output, args->debug_size);
1167 
1168 	char revisionBuffer[64];
1169 	length = snprintf(revisionBuffer, sizeof(revisionBuffer),
1170 		"Welcome to syslog debug output!\nHaiku revision: %lu\n",
1171 		get_haiku_revision());
1172 	syslog_write(revisionBuffer, length);
1173 
1174 	add_debugger_command_etc("syslog", &cmd_dump_syslog,
1175 		"Dumps the syslog buffer.",
1176 		"[-n]\nDumps the whole syslog buffer, or, if -n is specified, only "
1177 		"the part that hasn't been sent yet.\n", 0);
1178 
1179 	return B_OK;
1180 
1181 err2:
1182 	free(sSyslogMessage);
1183 err1:
1184 	sSyslogOutputEnabled = false;
1185 	return status;
1186 }
1187 
1188 
1189 static void
1190 debug_memcpy_trampoline(void* _parameters)
1191 {
1192 	debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters;
1193 	memcpy(parameters->to, parameters->from, parameters->size);
1194 }
1195 
1196 
1197 static void
1198 debug_strlcpy_trampoline(void* _parameters)
1199 {
1200 	debug_strlcpy_parameters* parameters
1201 		= (debug_strlcpy_parameters*)_parameters;
1202 	parameters->result = strlcpy(parameters->to, parameters->from,
1203 		parameters->size);
1204 }
1205 
1206 
1207 void
1208 call_modules_hook(bool enter)
1209 {
1210 	uint32 index = 0;
1211 	while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) {
1212 		debugger_module_info* module = sDebuggerModules[index];
1213 
1214 		if (enter && module->enter_debugger != NULL)
1215 			module->enter_debugger();
1216 		else if (!enter && module->exit_debugger != NULL)
1217 			module->exit_debugger();
1218 
1219 		index++;
1220 	}
1221 }
1222 
1223 
1224 //!	Must be called with the sSpinlock held.
1225 static void
1226 debug_output(const char* string, int32 length, bool syslogOutput)
1227 {
1228 	if (length >= OUTPUT_BUFFER_SIZE)
1229 		length = OUTPUT_BUFFER_SIZE - 1;
1230 
1231 	if (length > 1 && string[length - 1] == '\n'
1232 		&& strncmp(string, sLastOutputBuffer, length) == 0) {
1233 		sMessageRepeatCount++;
1234 		sMessageRepeatLastTime = system_time();
1235 		if (sMessageRepeatFirstTime == 0)
1236 			sMessageRepeatFirstTime = sMessageRepeatLastTime;
1237 	} else {
1238 		flush_pending_repeats(syslogOutput);
1239 
1240 		if (sSerialDebugEnabled)
1241 			arch_debug_serial_puts(string);
1242 		if (sSyslogOutputEnabled && syslogOutput)
1243 			syslog_write(string, length);
1244 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1245 			blue_screen_puts(string);
1246 		if (sSerialDebugEnabled) {
1247 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1248 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1249 					sDebuggerModules[i]->debugger_puts(string, length);
1250 			}
1251 		}
1252 
1253 		memcpy(sLastOutputBuffer, string, length);
1254 		sLastOutputBuffer[length] = 0;
1255 	}
1256 }
1257 
1258 
1259 //!	Must be called with the sSpinlock held.
1260 static void
1261 flush_pending_repeats(bool syslogOutput)
1262 {
1263 	if (sMessageRepeatCount <= 0)
1264 		return;
1265 
1266 	if (sMessageRepeatCount > 1) {
1267 		static char temp[40];
1268 		size_t length = snprintf(temp, sizeof(temp),
1269 			"Last message repeated %ld times.\n", sMessageRepeatCount);
1270 
1271 		if (sSerialDebugEnabled)
1272 			arch_debug_serial_puts(temp);
1273 		if (sSyslogOutputEnabled && syslogOutput)
1274 			syslog_write(temp, length);
1275 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1276 			blue_screen_puts(temp);
1277 		if (sSerialDebugEnabled) {
1278 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1279 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1280 					sDebuggerModules[i]->debugger_puts(temp, length);
1281 			}
1282 		}
1283 	} else {
1284 		// if we only have one repeat just reprint the last buffer
1285 		size_t length = strlen(sLastOutputBuffer);
1286 
1287 		if (sSerialDebugEnabled)
1288 			arch_debug_serial_puts(sLastOutputBuffer);
1289 		if (sSyslogOutputEnabled && syslogOutput)
1290 			syslog_write(sLastOutputBuffer, length);
1291 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1292 			blue_screen_puts(sLastOutputBuffer);
1293 		if (sSerialDebugEnabled) {
1294 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1295 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) {
1296 					sDebuggerModules[i]->debugger_puts(sLastOutputBuffer,
1297 						length);
1298 				}
1299 			}
1300 		}
1301 	}
1302 
1303 	sMessageRepeatFirstTime = 0;
1304 	sMessageRepeatCount = 0;
1305 }
1306 
1307 
1308 static void
1309 check_pending_repeats(void* /*data*/, int /*iteration*/)
1310 {
1311 	if (sMessageRepeatCount > 0
1312 		&& (system_time() - sMessageRepeatLastTime > 1000000
1313 			|| system_time() - sMessageRepeatFirstTime > 3000000)) {
1314 		cpu_status state = disable_interrupts();
1315 		acquire_spinlock(&sSpinlock);
1316 
1317 		flush_pending_repeats(true);
1318 
1319 		release_spinlock(&sSpinlock);
1320 		restore_interrupts(state);
1321 	}
1322 }
1323 
1324 
1325 static void
1326 dprintf_args(const char* format, va_list args, bool syslogOutput)
1327 {
1328 	if (are_interrupts_enabled()) {
1329 		MutexLocker locker(sOutputLock);
1330 
1331 		int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE,
1332 			format, args);
1333 
1334 		InterruptsSpinLocker _(sSpinlock);
1335 		debug_output(sOutputBuffer, length, syslogOutput);
1336 	} else {
1337 		InterruptsSpinLocker _(sSpinlock);
1338 
1339 		int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE,
1340 			format, args);
1341 
1342 		debug_output(sInterruptOutputBuffer, length, syslogOutput);
1343 	}
1344 }
1345 
1346 
1347 // #pragma mark - private kernel API
1348 
1349 
1350 bool
1351 debug_screen_output_enabled(void)
1352 {
1353 	return sDebugScreenEnabled;
1354 }
1355 
1356 
1357 void
1358 debug_stop_screen_debug_output(void)
1359 {
1360 	sDebugScreenEnabled = false;
1361 }
1362 
1363 
1364 bool
1365 debug_debugger_running(void)
1366 {
1367 	return sDebuggerOnCPU != -1;
1368 }
1369 
1370 
1371 void
1372 debug_puts(const char* string, int32 length)
1373 {
1374 	InterruptsSpinLocker _(sSpinlock);
1375 	debug_output(string, length, sSyslogOutputEnabled);
1376 }
1377 
1378 
1379 void
1380 debug_early_boot_message(const char* string)
1381 {
1382 	arch_debug_serial_early_boot_message(string);
1383 }
1384 
1385 
1386 status_t
1387 debug_init(kernel_args* args)
1388 {
1389 	new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter;
1390 
1391 	debug_paranoia_init();
1392 	return arch_debug_console_init(args);
1393 }
1394 
1395 
1396 status_t
1397 debug_init_post_vm(kernel_args* args)
1398 {
1399 	add_debugger_command_etc("cpu", &cmd_switch_cpu,
1400 		"Switches to another CPU.",
1401 		"<cpu>\n"
1402 		"Switches to CPU with the index <cpu>.\n", 0);
1403 	add_debugger_command_etc("message", &cmd_dump_kdl_message,
1404 		"Reprint the message printed when entering KDL",
1405 		"\n"
1406 		"Reprints the message printed when entering KDL.\n", 0);
1407 
1408 	debug_builtin_commands_init();
1409 
1410 	debug_heap_init();
1411 	debug_variables_init();
1412 	frame_buffer_console_init(args);
1413 	arch_debug_console_init_settings(args);
1414 	tracing_init();
1415 
1416 	// get debug settings
1417 
1418 	sSerialDebugEnabled = get_safemode_boolean("serial_debug_output",
1419 		sSerialDebugEnabled);
1420 	sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output",
1421 		sSyslogOutputEnabled);
1422 	sBlueScreenOutput = get_safemode_boolean("bluescreen", true);
1423 	sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys",
1424 		sEmergencyKeysEnabled);
1425 	sDebugScreenEnabled = get_safemode_boolean("debug_screen", false);
1426 
1427 	if ((sBlueScreenOutput || sDebugScreenEnabled)
1428 		&& blue_screen_init() != B_OK)
1429 		sBlueScreenOutput = sDebugScreenEnabled = false;
1430 
1431 	if (sDebugScreenEnabled)
1432 		blue_screen_enter(true);
1433 
1434 	syslog_init(args);
1435 
1436 	return arch_debug_init(args);
1437 }
1438 
1439 
1440 status_t
1441 debug_init_post_modules(struct kernel_args* args)
1442 {
1443 	void* cookie;
1444 
1445 	// check for dupped lines every 10/10 second
1446 	register_kernel_daemon(check_pending_repeats, NULL, 10);
1447 
1448 	syslog_init_post_threads();
1449 
1450 	// load kernel debugger addons
1451 
1452 	static const char* kDemanglePrefix = "debugger/demangle/";
1453 
1454 	cookie = open_module_list("debugger");
1455 	uint32 count = 0;
1456 	while (count < kMaxDebuggerModules) {
1457 		char name[B_FILE_NAME_LENGTH];
1458 		size_t nameLength = sizeof(name);
1459 
1460 		if (read_next_module_name(cookie, name, &nameLength) != B_OK)
1461 			break;
1462 
1463 		// get demangle module, if any
1464 		if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) {
1465 			if (sDemangleModule == NULL)
1466 				get_module(name, (module_info**)&sDemangleModule);
1467 			continue;
1468 		}
1469 
1470 		if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) {
1471 			dprintf("kernel debugger extension \"%s\": loaded\n", name);
1472 			count++;
1473 		} else
1474 			dprintf("kernel debugger extension \"%s\": failed to load\n", name);
1475 	}
1476 	close_module_list(cookie);
1477 
1478 	return frame_buffer_console_init_post_modules(args);
1479 }
1480 
1481 
1482 void
1483 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags)
1484 {
1485 	sPageFaultInfo.fault_address = faultAddress;
1486 	sPageFaultInfo.pc = pc;
1487 	sPageFaultInfo.flags = flags;
1488 }
1489 
1490 
1491 debug_page_fault_info*
1492 debug_get_page_fault_info()
1493 {
1494 	return &sPageFaultInfo;
1495 }
1496 
1497 
1498 void
1499 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
1500 {
1501 	InterruptsLocker locker;
1502 
1503 	// return, if we've been called recursively (we call
1504 	// smp_intercpu_int_handler() below)
1505 	if (sCPUTrapped[cpu])
1506 		return;
1507 
1508 	sCPUTrapped[cpu] = true;
1509 
1510 	while (sInDebugger != 0) {
1511 		if (sHandOverKDL && sHandOverKDLToCPU == cpu) {
1512 			if (returnIfHandedOver)
1513 				break;
1514 
1515 			kernel_debugger_internal(NULL, cpu);
1516 		} else
1517 			smp_intercpu_int_handler(cpu);
1518 	}
1519 
1520 	sCPUTrapped[cpu] = false;
1521 }
1522 
1523 
1524 void
1525 debug_double_fault(int32 cpu)
1526 {
1527 	kernel_debugger_internal("Double Fault!\n", cpu);
1528 }
1529 
1530 
1531 bool
1532 debug_emergency_key_pressed(char key)
1533 {
1534 	if (!sEmergencyKeysEnabled)
1535 		return false;
1536 
1537 	if (key == 'd') {
1538 		kernel_debugger("Keyboard Requested Halt.");
1539 		return true;
1540 	}
1541 
1542 	// Broadcast to the kernel debugger modules
1543 
1544 	for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1545 		if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) {
1546 			if (sDebuggerModules[i]->emergency_key_pressed(key))
1547 				return true;
1548 		}
1549 	}
1550 
1551 	return false;
1552 }
1553 
1554 
1555 /*!	Verifies that the complete given memory range is accessible in the current
1556 	context.
1557 
1558 	Invoked in the kernel debugger only.
1559 
1560 	\param address The start address of the memory range to be checked.
1561 	\param size The size of the memory range to be checked.
1562 	\param protection The area protection for which to check. Valid is a bitwise
1563 		or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA.
1564 	\return \c true, if the complete memory range can be accessed in all ways
1565 		specified by \a protection, \c false otherwise.
1566 */
1567 bool
1568 debug_is_kernel_memory_accessible(addr_t address, size_t size,
1569 	uint32 protection)
1570 {
1571 	addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE);
1572 	address = ROUNDDOWN(address, B_PAGE_SIZE);
1573 
1574 	if (!IS_KERNEL_ADDRESS(address) || endAddress < address)
1575 		return false;
1576 
1577 	for (; address < endAddress; address += B_PAGE_SIZE) {
1578 		if (!arch_vm_translation_map_is_kernel_page_accessible(address,
1579 				protection)) {
1580 			return false;
1581 		}
1582 	}
1583 
1584 	return true;
1585 }
1586 
1587 
1588 /*!	Calls a function in a setjmp() + fault handler context.
1589 	May only be used in the kernel debugger.
1590 
1591 	\param jumpBuffer Buffer to be used for setjmp()/longjmp().
1592 	\param function The function to be called.
1593 	\param parameter The parameter to be passed to the function to be called.
1594 	\return
1595 		- \c 0, when the function executed without causing a page fault or
1596 		  calling longjmp().
1597 		- \c 1, when the function caused a page fault.
1598 		- Any other value the function passes to longjmp().
1599 */
1600 int
1601 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*),
1602 	void* parameter)
1603 {
1604 	// save current fault handler
1605 	cpu_ent* cpu = gCPU + sDebuggerOnCPU;
1606 	addr_t oldFaultHandler = cpu->fault_handler;
1607 	addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer;
1608 
1609 	int result = setjmp(jumpBuffer);
1610 	if (result == 0) {
1611 		arch_debug_call_with_fault_handler(cpu, jumpBuffer, function,
1612 			parameter);
1613 	}
1614 
1615 	// restore old fault handler
1616 	cpu->fault_handler = oldFaultHandler;
1617 	cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer;
1618 
1619 	return result;
1620 }
1621 
1622 
1623 /*!	Similar to user_memcpy(), but can only be invoked from within the kernel
1624 	debugger (and must not be used outside).
1625 */
1626 status_t
1627 debug_memcpy(void* to, const void* from, size_t size)
1628 {
1629 	// don't allow address overflows
1630 	if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to)
1631 		return B_BAD_ADDRESS;
1632 
1633 	debug_memcpy_parameters parameters = {to, from, size};
1634 
1635 	if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1636 			&debug_memcpy_trampoline, &parameters) != 0) {
1637 		return B_BAD_ADDRESS;
1638 	}
1639 	return B_OK;
1640 }
1641 
1642 
1643 /*!	Similar to user_strlcpy(), but can only be invoked from within the kernel
1644 	debugger (and must not be used outside).
1645 */
1646 ssize_t
1647 debug_strlcpy(char* to, const char* from, size_t size)
1648 {
1649 	if (size == 0)
1650 		return 0;
1651 	if (from == NULL || to == NULL)
1652 		return B_BAD_ADDRESS;
1653 
1654 	// limit size to avoid address overflows
1655 	size_t maxSize = std::min(size,
1656 		~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1);
1657 		// NOTE: Since strlcpy() determines the length of \a from, the source
1658 		// address might still overflow.
1659 
1660 	debug_strlcpy_parameters parameters = {to, from, maxSize};
1661 
1662 	if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1663 			&debug_strlcpy_trampoline, &parameters) != 0) {
1664 		return B_BAD_ADDRESS;
1665 	}
1666 
1667 	// If we hit the address overflow boundary, fail.
1668 	if (parameters.result >= maxSize && maxSize < size)
1669 		return B_BAD_ADDRESS;
1670 
1671 	return parameters.result;
1672 }
1673 
1674 
1675 // #pragma mark - public API
1676 
1677 
1678 uint64
1679 parse_expression(const char* expression)
1680 {
1681 	uint64 result;
1682 	return evaluate_debug_expression(expression, &result, true) ? result : 0;
1683 }
1684 
1685 
1686 void
1687 panic(const char* format, ...)
1688 {
1689 	va_list args;
1690 	char temp[128];
1691 
1692 	va_start(args, format);
1693 	vsnprintf(temp, sizeof(temp), format, args);
1694 	va_end(args);
1695 
1696 	kernel_debugger(temp);
1697 }
1698 
1699 
1700 void
1701 kernel_debugger(const char* message)
1702 {
1703 	cpu_status state = disable_interrupts();
1704 
1705 	kernel_debugger_internal(message, smp_get_current_cpu());
1706 
1707 	restore_interrupts(state);
1708 }
1709 
1710 
1711 bool
1712 set_dprintf_enabled(bool newState)
1713 {
1714 	bool oldState = sSerialDebugEnabled;
1715 	sSerialDebugEnabled = newState;
1716 
1717 	return oldState;
1718 }
1719 
1720 
1721 void
1722 dprintf(const char* format, ...)
1723 {
1724 	va_list args;
1725 
1726 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
1727 		return;
1728 
1729 	va_start(args, format);
1730 	dprintf_args(format, args, sSyslogOutputEnabled);
1731 	va_end(args);
1732 }
1733 
1734 
1735 void
1736 dprintf_no_syslog(const char* format, ...)
1737 {
1738 	va_list args;
1739 
1740 	if (!sSerialDebugEnabled && !sBlueScreenEnabled)
1741 		return;
1742 
1743 	va_start(args, format);
1744 	dprintf_args(format, args, false);
1745 	va_end(args);
1746 }
1747 
1748 
1749 /*!	Similar to dprintf() but thought to be used in the kernel
1750 	debugger only (it doesn't lock).
1751 */
1752 void
1753 kprintf(const char* format, ...)
1754 {
1755 	if (sDebugOutputFilter != NULL) {
1756 		va_list args;
1757 		va_start(args, format);
1758 		sDebugOutputFilter->Print(format, args);
1759 		va_end(args);
1760 	}
1761 }
1762 
1763 
1764 void
1765 kprintf_unfiltered(const char* format, ...)
1766 {
1767 	va_list args;
1768 	va_start(args, format);
1769 	gDefaultDebugOutputFilter.Print(format, args);
1770 	va_end(args);
1771 }
1772 
1773 
1774 const char*
1775 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize,
1776 	bool* _isObjectMethod)
1777 {
1778 	if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) {
1779 		return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize,
1780 			_isObjectMethod);
1781 	}
1782 
1783 	if (_isObjectMethod != NULL)
1784 		*_isObjectMethod = false;
1785 
1786 	return symbol;
1787 }
1788 
1789 
1790 status_t
1791 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol,
1792 	char* name, size_t nameSize, int32* _type, size_t* _argumentLength)
1793 {
1794 	if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) {
1795 		return sDemangleModule->get_next_argument(_cookie, symbol, name,
1796 			nameSize, _type, _argumentLength);
1797 	}
1798 
1799 	return B_NOT_SUPPORTED;
1800 }
1801 
1802 
1803 struct thread*
1804 debug_set_debugged_thread(struct thread* thread)
1805 {
1806 	struct thread* previous = sDebuggedThread;
1807 	sDebuggedThread = thread;
1808 	return previous;
1809 }
1810 
1811 
1812 struct thread*
1813 debug_get_debugged_thread()
1814 {
1815 	return sDebuggedThread != NULL
1816 		? sDebuggedThread : thread_get_current_thread();
1817 }
1818 
1819 
1820 //	#pragma mark -
1821 //	userland syscalls
1822 
1823 
1824 status_t
1825 _user_kernel_debugger(const char *userMessage)
1826 {
1827 	if (geteuid() != 0)
1828 		return B_NOT_ALLOWED;
1829 
1830 	char message[512];
1831 	strcpy(message, "USER: ");
1832 	size_t len = strlen(message);
1833 
1834 	if (userMessage == NULL || !IS_USER_ADDRESS(userMessage)
1835 		|| 	user_strlcpy(message + len, userMessage, sizeof(message) - len)
1836 			< 0) {
1837 		return B_BAD_ADDRESS;
1838 	}
1839 
1840 	kernel_debugger(message);
1841 	return B_OK;
1842 }
1843 
1844 
1845 void
1846 _user_debug_output(const char* userString)
1847 {
1848 	char string[512];
1849 	int32 length;
1850 
1851 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled)
1852 		return;
1853 
1854 	if (!IS_USER_ADDRESS(userString))
1855 		return;
1856 
1857 	do {
1858 		length = user_strlcpy(string, userString, sizeof(string));
1859 		debug_puts(string, length);
1860 		userString += sizeof(string) - 1;
1861 	} while (length >= (ssize_t)sizeof(string));
1862 }
1863 
1864 
1865 void
1866 dump_block(const char* buffer, int size, const char* prefix)
1867 {
1868 	const int DUMPED_BLOCK_SIZE = 16;
1869 	int i;
1870 
1871 	for (i = 0; i < size;) {
1872 		int start = i;
1873 
1874 		dprintf("%s%04x ", prefix, i);
1875 		for (; i < start + DUMPED_BLOCK_SIZE; i++) {
1876 			if (!(i % 4))
1877 				dprintf(" ");
1878 
1879 			if (i >= size)
1880 				dprintf("  ");
1881 			else
1882 				dprintf("%02x", *(unsigned char*)(buffer + i));
1883 		}
1884 		dprintf("  ");
1885 
1886 		for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) {
1887 			if (i < size) {
1888 				char c = buffer[i];
1889 
1890 				if (c < 30)
1891 					dprintf(".");
1892 				else
1893 					dprintf("%c", c);
1894 			} else
1895 				break;
1896 		}
1897 		dprintf("\n");
1898 	}
1899 }
1900