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