2 * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
17 typedef struct debug_string_entry
{
22 static const debug_string_entry sDebugMessageStrings
[] = {
23 { "Thread not running", B_DEBUGGER_MESSAGE_THREAD_DEBUGGED
},
24 { "Debugger call", B_DEBUGGER_MESSAGE_DEBUGGER_CALL
},
25 { "Breakpoint hit", B_DEBUGGER_MESSAGE_BREAKPOINT_HIT
},
26 { "Watchpoint hit", B_DEBUGGER_MESSAGE_WATCHPOINT_HIT
},
27 { "Single step", B_DEBUGGER_MESSAGE_SINGLE_STEP
},
28 { "Before syscall", B_DEBUGGER_MESSAGE_PRE_SYSCALL
},
29 { "After syscall", B_DEBUGGER_MESSAGE_POST_SYSCALL
},
30 { "Signal received", B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED
},
31 { "Exception occurred", B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED
},
32 { "Team created", B_DEBUGGER_MESSAGE_TEAM_CREATED
},
33 { "Team deleted", B_DEBUGGER_MESSAGE_TEAM_DELETED
},
34 { "Thread created", B_DEBUGGER_MESSAGE_THREAD_CREATED
},
35 { "Thread created", B_DEBUGGER_MESSAGE_THREAD_DELETED
},
36 { "Image created", B_DEBUGGER_MESSAGE_IMAGE_CREATED
},
37 { "Image deleted", B_DEBUGGER_MESSAGE_IMAGE_DELETED
},
41 static const debug_string_entry sDebugExceptionTypeStrings
[] = {
42 { "Non-maskable interrupt", B_NON_MASKABLE_INTERRUPT
},
43 { "Machine check exception", B_MACHINE_CHECK_EXCEPTION
},
44 { "Segment violation", B_SEGMENT_VIOLATION
},
45 { "Alignment exception", B_ALIGNMENT_EXCEPTION
},
46 { "Divide error", B_DIVIDE_ERROR
},
47 { "Overflow exception", B_OVERFLOW_EXCEPTION
},
48 { "Bounds check exception", B_BOUNDS_CHECK_EXCEPTION
},
49 { "Invalid opcode exception", B_INVALID_OPCODE_EXCEPTION
},
50 { "Segment not present", B_SEGMENT_NOT_PRESENT
},
51 { "Stack fault", B_STACK_FAULT
},
52 { "General protection fault", B_GENERAL_PROTECTION_FAULT
},
53 { "Floating point exception", B_FLOATING_POINT_EXCEPTION
},
57 bool _rtDebugFlag
= true;
61 debugger(const char *message
)
63 debug_printf("%" B_PRId32
": DEBUGGER: %s\n", find_thread(NULL
), message
);
64 _kern_debugger(message
);
69 disable_debugger(int state
)
71 return _kern_disable_debugger(state
);
76 install_default_debugger(port_id debuggerPort
)
78 return _kern_install_default_debugger(debuggerPort
);
83 install_team_debugger(team_id team
, port_id debuggerPort
)
85 return _kern_install_team_debugger(team
, debuggerPort
);
90 remove_team_debugger(team_id team
)
92 return _kern_remove_team_debugger(team
);
97 debug_thread(thread_id thread
)
99 return _kern_debug_thread(thread
);
103 /** \brief Suspends the thread until a debugger has been installed for this
106 * As soon as this happens (immediately, if a debugger is already installed)
107 * the thread stops for debugging. This is desirable for debuggers that spawn
108 * their debugged teams via fork() and want the child to wait till they have
109 * installed themselves as team debugger before continuing with exec*().
113 wait_for_debugger(void)
115 _kern_wait_for_debugger();
120 set_debugger_breakpoint(void *address
)
122 return _kern_set_debugger_breakpoint(address
, 0, 0, false);
127 clear_debugger_breakpoint(void *address
)
129 return _kern_clear_debugger_breakpoint(address
, false);
134 set_debugger_watchpoint(void *address
, uint32 type
, int32 length
)
136 return _kern_set_debugger_breakpoint(address
, type
, length
, true);
141 clear_debugger_watchpoint(void *address
)
143 return _kern_clear_debugger_breakpoint(address
, true);
148 get_debug_string(const debug_string_entry
*stringEntries
,
149 const char *defaultString
, uint32 code
, char *buffer
, int32 bufferSize
)
153 if (!buffer
|| bufferSize
<= 0)
156 for (i
= 0; stringEntries
[i
].string
; i
++) {
157 if (stringEntries
[i
].code
== code
) {
158 strlcpy(buffer
, stringEntries
[i
].string
, bufferSize
);
163 snprintf(buffer
, bufferSize
, defaultString
, code
);
168 get_debug_message_string(debug_debugger_message message
, char *buffer
,
171 get_debug_string(sDebugMessageStrings
, "Unknown message %lu",
172 (uint32
)message
, buffer
, bufferSize
);
177 get_debug_exception_string(debug_exception_type exception
, char *buffer
,
180 get_debug_string(sDebugExceptionTypeStrings
, "Unknown exception %lu",
181 (uint32
)exception
, buffer
, bufferSize
);
185 // #pragma mark - Debug.h functions
196 _setDebugFlag(bool flag
)
198 bool previous
= _rtDebugFlag
;
205 _debugPrintf(const char *fmt
, ...)
214 ret
= vfprintf(stdout
, fmt
, ap
);
222 _sPrintf(const char *fmt
, ...)
232 ret
= vsnprintf(buffer
, sizeof(buffer
), fmt
, ap
);
236 _kern_debug_output(buffer
);
243 _xdebugPrintf(const char *fmt
, ...)
249 ret
= vfprintf(stdout
, fmt
, ap
);
257 _debuggerAssert(const char *file
, int line
, const char *message
)
260 snprintf(buffer
, sizeof(buffer
),
261 "Assert failed: File: %s, Line: %d, %s",
262 file
, line
, message
);
264 debug_printf("%" B_PRId32
": ASSERT: %s:%d %s\n", find_thread(NULL
), file
,
266 _kern_debugger(buffer
);
271 // TODO: Remove. Temporary debug helper.
272 // (accidently these are more or less the same as _sPrintf())
275 debug_printf(const char *format
, ...)
278 va_start(list
, format
);
280 debug_vprintf(format
, list
);
286 debug_vprintf(const char *format
, va_list args
)
289 vsnprintf(buffer
, sizeof(buffer
), format
, args
);
291 _kern_debug_output(buffer
);
296 ktrace_printf(const char *format
, ...)
299 va_start(list
, format
);
301 ktrace_vprintf(format
, list
);
308 ktrace_vprintf(const char *format
, va_list args
)
311 vsnprintf(buffer
, sizeof(buffer
), format
, args
);
313 _kern_ktrace_output(buffer
);