152a38012Sejakowatz/*
24bf862e3SAxel Dörfler * Copyright 2002-2015, Axel D��rfler, axeld@pinc-software.de
347a21c5cSAugustin Cavalier * Distributed under the terms of the MIT License.
49a63135fSAxel Dörfler *
59a63135fSAxel Dörfler * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
69a63135fSAxel Dörfler * Distributed under the terms of the NewOS License.
79a63135fSAxel Dörfler */
852a38012Sejakowatz#ifndef _KERNEL_DEBUG_H
952a38012Sejakowatz#define _KERNEL_DEBUG_H
1052a38012Sejakowatz
11ea2abd11SIngo Weinhold
12ea2abd11SIngo Weinhold#include <setjmp.h>
13564cba31SAxel Dörfler
1476ab7bdcSIngo Weinhold#include <KernelExport.h>
153cec75dcSAxel Dörfler#include <module.h>
163cec75dcSAxel Dörfler
17ea2abd11SIngo Weinhold#include "kernel_debug_config.h"
18ea2abd11SIngo Weinhold
19564cba31SAxel Dörfler
204535495dSIngo Weinhold// We need the BKernel::Thread type below (opaquely) in the exported C
214535495dSIngo Weinhold// functions below. Since this header is currently still included by plain C
224535495dSIngo Weinhold// code, we define a dummy type BKernel_Thread in C mode and a equally named
234535495dSIngo Weinhold// macro in C++ mode.
244535495dSIngo Weinhold#ifdef __cplusplus
254535495dSIngo Weinhold	namespace BKernel {
264535495dSIngo Weinhold		struct Thread;
274535495dSIngo Weinhold	}
284535495dSIngo Weinhold
294535495dSIngo Weinhold	using BKernel::Thread;
304535495dSIngo Weinhold#	define BKernel_Thread	Thread
314535495dSIngo Weinhold#else
324535495dSIngo Weinhold	typedef struct BKernel_Thread BKernel_Thread;
334535495dSIngo Weinhold#endif
344535495dSIngo Weinhold
354535495dSIngo Weinhold
361894a0a9SIngo Weinhold/*	KDEBUG
371894a0a9SIngo Weinhold	The kernel debug level.
381894a0a9SIngo Weinhold	Level 1 is usual asserts, > 1 should be used for very expensive runtime
391894a0a9SIngo Weinhold	checks
40c9788912STravis Geiselbrecht */
411894a0a9SIngo Weinhold#if !defined(KDEBUG)
421894a0a9SIngo Weinhold#	if DEBUG
431894a0a9SIngo Weinhold#		define KDEBUG 1
441894a0a9SIngo Weinhold#	else
451894a0a9SIngo Weinhold#		define KDEBUG 0
461894a0a9SIngo Weinhold#	endif
47c9788912STravis Geiselbrecht#endif
48c9788912STravis Geiselbrecht
49c9788912STravis Geiselbrecht#define ASSERT_ALWAYS(x) \
50c755ecfeSAxel Dörfler	do {																	\
51c755ecfeSAxel Dörfler		if (!(x)) {															\
528b522fcfSIngo Weinhold			panic("ASSERT FAILED (%s:%d): %s", __FILE__, __LINE__, #x);		\
53c755ecfeSAxel Dörfler		}																	\
54c755ecfeSAxel Dörfler	} while (0)
55c9788912STravis Geiselbrecht
568b522fcfSIngo Weinhold#define ASSERT_ALWAYS_PRINT(x, format, args...) \
57cf1539e1SIngo Weinhold	do {																	\
58cf1539e1SIngo Weinhold		if (!(x)) {															\
598b522fcfSIngo Weinhold			panic("ASSERT FAILED (%s:%d): %s; " format, __FILE__, __LINE__,	\
608b522fcfSIngo Weinhold				#x, args);													\
61cf1539e1SIngo Weinhold		}																	\
62cf1539e1SIngo Weinhold	} while (0)
63cf1539e1SIngo Weinhold
64c9788912STravis Geiselbrecht#if KDEBUG
658b522fcfSIngo Weinhold#	define ASSERT(x)						ASSERT_ALWAYS(x)
668b522fcfSIngo Weinhold#	define ASSERT_PRINT(x, format, args...)	ASSERT_ALWAYS_PRINT(x, format, args)
6746ec2301SIngo Weinhold#else
688b522fcfSIngo Weinhold#	define ASSERT(x)						do { } while(0)
698b522fcfSIngo Weinhold#	define ASSERT_PRINT(x, format, args...)	do { } while(0)
7052a38012Sejakowatz#endif
712b5d1dc4SAxel Dörfler
7247b079afSAugustin Cavalier#if __GNUC__ >= 5 && !defined(__cplusplus)
7347b079afSAugustin Cavalier#	define STATIC_ASSERT(x) _Static_assert(x, "static assert failed!")
7447b079afSAugustin Cavalier#elif defined(__cplusplus) && __cplusplus >= 201103L
7547b079afSAugustin Cavalier#	define STATIC_ASSERT(x) static_assert(x, "static assert failed!")
7647b079afSAugustin Cavalier#else
7747b079afSAugustin Cavalier#	define STATIC_ASSERT(x)								\
7847b079afSAugustin Cavalier		do {												\
7947b079afSAugustin Cavalier			struct __staticAssertStruct__ {					\
8047b079afSAugustin Cavalier				char __static_assert_failed__[2*(x) - 1];	\
8147b079afSAugustin Cavalier			};												\
8247b079afSAugustin Cavalier		} while (false)
8347b079afSAugustin Cavalier#endif
84f498c079SIngo Weinhold
85eb0dca1dSMichael Lotz#if KDEBUG
86eb0dca1dSMichael Lotz#	define KDEBUG_ONLY(x)				x
87eb0dca1dSMichael Lotz#else
88eb0dca1dSMichael Lotz#	define KDEBUG_ONLY(x)				/* nothing */
89eb0dca1dSMichael Lotz#endif
90eb0dca1dSMichael Lotz
9197ac7257SIngo Weinhold
9297ac7257SIngo Weinhold// Macros for for placing marker functions. They can be used to mark the
9397ac7257SIngo Weinhold// beginning and end of code sections (e.g. used in the slab code).
9497ac7257SIngo Weinhold#define RANGE_MARKER_FUNCTION(functionName) \
9597ac7257SIngo Weinhold	void functionName() {}
9697ac7257SIngo Weinhold#define RANGE_MARKER_FUNCTION_BEGIN(scope) \
9797ac7257SIngo Weinhold	RANGE_MARKER_FUNCTION(scope##_begin)
9897ac7257SIngo Weinhold#define RANGE_MARKER_FUNCTION_END(scope) \
9997ac7257SIngo Weinhold	RANGE_MARKER_FUNCTION(scope##_end)
10097ac7257SIngo Weinhold
10197ac7257SIngo Weinhold#define RANGE_MARKER_FUNCTION_PROTOTYPE(functionName) \
10297ac7257SIngo Weinhold	void functionName();
10397ac7257SIngo Weinhold#define RANGE_MARKER_FUNCTION_PROTOTYPES(scope)		\
10497ac7257SIngo Weinhold	RANGE_MARKER_FUNCTION_PROTOTYPE(scope##_begin)	\
10597ac7257SIngo Weinhold	RANGE_MARKER_FUNCTION_PROTOTYPE(scope##_end)
10697ac7257SIngo Weinhold#define RANGE_MARKER_FUNCTION_ADDRESS_RANGE(scope) \
10797ac7257SIngo Weinhold	(addr_t)&scope##_begin, (addr_t)&scope##_end
10897ac7257SIngo Weinhold
10997ac7257SIngo Weinhold
11073aa393dSIngo Weinhold// command return value
111945a6a41SMichael Lotz#define B_KDEBUG_ERROR			4
112945a6a41SMichael Lotz#define B_KDEBUG_RESTART_PIPE	5
11373aa393dSIngo Weinhold
11473aa393dSIngo Weinhold// command flags
115325b88a6SIngo Weinhold#define B_KDEBUG_DONT_PARSE_ARGUMENTS	(0x01)
11673aa393dSIngo Weinhold#define B_KDEBUG_PIPE_FINAL_RERUN		(0x02)
117325b88a6SIngo Weinhold
118cfefeee3SIngo Weinhold
119cfefeee3SIngo Weinholdstruct arch_debug_registers;
120cfefeee3SIngo Weinhold
121cfefeee3SIngo Weinhold
1223cec75dcSAxel Dörflerstruct debugger_module_info {
1233cec75dcSAxel Dörfler	module_info info;
1243cec75dcSAxel Dörfler
1253cec75dcSAxel Dörfler	void (*enter_debugger)(void);
1263cec75dcSAxel Dörfler	void (*exit_debugger)(void);
1277f393752SFrançois Revol
128c755ecfeSAxel Dörfler	// I/O hooks
1297f393752SFrançois Revol	int (*debugger_puts)(const char *str, int32 length);
1307f393752SFrançois Revol	int (*debugger_getchar)(void);
1317f393752SFrançois Revol	// TODO: add hooks for tunnelling gdb ?
132c755ecfeSAxel Dörfler
133c755ecfeSAxel Dörfler	// Misc. hooks
134c755ecfeSAxel Dörfler	bool (*emergency_key_pressed)(char key);
1353cec75dcSAxel Dörfler};
1363cec75dcSAxel Dörfler
137ddecb4a7SAxel Dörflerstruct debugger_demangle_module_info {
138ddecb4a7SAxel Dörfler	module_info info;
139ddecb4a7SAxel Dörfler
140ddecb4a7SAxel Dörfler	const char* (*demangle_symbol)(const char* name, char* buffer,
141ddecb4a7SAxel Dörfler		size_t bufferSize, bool* _isObjectMethod);
142ddecb4a7SAxel Dörfler	status_t (*get_next_argument)(uint32* _cookie, const char* symbol,
143ddecb4a7SAxel Dörfler		char* name, size_t nameSize, int32* _type, size_t* _argumentLength);
144ddecb4a7SAxel Dörfler};
145ddecb4a7SAxel Dörfler
146ddecb4a7SAxel Dörfler
14746ec2301SIngo Weinholdtypedef struct debug_page_fault_info {
14846ec2301SIngo Weinhold	addr_t	fault_address;
14946ec2301SIngo Weinhold	addr_t	pc;
15046ec2301SIngo Weinhold	uint32	flags;
15146ec2301SIngo Weinhold} debug_page_fault_info;
15246ec2301SIngo Weinhold
15346ec2301SIngo Weinhold// debug_page_fault_info::flags
15446ec2301SIngo Weinhold#define DEBUG_PAGE_FAULT_WRITE		0x01	/* write fault */
15546ec2301SIngo Weinhold#define DEBUG_PAGE_FAULT_NO_INFO	0x02	/* fault address and read/write
15646ec2301SIngo Weinhold											   unknown */
15746ec2301SIngo Weinhold
15846ec2301SIngo Weinhold
1599289abf0SAxel Dörfler#ifdef __cplusplus
1609289abf0SAxel Dörflerextern "C" {
1619289abf0SAxel Dörfler#endif
1629289abf0SAxel Dörfler
163c9788912STravis Geiselbrechtstruct kernel_args;
164c9788912STravis Geiselbrecht
1658c8fcd77SAxel Dörflerextern void		debug_init(struct kernel_args *args);
1668c8fcd77SAxel Dörflerextern void		debug_init_post_vm(struct kernel_args *args);
1678c8fcd77SAxel Dörflerextern void		debug_init_post_settings(struct kernel_args *args);
1688c8fcd77SAxel Dörflerextern void		debug_init_post_modules(struct kernel_args *args);
169ddecb4a7SAxel Dörflerextern void		debug_early_boot_message(const char *string);
170ddecb4a7SAxel Dörflerextern void		debug_puts(const char *s, int32 length);
171ddecb4a7SAxel Dörflerextern bool		debug_debugger_running(void);
172ddecb4a7SAxel Dörflerextern bool		debug_screen_output_enabled(void);
173ddecb4a7SAxel Dörflerextern void		debug_stop_screen_debug_output(void);
174ddecb4a7SAxel Dörflerextern void		debug_set_page_fault_info(addr_t faultAddress, addr_t pc,
175ddecb4a7SAxel Dörfler					uint32 flags);
17646ec2301SIngo Weinholdextern debug_page_fault_info* debug_get_page_fault_info();
177671a2442SIngo Weinholdextern void		debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver);
178671a2442SIngo Weinholdextern void		debug_double_fault(int32 cpu);
179c755ecfeSAxel Dörflerextern bool		debug_emergency_key_pressed(char key);
180ea2abd11SIngo Weinholdextern bool		debug_is_kernel_memory_accessible(addr_t address, size_t size,
181ea2abd11SIngo Weinhold					uint32 protection);
182ea2abd11SIngo Weinholdextern int		debug_call_with_fault_handler(jmp_buf jumpBuffer,
183ea2abd11SIngo Weinhold					void (*function)(void*), void* parameter);
184c3676b54SIngo Weinholdextern status_t	debug_memcpy(team_id teamID, void* to, const void* from,
185c3676b54SIngo Weinhold					size_t size);
186c3676b54SIngo Weinholdextern ssize_t	debug_strlcpy(team_id teamID, char* to, const char* from,
187c3676b54SIngo Weinhold					size_t size);
1889289abf0SAxel Dörfler
1896eba0636SMichael Lotzextern char		kgetc(void);
190ddecb4a7SAxel Dörflerextern void		kputs(const char *string);
191ddecb4a7SAxel Dörflerextern void		kputs_unfiltered(const char *string);
192ddecb4a7SAxel Dörflerextern void		kprintf_unfiltered(const char *format, ...)
193ddecb4a7SAxel Dörfler					__attribute__ ((format (__printf__, 1, 2)));
194ddecb4a7SAxel Dörflerextern void		dprintf_no_syslog(const char *format, ...)
195ddecb4a7SAxel Dörfler					__attribute__ ((format (__printf__, 1, 2)));
19676ab7bdcSIngo Weinhold
1973b4fa166SIngo Weinholdextern bool		is_debug_variable_defined(const char* variableName);
1983b4fa166SIngo Weinholdextern bool		set_debug_variable(const char* variableName, uint64 value);
1993b4fa166SIngo Weinholdextern uint64	get_debug_variable(const char* variableName,
2003b4fa166SIngo Weinhold					uint64 defaultValue);
20106f78e9fSIngo Weinholdextern bool		unset_debug_variable(const char* variableName);
20206f78e9fSIngo Weinholdextern void		unset_all_debug_variables();
2033b4fa166SIngo Weinhold
2043b4fa166SIngo Weinholdextern bool		evaluate_debug_expression(const char* expression,
2053b4fa166SIngo Weinhold					uint64* result, bool silent);
2063b4fa166SIngo Weinholdextern int		evaluate_debug_command(const char* command);
2070deddbe3SIngo Weinholdextern status_t	parse_next_debug_command_argument(const char** expressionString,
2080deddbe3SIngo Weinhold					char* buffer, size_t bufferSize);
2093b4fa166SIngo Weinhold
2108a90d12eSIngo Weinholdextern status_t	add_debugger_command_etc(const char* name,
2118a90d12eSIngo Weinhold					debugger_command_hook func, const char* description,
2128a90d12eSIngo Weinhold					const char* usage, uint32 flags);
2138a90d12eSIngo Weinholdextern status_t	add_debugger_command_alias(const char* newName,
2148a90d12eSIngo Weinhold					const char* oldName, const char* description);
2158a90d12eSIngo Weinholdextern bool		print_debugger_command_usage(const char* command);
2165b9d5a2eSMichael Lotzextern bool		has_debugger_command(const char* command);
2178a90d12eSIngo Weinhold
218ddecb4a7SAxel Dörflerextern const char *debug_demangle_symbol(const char* symbol, char* buffer,
219ddecb4a7SAxel Dörfler					size_t bufferSize, bool* _isObjectMethod);
220ddecb4a7SAxel Dörflerextern status_t	debug_get_next_demangled_argument(uint32* _cookie,
221ddecb4a7SAxel Dörfler					const char* symbol, char* name, size_t nameSize,
222ddecb4a7SAxel Dörfler					int32* _type, size_t* _argumentLength);
2238881176fSFrançois Revol
2244535495dSIngo Weinholdextern BKernel_Thread* debug_set_debugged_thread(BKernel_Thread* thread);
2254535495dSIngo Weinholdextern BKernel_Thread* debug_get_debugged_thread();
226c3676b54SIngo Weinholdextern bool debug_is_debugged_team(team_id teamID);
227cfefeee3SIngo Weinhold
228c3676b54SIngo Weinholdextern struct arch_debug_registers* debug_get_debug_registers(int32 cpu);
229290e3dd2SIngo Weinhold
2304bf862e3SAxel Dörflerextern status_t _user_kernel_debugger(const char *message);
2314bf862e3SAxel Dörflerextern void _user_register_syslog_daemon(port_id port);
2324bf862e3SAxel Dörflerextern void	_user_debug_output(const char *userString);
23346ec2301SIngo Weinhold
2349289abf0SAxel Dörfler#ifdef __cplusplus
2359289abf0SAxel Dörfler}
2369289abf0SAxel Dörfler#endif
2379289abf0SAxel Dörfler
238c3676b54SIngo Weinhold
239c3676b54SIngo Weinhold#ifdef __cplusplus
240c3676b54SIngo Weinhold
241c3676b54SIngo Weinholdstruct DebuggedThreadSetter {
2424535495dSIngo Weinhold	DebuggedThreadSetter(Thread* thread)
243c3676b54SIngo Weinhold		:
244c3676b54SIngo Weinhold		fPreviousThread(debug_set_debugged_thread(thread))
245c3676b54SIngo Weinhold	{
246c3676b54SIngo Weinhold	}
247c3676b54SIngo Weinhold
248c3676b54SIngo Weinhold	~DebuggedThreadSetter()
249c3676b54SIngo Weinhold	{
250c3676b54SIngo Weinhold		debug_set_debugged_thread(fPreviousThread);
251c3676b54SIngo Weinhold	}
252c3676b54SIngo Weinhold
253c3676b54SIngo Weinholdprivate:
2544535495dSIngo Weinhold	Thread*	fPreviousThread;
255c3676b54SIngo Weinhold};
256c3676b54SIngo Weinhold
257c3676b54SIngo Weinhold
258c3676b54SIngo Weinhold#endif	// __cplusplus
259c3676b54SIngo Weinhold
260c3676b54SIngo Weinhold
2612b5d1dc4SAxel Dörfler#endif	/* _KERNEL_DEBUG_H */
262