xref: /haiku/src/system/kernel/debug/debug.cpp (revision f72d1684e521ba60da5fce8a71ae90494b960164)
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 
DebugOutputFilter()159 DebugOutputFilter::DebugOutputFilter()
160 {
161 }
162 
163 
~DebugOutputFilter()164 DebugOutputFilter::~DebugOutputFilter()
165 {
166 }
167 
168 
169 void
PrintString(const char * string)170 DebugOutputFilter::PrintString(const char* string)
171 {
172 }
173 
174 
175 void
Print(const char * format,va_list args)176 DebugOutputFilter::Print(const char* format, va_list args)
177 {
178 }
179 
180 
181 void
PrintString(const char * string)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
Print(const char * format,va_list args)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*
set_debug_output_filter(DebugOutputFilter * filter)213 set_debug_output_filter(DebugOutputFilter* filter)
214 {
215 	DebugOutputFilter* oldFilter = sDebugOutputFilter;
216 	sDebugOutputFilter = filter;
217 	return oldFilter;
218 }
219 
220 
221 static void
kputchar(char c)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
kputs(const char * s)235 kputs(const char* s)
236 {
237 	if (sDebugOutputFilter != NULL)
238 		sDebugOutputFilter->PrintString(s);
239 }
240 
241 
242 void
kputs_unfiltered(const char * s)243 kputs_unfiltered(const char* s)
244 {
245 	gDefaultDebugOutputFilter.PrintString(s);
246 }
247 
248 
249 static void
insert_chars_into_line(char * buffer,int32 & position,int32 & length,const char * chars,int32 charCount)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
insert_char_into_line(char * buffer,int32 & position,int32 & length,char c)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
remove_char_from_line(char * buffer,int32 & position,int32 & length)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:
~LineEditingHelper()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:
CommandLineEditingHelper()318 	CommandLineEditingHelper()
319 	{
320 	}
321 
~CommandLineEditingHelper()322 	virtual	~CommandLineEditingHelper() {}
323 
TabCompletion(char * buffer,int32 capacity,int32 & position,int32 & length)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
read_line(char * buffer,int32 maxLength,LineEditingHelper * editingHelper=NULL)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
kgetc(void)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
kgets(char * buffer,int length)724 kgets(char* buffer, int length)
725 {
726 	return read_line(buffer, length);
727 }
728 
729 
730 static void
print_kernel_debugger_message()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
execute_panic_commands()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
stack_trace_trampoline(void *)810 stack_trace_trampoline(void*)
811 {
812 	arch_debug_stack_trace();
813 }
814 
815 
816 static void
kernel_debugger_loop(const char * messagePrefix,const char * message,va_list args,int32 cpu)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
enter_kernel_debugger(int32 cpu,int32 & previousCPU)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
exit_kernel_debugger()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
hand_over_kernel_debugger()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
kernel_debugger_internal(const char * messagePrefix,const char * message,va_list args,int32 cpu)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
cmd_dump_kdl_message(int argc,char ** argv)1071 cmd_dump_kdl_message(int argc, char** argv)
1072 {
1073 	print_kernel_debugger_message();
1074 	return 0;
1075 }
1076 
1077 
1078 static int
cmd_execute_panic_commands(int argc,char ** argv)1079 cmd_execute_panic_commands(int argc, char** argv)
1080 {
1081 	execute_panic_commands();
1082 	return 0;
1083 }
1084 
1085 
1086 static int
cmd_dump_syslog(int argc,char ** argv)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
cmd_switch_cpu(int argc,char ** argv)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
syslog_sender(void * data)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
syslog_write(const char * text,int32 length,bool notify)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
syslog_init_post_threads(void)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
syslog_init_post_vm(struct kernel_args * args)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
syslog_init_post_modules()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
syslog_init(struct kernel_args * args)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
debug_memcpy_trampoline(void * _parameters)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
debug_strlcpy_trampoline(void * _parameters)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
call_modules_hook(bool enter)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
debug_output(const char * string,int32 length,bool notifySyslog)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
flush_pending_repeats(bool notifySyslog)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
check_pending_repeats(void *,int)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
dprintf_args(const char * format,va_list args,bool notifySyslog)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
debug_screen_output_enabled(void)1648 debug_screen_output_enabled(void)
1649 {
1650 	return sDebugScreenEnabled;
1651 }
1652 
1653 
1654 void
debug_stop_screen_debug_output(void)1655 debug_stop_screen_debug_output(void)
1656 {
1657 	sDebugScreenEnabled = false;
1658 }
1659 
1660 
1661 bool
debug_debugger_running(void)1662 debug_debugger_running(void)
1663 {
1664 	return sDebuggerOnCPU != -1;
1665 }
1666 
1667 
1668 void
debug_puts(const char * string,int32 length)1669 debug_puts(const char* string, int32 length)
1670 {
1671 	InterruptsSpinLocker _(sSpinlock);
1672 	debug_output(string, length, true);
1673 }
1674 
1675 
1676 void
debug_early_boot_message(const char * string)1677 debug_early_boot_message(const char* string)
1678 {
1679 	arch_debug_serial_early_boot_message(string);
1680 }
1681 
1682 
1683 void
debug_init(kernel_args * args)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 	if (frame_buffer_console_init(args) == B_OK && blue_screen_init_early() == B_OK)
1694 		sBlueScreenOutput = true;
1695 }
1696 
1697 
1698 void
debug_init_post_vm(kernel_args * args)1699 debug_init_post_vm(kernel_args* args)
1700 {
1701 	add_debugger_command_etc("cpu", &cmd_switch_cpu,
1702 		"Switches to another CPU.",
1703 		"<cpu>\n"
1704 		"Switches to CPU with the index <cpu>.\n", 0);
1705 	add_debugger_command_etc("message", &cmd_dump_kdl_message,
1706 		"Reprint the message printed when entering KDL",
1707 		"\n"
1708 		"Reprints the message printed when entering KDL.\n", 0);
1709 	add_debugger_command_etc("panic_commands", &cmd_execute_panic_commands,
1710 		"Execute commands associated with the panic() that caused "
1711 			"entering KDL",
1712 		"\n"
1713 		"Executes the commands associated with the panic() that caused "
1714 			"entering KDL.\n", 0);
1715 
1716 	debug_builtin_commands_init();
1717 	arch_debug_init(args);
1718 
1719 	debug_heap_init();
1720 	debug_variables_init();
1721 	frame_buffer_console_init_post_vm(args);
1722 	tracing_init();
1723 }
1724 
1725 
1726 void
debug_init_post_settings(struct kernel_args * args)1727 debug_init_post_settings(struct kernel_args* args)
1728 {
1729 	// get debug settings
1730 
1731 	sSerialDebugEnabled = get_safemode_boolean("serial_debug_output",
1732 		sSerialDebugEnabled);
1733 	sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output",
1734 		sSyslogOutputEnabled);
1735 	sBlueScreenOutput = get_safemode_boolean("bluescreen", true);
1736 	sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys",
1737 		sEmergencyKeysEnabled);
1738 	sDebugScreenEnabled = get_safemode_boolean("debug_screen", false);
1739 
1740 	if ((sBlueScreenOutput || sDebugScreenEnabled)
1741 			&& blue_screen_init() != B_OK)
1742 		sBlueScreenOutput = sDebugScreenEnabled = false;
1743 
1744 	if (sDebugScreenEnabled)
1745 		blue_screen_enter(true);
1746 
1747 	arch_debug_console_init_settings(args);
1748 	syslog_init_post_vm(args);
1749 }
1750 
1751 
1752 void
debug_init_post_modules(struct kernel_args * args)1753 debug_init_post_modules(struct kernel_args* args)
1754 {
1755 	syslog_init_post_modules();
1756 
1757 	// check for dupped lines every 10/10 second
1758 	register_kernel_daemon(check_pending_repeats, NULL, 10);
1759 
1760 	syslog_init_post_threads();
1761 
1762 	// load kernel debugger addons
1763 
1764 	static const char* kDemanglePrefix = "debugger/demangle/";
1765 
1766 	void* cookie = open_module_list("debugger");
1767 	uint32 count = 0;
1768 	while (count < kMaxDebuggerModules) {
1769 		char name[B_FILE_NAME_LENGTH];
1770 		size_t nameLength = sizeof(name);
1771 
1772 		if (read_next_module_name(cookie, name, &nameLength) != B_OK)
1773 			break;
1774 
1775 		// get demangle module, if any
1776 		if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) {
1777 			if (sDemangleModule == NULL)
1778 				get_module(name, (module_info**)&sDemangleModule);
1779 			continue;
1780 		}
1781 
1782 		if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) {
1783 			dprintf("kernel debugger extension \"%s\": loaded\n", name);
1784 			count++;
1785 		} else
1786 			dprintf("kernel debugger extension \"%s\": failed to load\n", name);
1787 	}
1788 	close_module_list(cookie);
1789 
1790 	frame_buffer_console_init_post_modules(args);
1791 }
1792 
1793 
1794 void
debug_set_page_fault_info(addr_t faultAddress,addr_t pc,uint32 flags)1795 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags)
1796 {
1797 	sPageFaultInfo.fault_address = faultAddress;
1798 	sPageFaultInfo.pc = pc;
1799 	sPageFaultInfo.flags = flags;
1800 }
1801 
1802 
1803 debug_page_fault_info*
debug_get_page_fault_info()1804 debug_get_page_fault_info()
1805 {
1806 	return &sPageFaultInfo;
1807 }
1808 
1809 
1810 void
debug_trap_cpu_in_kdl(int32 cpu,bool returnIfHandedOver)1811 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
1812 {
1813 	InterruptsLocker locker;
1814 
1815 	// return, if we've been called recursively (we call
1816 	// smp_intercpu_int_handler() below)
1817 	if (sCPUTrapped[cpu])
1818 		return;
1819 
1820 	arch_debug_save_registers(&sDebugRegisters[cpu]);
1821 
1822 	sCPUTrapped[cpu] = true;
1823 
1824 	while (sInDebugger != 0) {
1825 		cpu_pause();
1826 
1827 		if (sHandOverKDL && sHandOverKDLToCPU == cpu) {
1828 			if (returnIfHandedOver)
1829 				break;
1830 
1831 			kernel_debugger_internal(NULL, NULL,
1832 				sCurrentKernelDebuggerMessageArgs, cpu);
1833 		} else
1834 			smp_intercpu_int_handler(cpu);
1835 	}
1836 
1837 	sCPUTrapped[cpu] = false;
1838 }
1839 
1840 
1841 void
debug_double_fault(int32 cpu)1842 debug_double_fault(int32 cpu)
1843 {
1844 	kernel_debugger_internal("Double Fault!", NULL,
1845 		sCurrentKernelDebuggerMessageArgs, cpu);
1846 }
1847 
1848 
1849 bool
debug_emergency_key_pressed(char key)1850 debug_emergency_key_pressed(char key)
1851 {
1852 	if (!sEmergencyKeysEnabled)
1853 		return false;
1854 
1855 	if (key == 'd') {
1856 		kernel_debugger("Keyboard Requested Halt.");
1857 		return true;
1858 	}
1859 
1860 	// Broadcast to the kernel debugger modules
1861 
1862 	for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1863 		if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) {
1864 			if (sDebuggerModules[i]->emergency_key_pressed(key))
1865 				return true;
1866 		}
1867 	}
1868 
1869 	return false;
1870 }
1871 
1872 
1873 /*!	Verifies that the complete given memory range is accessible in the current
1874 	context.
1875 
1876 	Invoked in the kernel debugger only.
1877 
1878 	\param address The start address of the memory range to be checked.
1879 	\param size The size of the memory range to be checked.
1880 	\param protection The area protection for which to check. Valid is a bitwise
1881 		or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA.
1882 	\return \c true, if the complete memory range can be accessed in all ways
1883 		specified by \a protection, \c false otherwise.
1884 */
1885 bool
debug_is_kernel_memory_accessible(addr_t address,size_t size,uint32 protection)1886 debug_is_kernel_memory_accessible(addr_t address, size_t size,
1887 	uint32 protection)
1888 {
1889 	addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE);
1890 	address = ROUNDDOWN(address, B_PAGE_SIZE);
1891 
1892 	if (!IS_KERNEL_ADDRESS(address) || endAddress < address)
1893 		return false;
1894 
1895 	for (; address < endAddress; address += B_PAGE_SIZE) {
1896 		if (!arch_vm_translation_map_is_kernel_page_accessible(address,
1897 				protection)) {
1898 			return false;
1899 		}
1900 	}
1901 
1902 	return true;
1903 }
1904 
1905 
1906 /*!	Calls a function in a setjmp() + fault handler context.
1907 	May only be used in the kernel debugger.
1908 
1909 	\param jumpBuffer Buffer to be used for setjmp()/longjmp().
1910 	\param function The function to be called.
1911 	\param parameter The parameter to be passed to the function to be called.
1912 	\return
1913 		- \c 0, when the function executed without causing a page fault or
1914 		  calling longjmp().
1915 		- \c 1, when the function caused a page fault.
1916 		- Any other value the function passes to longjmp().
1917 */
1918 int
debug_call_with_fault_handler(jmp_buf jumpBuffer,void (* function)(void *),void * parameter)1919 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*),
1920 	void* parameter)
1921 {
1922 	// save current fault handler
1923 	cpu_ent* cpu = gCPU + sDebuggerOnCPU;
1924 	addr_t oldFaultHandler = cpu->fault_handler;
1925 	addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer;
1926 
1927 	int result = setjmp(jumpBuffer);
1928 	if (result == 0) {
1929 		arch_debug_call_with_fault_handler(cpu, jumpBuffer, function,
1930 			parameter);
1931 	}
1932 
1933 	// restore old fault handler
1934 	cpu->fault_handler = oldFaultHandler;
1935 	cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer;
1936 
1937 	return result;
1938 }
1939 
1940 
1941 /*!	Similar to user_memcpy(), but can only be invoked from within the kernel
1942 	debugger (and must not be used outside).
1943 	The supplied \a teamID specifies the address space in which to interpret
1944 	the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(),
1945 	or any valid team ID. If the addresses are both kernel addresses, the
1946 	argument is ignored and the current address space is used.
1947 */
1948 status_t
debug_memcpy(team_id teamID,void * to,const void * from,size_t size)1949 debug_memcpy(team_id teamID, void* to, const void* from, size_t size)
1950 {
1951 	// don't allow address overflows
1952 	if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to)
1953 		return B_BAD_ADDRESS;
1954 
1955 	// Try standard memcpy() with fault handler, if the addresses can be
1956 	// interpreted in the current address space.
1957 	if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to))
1958 			|| debug_is_debugged_team(teamID)) {
1959 		debug_memcpy_parameters parameters = {to, from, size};
1960 
1961 		if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1962 				&debug_memcpy_trampoline, &parameters) == 0) {
1963 			return B_OK;
1964 		}
1965 	}
1966 
1967 	// Try harder. The pages of the respective memory could be unmapped but
1968 	// still exist in a cache (the page daemon does that with inactive pages).
1969 	while (size > 0) {
1970 		uint8 buffer[32];
1971 		size_t toCopy = std::min(size, sizeof(buffer));
1972 
1973 		// restrict the size so we don't cross page boundaries
1974 		if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy)
1975 			toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE;
1976 		if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy)
1977 			toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE;
1978 
1979 		if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy,
1980 				false) != B_OK
1981 			|| vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
1982 				!= B_OK) {
1983 			return B_BAD_ADDRESS;
1984 		}
1985 
1986 		from = (const uint8*)from + toCopy;
1987 		to = (uint8*)to + toCopy;
1988 		size -= toCopy;
1989 	}
1990 
1991 	return B_OK;
1992 }
1993 
1994 
1995 /*!	Similar to user_strlcpy(), but can only be invoked from within the kernel
1996 	debugger (and must not be used outside).
1997 	The supplied \a teamID specifies the address space in which to interpret
1998 	the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(),
1999 	or any valid team ID. If the addresses are both kernel addresses, the
2000 	argument is ignored and the current address space is used.
2001 */
2002 ssize_t
debug_strlcpy(team_id teamID,char * to,const char * from,size_t size)2003 debug_strlcpy(team_id teamID, char* to, const char* from, size_t size)
2004 {
2005 	if (from == NULL || (to == NULL && size > 0))
2006 		return B_BAD_ADDRESS;
2007 
2008 	// limit size to avoid address overflows
2009 	size_t maxSize = std::min((addr_t)size,
2010 		~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1);
2011 		// NOTE: Since strlcpy() determines the length of \a from, the source
2012 		// address might still overflow.
2013 
2014 	// Try standard strlcpy() with fault handler, if the addresses can be
2015 	// interpreted in the current address space.
2016 	if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to))
2017 			|| debug_is_debugged_team(teamID)) {
2018 		debug_strlcpy_parameters parameters = {to, from, maxSize};
2019 
2020 		if (debug_call_with_fault_handler(
2021 				gCPU[sDebuggerOnCPU].fault_jump_buffer,
2022 				&debug_strlcpy_trampoline, &parameters) == 0) {
2023 			// If we hit the address overflow boundary, fail.
2024 			if (parameters.result >= maxSize && maxSize < size)
2025 				return B_BAD_ADDRESS;
2026 
2027 			return parameters.result;
2028 		}
2029 	}
2030 
2031 	// Try harder. The pages of the respective memory could be unmapped but
2032 	// still exist in a cache (the page daemon does that with inactive pages).
2033 	size_t totalLength = 0;
2034 	while (maxSize > 0) {
2035 		char buffer[32];
2036 		size_t toCopy = std::min(maxSize, sizeof(buffer));
2037 
2038 		// restrict the size so we don't cross page boundaries
2039 		if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy)
2040 			toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE;
2041 		if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy)
2042 			toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE;
2043 
2044 		// copy the next part of the string from the source
2045 		if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy,
2046 				false) != B_OK) {
2047 			return B_BAD_ADDRESS;
2048 		}
2049 
2050 		// determine the length of the part and whether we've reached the end
2051 		// of the string
2052 		size_t length = strnlen(buffer, toCopy);
2053 		bool endOfString = length < toCopy;
2054 
2055 		from = (const char*)from + toCopy;
2056 		totalLength += length;
2057 		maxSize -= length;
2058 
2059 		if (endOfString) {
2060 			// only copy the actual string, including the terminating null
2061 			toCopy = length + 1;
2062 		}
2063 
2064 		if (size > 0) {
2065 			// We still have space left in the target buffer.
2066 			if (size <= length) {
2067 				// Not enough space for the complete part. Null-terminate it and
2068 				// copy what we can.
2069 				buffer[size - 1] = '\0';
2070 				totalLength += length - size;
2071 				toCopy = size;
2072 			}
2073 
2074 			if (vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
2075 					!= B_OK) {
2076 				return B_BAD_ADDRESS;
2077 			}
2078 
2079 			to = (char*)to + toCopy;
2080 			size -= toCopy;
2081 		}
2082 
2083 		if (endOfString)
2084 			return totalLength;
2085 	}
2086 
2087 	return totalLength;
2088 }
2089 
2090 
2091 // #pragma mark - public API
2092 
2093 
2094 uint64
parse_expression(const char * expression)2095 parse_expression(const char* expression)
2096 {
2097 	uint64 result;
2098 	return evaluate_debug_expression(expression, &result, true) ? result : 0;
2099 }
2100 
2101 
2102 void
panic(const char * format,...)2103 panic(const char* format, ...)
2104 {
2105 	va_list args;
2106 	va_start(args, format);
2107 
2108 	cpu_status state = disable_interrupts();
2109 
2110 	kernel_debugger_internal("PANIC: ", format, args,
2111 		thread_get_current_thread() ? smp_get_current_cpu() : 0);
2112 
2113 	restore_interrupts(state);
2114 
2115 	va_end(args);
2116 }
2117 
2118 
2119 void
kernel_debugger(const char * message)2120 kernel_debugger(const char* message)
2121 {
2122 	cpu_status state = disable_interrupts();
2123 
2124 	kernel_debugger_internal(message, NULL, sCurrentKernelDebuggerMessageArgs,
2125 		smp_get_current_cpu());
2126 
2127 	restore_interrupts(state);
2128 }
2129 
2130 
2131 bool
set_dprintf_enabled(bool newState)2132 set_dprintf_enabled(bool newState)
2133 {
2134 	bool oldState = sSerialDebugEnabled;
2135 	sSerialDebugEnabled = newState;
2136 
2137 	return oldState;
2138 }
2139 
2140 
2141 void
dprintf(const char * format,...)2142 dprintf(const char* format, ...)
2143 {
2144 	va_list args;
2145 
2146 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
2147 		return;
2148 
2149 	va_start(args, format);
2150 	dprintf_args(format, args, true);
2151 	va_end(args);
2152 }
2153 
2154 
2155 void
dvprintf(const char * format,va_list args)2156 dvprintf(const char* format, va_list args)
2157 {
2158 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
2159 		return;
2160 
2161 	dprintf_args(format, args, true);
2162 }
2163 
2164 
2165 void
dprintf_no_syslog(const char * format,...)2166 dprintf_no_syslog(const char* format, ...)
2167 {
2168 	va_list args;
2169 
2170 	if (!sSerialDebugEnabled && !sBlueScreenEnabled)
2171 		return;
2172 
2173 	va_start(args, format);
2174 	dprintf_args(format, args, false);
2175 	va_end(args);
2176 }
2177 
2178 
2179 /*!	Similar to dprintf() but thought to be used in the kernel
2180 	debugger only (it doesn't lock).
2181 */
2182 void
kprintf(const char * format,...)2183 kprintf(const char* format, ...)
2184 {
2185 	if (sDebugOutputFilter != NULL) {
2186 		va_list args;
2187 		va_start(args, format);
2188 		sDebugOutputFilter->Print(format, args);
2189 		va_end(args);
2190 	}
2191 }
2192 
2193 
2194 void
kprintf_unfiltered(const char * format,...)2195 kprintf_unfiltered(const char* format, ...)
2196 {
2197 	va_list args;
2198 	va_start(args, format);
2199 	gDefaultDebugOutputFilter.Print(format, args);
2200 	va_end(args);
2201 }
2202 
2203 
2204 const char*
debug_demangle_symbol(const char * symbol,char * buffer,size_t bufferSize,bool * _isObjectMethod)2205 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize,
2206 	bool* _isObjectMethod)
2207 {
2208 	if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) {
2209 		return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize,
2210 			_isObjectMethod);
2211 	}
2212 
2213 	if (_isObjectMethod != NULL)
2214 		*_isObjectMethod = false;
2215 
2216 	return symbol;
2217 }
2218 
2219 
2220 status_t
debug_get_next_demangled_argument(uint32 * _cookie,const char * symbol,char * name,size_t nameSize,int32 * _type,size_t * _argumentLength)2221 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol,
2222 	char* name, size_t nameSize, int32* _type, size_t* _argumentLength)
2223 {
2224 	if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) {
2225 		return sDemangleModule->get_next_argument(_cookie, symbol, name,
2226 			nameSize, _type, _argumentLength);
2227 	}
2228 
2229 	return B_NOT_SUPPORTED;
2230 }
2231 
2232 
2233 struct arch_debug_registers*
debug_get_debug_registers(int32 cpu)2234 debug_get_debug_registers(int32 cpu)
2235 {
2236 	if (cpu < 0 || cpu > smp_get_num_cpus())
2237 		return NULL;
2238 
2239 	return &sDebugRegisters[cpu];
2240 }
2241 
2242 
2243 Thread*
debug_set_debugged_thread(Thread * thread)2244 debug_set_debugged_thread(Thread* thread)
2245 {
2246 	Thread* previous = sDebuggedThread;
2247 	sDebuggedThread = thread;
2248 	return previous;
2249 }
2250 
2251 
2252 Thread*
debug_get_debugged_thread()2253 debug_get_debugged_thread()
2254 {
2255 	return sDebuggedThread != NULL
2256 		? sDebuggedThread : thread_get_current_thread();
2257 }
2258 
2259 
2260 /*!	Returns whether the supplied team ID refers to the same team the currently
2261 	debugged thread (debug_get_debugged_thread()) belongs to.
2262 	Always returns \c true, if \c B_CURRENT_TEAM is given.
2263 */
2264 bool
debug_is_debugged_team(team_id teamID)2265 debug_is_debugged_team(team_id teamID)
2266 {
2267 	if (teamID == B_CURRENT_TEAM)
2268 		return true;
2269 
2270 	Thread* thread = debug_get_debugged_thread();
2271 	return thread != NULL && thread->team != NULL
2272 		&& thread->team->id == teamID;
2273 }
2274 
2275 
2276 //	#pragma mark -
2277 //	userland syscalls
2278 
2279 
2280 status_t
_user_kernel_debugger(const char * userMessage)2281 _user_kernel_debugger(const char* userMessage)
2282 {
2283 	if (geteuid() != 0)
2284 		return B_NOT_ALLOWED;
2285 
2286 	char message[512];
2287 	strcpy(message, "USER: ");
2288 	size_t length = strlen(message);
2289 
2290 	if (userMessage == NULL || !IS_USER_ADDRESS(userMessage) || user_strlcpy(
2291 			message + length, userMessage, sizeof(message) - length) < 0) {
2292 		return B_BAD_ADDRESS;
2293 	}
2294 
2295 	kernel_debugger(message);
2296 	return B_OK;
2297 }
2298 
2299 
2300 void
_user_register_syslog_daemon(port_id port)2301 _user_register_syslog_daemon(port_id port)
2302 {
2303 	if (geteuid() != 0 || !sSyslogOutputEnabled || sSyslogNotify < 0)
2304 		return;
2305 
2306 	sSyslogPort = port;
2307 
2308 	if (sSyslogWriter < 0) {
2309 		sSyslogWriter = spawn_kernel_thread(syslog_sender, "syslog sender",
2310 			B_LOW_PRIORITY, NULL);
2311 		if (sSyslogWriter >= 0)
2312 			resume_thread(sSyslogWriter);
2313 	}
2314 }
2315 
2316 
2317 void
_user_debug_output(const char * userString)2318 _user_debug_output(const char* userString)
2319 {
2320 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled)
2321 		return;
2322 
2323 	if (!IS_USER_ADDRESS(userString))
2324 		return;
2325 
2326 	char string[512];
2327 	int32 length;
2328 	int32 toWrite;
2329 	do {
2330 		length = user_strlcpy(string, userString, sizeof(string));
2331 		if (length <= 0)
2332 			break;
2333 		toWrite = std::min(length, (int32)sizeof(string) - 1);
2334 		debug_puts(string, toWrite);
2335 		userString += toWrite;
2336 	} while (length > toWrite);
2337 }
2338 
2339 
2340 void
dump_block(const char * buffer,int size,const char * prefix)2341 dump_block(const char* buffer, int size, const char* prefix)
2342 {
2343 	const int DUMPED_BLOCK_SIZE = 16;
2344 	int i;
2345 	char lineBuffer[3 + DUMPED_BLOCK_SIZE * 4];
2346 
2347 	for (i = 0; i < size;) {
2348 		char* pointer = lineBuffer;
2349 		int start = i;
2350 
2351 		for (; i < start + DUMPED_BLOCK_SIZE; i++) {
2352 			if (!(i % 4))
2353 				pointer += sprintf(pointer, " ");
2354 
2355 			if (i >= size)
2356 				pointer += sprintf(pointer, "  ");
2357 			else
2358 				pointer += sprintf(pointer, "%02x", *(unsigned char*)(buffer + i));
2359 		}
2360 		pointer += sprintf(pointer, "  ");
2361 
2362 		for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) {
2363 			if (i < size) {
2364 				char c = buffer[i];
2365 
2366 				if (c < 30)
2367 					pointer += sprintf(pointer, ".");
2368 				else
2369 					pointer += sprintf(pointer, "%c", c);
2370 			} else
2371 				break;
2372 		}
2373 		dprintf("%s%04x%s\n", prefix, start, lineBuffer);
2374 	}
2375 }
2376