xref: /haiku/src/system/kernel/debug/debug.cpp (revision 9760dcae2038d47442f4658c2575844c6cf92c40)
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/vm.h>
32 #include <vm/VMTranslationMap.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,
1173 		std::min(length, (ssize_t)sizeof(revisionBuffer) - 1));
1174 
1175 	add_debugger_command_etc("syslog", &cmd_dump_syslog,
1176 		"Dumps the syslog buffer.",
1177 		"[-n]\nDumps the whole syslog buffer, or, if -n is specified, only "
1178 		"the part that hasn't been sent yet.\n", 0);
1179 
1180 	return B_OK;
1181 
1182 err2:
1183 	free(sSyslogMessage);
1184 err1:
1185 	sSyslogOutputEnabled = false;
1186 	return status;
1187 }
1188 
1189 
1190 static void
1191 debug_memcpy_trampoline(void* _parameters)
1192 {
1193 	debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters;
1194 	memcpy(parameters->to, parameters->from, parameters->size);
1195 }
1196 
1197 
1198 static void
1199 debug_strlcpy_trampoline(void* _parameters)
1200 {
1201 	debug_strlcpy_parameters* parameters
1202 		= (debug_strlcpy_parameters*)_parameters;
1203 	parameters->result = strlcpy(parameters->to, parameters->from,
1204 		parameters->size);
1205 }
1206 
1207 
1208 void
1209 call_modules_hook(bool enter)
1210 {
1211 	uint32 index = 0;
1212 	while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) {
1213 		debugger_module_info* module = sDebuggerModules[index];
1214 
1215 		if (enter && module->enter_debugger != NULL)
1216 			module->enter_debugger();
1217 		else if (!enter && module->exit_debugger != NULL)
1218 			module->exit_debugger();
1219 
1220 		index++;
1221 	}
1222 }
1223 
1224 
1225 //!	Must be called with the sSpinlock held.
1226 static void
1227 debug_output(const char* string, int32 length, bool syslogOutput)
1228 {
1229 	if (length >= OUTPUT_BUFFER_SIZE)
1230 		length = OUTPUT_BUFFER_SIZE - 1;
1231 
1232 	if (length > 1 && string[length - 1] == '\n'
1233 		&& strncmp(string, sLastOutputBuffer, length) == 0) {
1234 		sMessageRepeatCount++;
1235 		sMessageRepeatLastTime = system_time();
1236 		if (sMessageRepeatFirstTime == 0)
1237 			sMessageRepeatFirstTime = sMessageRepeatLastTime;
1238 	} else {
1239 		flush_pending_repeats(syslogOutput);
1240 
1241 		if (sSerialDebugEnabled)
1242 			arch_debug_serial_puts(string);
1243 		if (sSyslogOutputEnabled && syslogOutput)
1244 			syslog_write(string, length);
1245 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1246 			blue_screen_puts(string);
1247 		if (sSerialDebugEnabled) {
1248 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1249 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1250 					sDebuggerModules[i]->debugger_puts(string, length);
1251 			}
1252 		}
1253 
1254 		memcpy(sLastOutputBuffer, string, length);
1255 		sLastOutputBuffer[length] = 0;
1256 	}
1257 }
1258 
1259 
1260 //!	Must be called with the sSpinlock held.
1261 static void
1262 flush_pending_repeats(bool syslogOutput)
1263 {
1264 	if (sMessageRepeatCount <= 0)
1265 		return;
1266 
1267 	if (sMessageRepeatCount > 1) {
1268 		static char temp[40];
1269 		size_t length = snprintf(temp, sizeof(temp),
1270 			"Last message repeated %ld times.\n", sMessageRepeatCount);
1271 		length = std::min(length, sizeof(temp) - 1);
1272 
1273 		if (sSerialDebugEnabled)
1274 			arch_debug_serial_puts(temp);
1275 		if (sSyslogOutputEnabled && syslogOutput)
1276 			syslog_write(temp, length);
1277 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1278 			blue_screen_puts(temp);
1279 		if (sSerialDebugEnabled) {
1280 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1281 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1282 					sDebuggerModules[i]->debugger_puts(temp, length);
1283 			}
1284 		}
1285 	} else {
1286 		// if we only have one repeat just reprint the last buffer
1287 		size_t length = strlen(sLastOutputBuffer);
1288 
1289 		if (sSerialDebugEnabled)
1290 			arch_debug_serial_puts(sLastOutputBuffer);
1291 		if (sSyslogOutputEnabled && syslogOutput)
1292 			syslog_write(sLastOutputBuffer, length);
1293 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1294 			blue_screen_puts(sLastOutputBuffer);
1295 		if (sSerialDebugEnabled) {
1296 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1297 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) {
1298 					sDebuggerModules[i]->debugger_puts(sLastOutputBuffer,
1299 						length);
1300 				}
1301 			}
1302 		}
1303 	}
1304 
1305 	sMessageRepeatFirstTime = 0;
1306 	sMessageRepeatCount = 0;
1307 }
1308 
1309 
1310 static void
1311 check_pending_repeats(void* /*data*/, int /*iteration*/)
1312 {
1313 	if (sMessageRepeatCount > 0
1314 		&& (system_time() - sMessageRepeatLastTime > 1000000
1315 			|| system_time() - sMessageRepeatFirstTime > 3000000)) {
1316 		cpu_status state = disable_interrupts();
1317 		acquire_spinlock(&sSpinlock);
1318 
1319 		flush_pending_repeats(true);
1320 
1321 		release_spinlock(&sSpinlock);
1322 		restore_interrupts(state);
1323 	}
1324 }
1325 
1326 
1327 static void
1328 dprintf_args(const char* format, va_list args, bool syslogOutput)
1329 {
1330 	if (are_interrupts_enabled()) {
1331 		MutexLocker locker(sOutputLock);
1332 
1333 		int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format,
1334 			args);
1335 		length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1336 
1337 		InterruptsSpinLocker _(sSpinlock);
1338 		debug_output(sOutputBuffer, length, syslogOutput);
1339 	} else {
1340 		InterruptsSpinLocker _(sSpinlock);
1341 
1342 		int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE,
1343 			format, args);
1344 		length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1345 
1346 		debug_output(sInterruptOutputBuffer, length, syslogOutput);
1347 	}
1348 }
1349 
1350 
1351 // #pragma mark - private kernel API
1352 
1353 
1354 bool
1355 debug_screen_output_enabled(void)
1356 {
1357 	return sDebugScreenEnabled;
1358 }
1359 
1360 
1361 void
1362 debug_stop_screen_debug_output(void)
1363 {
1364 	sDebugScreenEnabled = false;
1365 }
1366 
1367 
1368 bool
1369 debug_debugger_running(void)
1370 {
1371 	return sDebuggerOnCPU != -1;
1372 }
1373 
1374 
1375 void
1376 debug_puts(const char* string, int32 length)
1377 {
1378 	InterruptsSpinLocker _(sSpinlock);
1379 	debug_output(string, length, sSyslogOutputEnabled);
1380 }
1381 
1382 
1383 void
1384 debug_early_boot_message(const char* string)
1385 {
1386 	arch_debug_serial_early_boot_message(string);
1387 }
1388 
1389 
1390 status_t
1391 debug_init(kernel_args* args)
1392 {
1393 	new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter;
1394 
1395 	debug_paranoia_init();
1396 	return arch_debug_console_init(args);
1397 }
1398 
1399 
1400 status_t
1401 debug_init_post_vm(kernel_args* args)
1402 {
1403 	add_debugger_command_etc("cpu", &cmd_switch_cpu,
1404 		"Switches to another CPU.",
1405 		"<cpu>\n"
1406 		"Switches to CPU with the index <cpu>.\n", 0);
1407 	add_debugger_command_etc("message", &cmd_dump_kdl_message,
1408 		"Reprint the message printed when entering KDL",
1409 		"\n"
1410 		"Reprints the message printed when entering KDL.\n", 0);
1411 
1412 	debug_builtin_commands_init();
1413 
1414 	debug_heap_init();
1415 	debug_variables_init();
1416 	frame_buffer_console_init(args);
1417 	arch_debug_console_init_settings(args);
1418 	tracing_init();
1419 
1420 	// get debug settings
1421 
1422 	sSerialDebugEnabled = get_safemode_boolean("serial_debug_output",
1423 		sSerialDebugEnabled);
1424 	sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output",
1425 		sSyslogOutputEnabled);
1426 	sBlueScreenOutput = get_safemode_boolean("bluescreen", true);
1427 	sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys",
1428 		sEmergencyKeysEnabled);
1429 	sDebugScreenEnabled = get_safemode_boolean("debug_screen", false);
1430 
1431 	if ((sBlueScreenOutput || sDebugScreenEnabled)
1432 		&& blue_screen_init() != B_OK)
1433 		sBlueScreenOutput = sDebugScreenEnabled = false;
1434 
1435 	if (sDebugScreenEnabled)
1436 		blue_screen_enter(true);
1437 
1438 	syslog_init(args);
1439 
1440 	return arch_debug_init(args);
1441 }
1442 
1443 
1444 status_t
1445 debug_init_post_modules(struct kernel_args* args)
1446 {
1447 	void* cookie;
1448 
1449 	// check for dupped lines every 10/10 second
1450 	register_kernel_daemon(check_pending_repeats, NULL, 10);
1451 
1452 	syslog_init_post_threads();
1453 
1454 	// load kernel debugger addons
1455 
1456 	static const char* kDemanglePrefix = "debugger/demangle/";
1457 
1458 	cookie = open_module_list("debugger");
1459 	uint32 count = 0;
1460 	while (count < kMaxDebuggerModules) {
1461 		char name[B_FILE_NAME_LENGTH];
1462 		size_t nameLength = sizeof(name);
1463 
1464 		if (read_next_module_name(cookie, name, &nameLength) != B_OK)
1465 			break;
1466 
1467 		// get demangle module, if any
1468 		if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) {
1469 			if (sDemangleModule == NULL)
1470 				get_module(name, (module_info**)&sDemangleModule);
1471 			continue;
1472 		}
1473 
1474 		if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) {
1475 			dprintf("kernel debugger extension \"%s\": loaded\n", name);
1476 			count++;
1477 		} else
1478 			dprintf("kernel debugger extension \"%s\": failed to load\n", name);
1479 	}
1480 	close_module_list(cookie);
1481 
1482 	return frame_buffer_console_init_post_modules(args);
1483 }
1484 
1485 
1486 void
1487 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags)
1488 {
1489 	sPageFaultInfo.fault_address = faultAddress;
1490 	sPageFaultInfo.pc = pc;
1491 	sPageFaultInfo.flags = flags;
1492 }
1493 
1494 
1495 debug_page_fault_info*
1496 debug_get_page_fault_info()
1497 {
1498 	return &sPageFaultInfo;
1499 }
1500 
1501 
1502 void
1503 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
1504 {
1505 	InterruptsLocker locker;
1506 
1507 	// return, if we've been called recursively (we call
1508 	// smp_intercpu_int_handler() below)
1509 	if (sCPUTrapped[cpu])
1510 		return;
1511 
1512 	sCPUTrapped[cpu] = true;
1513 
1514 	while (sInDebugger != 0) {
1515 		if (sHandOverKDL && sHandOverKDLToCPU == cpu) {
1516 			if (returnIfHandedOver)
1517 				break;
1518 
1519 			kernel_debugger_internal(NULL, cpu);
1520 		} else
1521 			smp_intercpu_int_handler(cpu);
1522 	}
1523 
1524 	sCPUTrapped[cpu] = false;
1525 }
1526 
1527 
1528 void
1529 debug_double_fault(int32 cpu)
1530 {
1531 	kernel_debugger_internal("Double Fault!\n", cpu);
1532 }
1533 
1534 
1535 bool
1536 debug_emergency_key_pressed(char key)
1537 {
1538 	if (!sEmergencyKeysEnabled)
1539 		return false;
1540 
1541 	if (key == 'd') {
1542 		kernel_debugger("Keyboard Requested Halt.");
1543 		return true;
1544 	}
1545 
1546 	// Broadcast to the kernel debugger modules
1547 
1548 	for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1549 		if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) {
1550 			if (sDebuggerModules[i]->emergency_key_pressed(key))
1551 				return true;
1552 		}
1553 	}
1554 
1555 	return false;
1556 }
1557 
1558 
1559 /*!	Verifies that the complete given memory range is accessible in the current
1560 	context.
1561 
1562 	Invoked in the kernel debugger only.
1563 
1564 	\param address The start address of the memory range to be checked.
1565 	\param size The size of the memory range to be checked.
1566 	\param protection The area protection for which to check. Valid is a bitwise
1567 		or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA.
1568 	\return \c true, if the complete memory range can be accessed in all ways
1569 		specified by \a protection, \c false otherwise.
1570 */
1571 bool
1572 debug_is_kernel_memory_accessible(addr_t address, size_t size,
1573 	uint32 protection)
1574 {
1575 	addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE);
1576 	address = ROUNDDOWN(address, B_PAGE_SIZE);
1577 
1578 	if (!IS_KERNEL_ADDRESS(address) || endAddress < address)
1579 		return false;
1580 
1581 	for (; address < endAddress; address += B_PAGE_SIZE) {
1582 		if (!arch_vm_translation_map_is_kernel_page_accessible(address,
1583 				protection)) {
1584 			return false;
1585 		}
1586 	}
1587 
1588 	return true;
1589 }
1590 
1591 
1592 /*!	Calls a function in a setjmp() + fault handler context.
1593 	May only be used in the kernel debugger.
1594 
1595 	\param jumpBuffer Buffer to be used for setjmp()/longjmp().
1596 	\param function The function to be called.
1597 	\param parameter The parameter to be passed to the function to be called.
1598 	\return
1599 		- \c 0, when the function executed without causing a page fault or
1600 		  calling longjmp().
1601 		- \c 1, when the function caused a page fault.
1602 		- Any other value the function passes to longjmp().
1603 */
1604 int
1605 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*),
1606 	void* parameter)
1607 {
1608 	// save current fault handler
1609 	cpu_ent* cpu = gCPU + sDebuggerOnCPU;
1610 	addr_t oldFaultHandler = cpu->fault_handler;
1611 	addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer;
1612 
1613 	int result = setjmp(jumpBuffer);
1614 	if (result == 0) {
1615 		arch_debug_call_with_fault_handler(cpu, jumpBuffer, function,
1616 			parameter);
1617 	}
1618 
1619 	// restore old fault handler
1620 	cpu->fault_handler = oldFaultHandler;
1621 	cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer;
1622 
1623 	return result;
1624 }
1625 
1626 
1627 /*!	Similar to user_memcpy(), but can only be invoked from within the kernel
1628 	debugger (and must not be used outside).
1629 */
1630 status_t
1631 debug_memcpy(void* to, const void* from, size_t size)
1632 {
1633 	// don't allow address overflows
1634 	if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to)
1635 		return B_BAD_ADDRESS;
1636 
1637 	debug_memcpy_parameters parameters = {to, from, size};
1638 
1639 	if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1640 			&debug_memcpy_trampoline, &parameters) != 0) {
1641 		return B_BAD_ADDRESS;
1642 	}
1643 	return B_OK;
1644 }
1645 
1646 
1647 /*!	Similar to user_strlcpy(), but can only be invoked from within the kernel
1648 	debugger (and must not be used outside).
1649 */
1650 ssize_t
1651 debug_strlcpy(char* to, const char* from, size_t size)
1652 {
1653 	if (size == 0)
1654 		return 0;
1655 	if (from == NULL || to == NULL)
1656 		return B_BAD_ADDRESS;
1657 
1658 	// limit size to avoid address overflows
1659 	size_t maxSize = std::min(size,
1660 		~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1);
1661 		// NOTE: Since strlcpy() determines the length of \a from, the source
1662 		// address might still overflow.
1663 
1664 	debug_strlcpy_parameters parameters = {to, from, maxSize};
1665 
1666 	if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1667 			&debug_strlcpy_trampoline, &parameters) != 0) {
1668 		return B_BAD_ADDRESS;
1669 	}
1670 
1671 	// If we hit the address overflow boundary, fail.
1672 	if (parameters.result >= maxSize && maxSize < size)
1673 		return B_BAD_ADDRESS;
1674 
1675 	return parameters.result;
1676 }
1677 
1678 
1679 // #pragma mark - public API
1680 
1681 
1682 uint64
1683 parse_expression(const char* expression)
1684 {
1685 	uint64 result;
1686 	return evaluate_debug_expression(expression, &result, true) ? result : 0;
1687 }
1688 
1689 
1690 void
1691 panic(const char* format, ...)
1692 {
1693 	va_list args;
1694 	char temp[128];
1695 
1696 	va_start(args, format);
1697 	vsnprintf(temp, sizeof(temp), format, args);
1698 	va_end(args);
1699 
1700 	kernel_debugger(temp);
1701 }
1702 
1703 
1704 void
1705 kernel_debugger(const char* message)
1706 {
1707 	cpu_status state = disable_interrupts();
1708 
1709 	kernel_debugger_internal(message, smp_get_current_cpu());
1710 
1711 	restore_interrupts(state);
1712 }
1713 
1714 
1715 bool
1716 set_dprintf_enabled(bool newState)
1717 {
1718 	bool oldState = sSerialDebugEnabled;
1719 	sSerialDebugEnabled = newState;
1720 
1721 	return oldState;
1722 }
1723 
1724 
1725 void
1726 dprintf(const char* format, ...)
1727 {
1728 	va_list args;
1729 
1730 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
1731 		return;
1732 
1733 	va_start(args, format);
1734 	dprintf_args(format, args, sSyslogOutputEnabled);
1735 	va_end(args);
1736 }
1737 
1738 
1739 void
1740 dprintf_no_syslog(const char* format, ...)
1741 {
1742 	va_list args;
1743 
1744 	if (!sSerialDebugEnabled && !sBlueScreenEnabled)
1745 		return;
1746 
1747 	va_start(args, format);
1748 	dprintf_args(format, args, false);
1749 	va_end(args);
1750 }
1751 
1752 
1753 /*!	Similar to dprintf() but thought to be used in the kernel
1754 	debugger only (it doesn't lock).
1755 */
1756 void
1757 kprintf(const char* format, ...)
1758 {
1759 	if (sDebugOutputFilter != NULL) {
1760 		va_list args;
1761 		va_start(args, format);
1762 		sDebugOutputFilter->Print(format, args);
1763 		va_end(args);
1764 	}
1765 }
1766 
1767 
1768 void
1769 kprintf_unfiltered(const char* format, ...)
1770 {
1771 	va_list args;
1772 	va_start(args, format);
1773 	gDefaultDebugOutputFilter.Print(format, args);
1774 	va_end(args);
1775 }
1776 
1777 
1778 const char*
1779 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize,
1780 	bool* _isObjectMethod)
1781 {
1782 	if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) {
1783 		return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize,
1784 			_isObjectMethod);
1785 	}
1786 
1787 	if (_isObjectMethod != NULL)
1788 		*_isObjectMethod = false;
1789 
1790 	return symbol;
1791 }
1792 
1793 
1794 status_t
1795 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol,
1796 	char* name, size_t nameSize, int32* _type, size_t* _argumentLength)
1797 {
1798 	if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) {
1799 		return sDemangleModule->get_next_argument(_cookie, symbol, name,
1800 			nameSize, _type, _argumentLength);
1801 	}
1802 
1803 	return B_NOT_SUPPORTED;
1804 }
1805 
1806 
1807 struct thread*
1808 debug_set_debugged_thread(struct thread* thread)
1809 {
1810 	struct thread* previous = sDebuggedThread;
1811 	sDebuggedThread = thread;
1812 	return previous;
1813 }
1814 
1815 
1816 struct thread*
1817 debug_get_debugged_thread()
1818 {
1819 	return sDebuggedThread != NULL
1820 		? sDebuggedThread : thread_get_current_thread();
1821 }
1822 
1823 
1824 //	#pragma mark -
1825 //	userland syscalls
1826 
1827 
1828 status_t
1829 _user_kernel_debugger(const char *userMessage)
1830 {
1831 	if (geteuid() != 0)
1832 		return B_NOT_ALLOWED;
1833 
1834 	char message[512];
1835 	strcpy(message, "USER: ");
1836 	size_t len = strlen(message);
1837 
1838 	if (userMessage == NULL || !IS_USER_ADDRESS(userMessage)
1839 		|| 	user_strlcpy(message + len, userMessage, sizeof(message) - len)
1840 			< 0) {
1841 		return B_BAD_ADDRESS;
1842 	}
1843 
1844 	kernel_debugger(message);
1845 	return B_OK;
1846 }
1847 
1848 
1849 void
1850 _user_debug_output(const char* userString)
1851 {
1852 	char string[512];
1853 	int32 length;
1854 
1855 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled)
1856 		return;
1857 
1858 	if (!IS_USER_ADDRESS(userString))
1859 		return;
1860 
1861 	do {
1862 		length = user_strlcpy(string, userString, sizeof(string));
1863 		debug_puts(string, length);
1864 		userString += sizeof(string) - 1;
1865 	} while (length >= (ssize_t)sizeof(string));
1866 }
1867 
1868 
1869 void
1870 dump_block(const char* buffer, int size, const char* prefix)
1871 {
1872 	const int DUMPED_BLOCK_SIZE = 16;
1873 	int i;
1874 
1875 	for (i = 0; i < size;) {
1876 		int start = i;
1877 
1878 		dprintf("%s%04x ", prefix, i);
1879 		for (; i < start + DUMPED_BLOCK_SIZE; i++) {
1880 			if (!(i % 4))
1881 				dprintf(" ");
1882 
1883 			if (i >= size)
1884 				dprintf("  ");
1885 			else
1886 				dprintf("%02x", *(unsigned char*)(buffer + i));
1887 		}
1888 		dprintf("  ");
1889 
1890 		for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) {
1891 			if (i < size) {
1892 				char c = buffer[i];
1893 
1894 				if (c < 30)
1895 					dprintf(".");
1896 				else
1897 					dprintf("%c", c);
1898 			} else
1899 				break;
1900 		}
1901 		dprintf("\n");
1902 	}
1903 }
1904