xref: /haiku/src/system/kernel/debug/user_debugger.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 /*
2  * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 
10 #include <debugger.h>
11 #include <kernel.h>
12 #include <KernelExport.h>
13 #include <kscheduler.h>
14 #include <ksignal.h>
15 #include <ksyscalls.h>
16 #include <sem.h>
17 #include <team.h>
18 #include <thread.h>
19 #include <thread_types.h>
20 #include <user_debugger.h>
21 #include <vm.h>
22 #include <vm_types.h>
23 #include <arch/user_debugger.h>
24 
25 //#define TRACE_USER_DEBUGGER
26 #ifdef TRACE_USER_DEBUGGER
27 #	define TRACE(x) dprintf x
28 #else
29 #	define TRACE(x) ;
30 #endif
31 
32 
33 static port_id sDefaultDebuggerPort = -1;
34 	// accessed atomically
35 
36 
37 static status_t ensure_debugger_installed(team_id teamID, port_id *port = NULL);
38 static void get_team_debug_info(team_debug_info &teamDebugInfo);
39 
40 
41 static ssize_t
42 kill_interruptable_read_port(port_id port, int32 *code, void *buffer,
43 	size_t bufferSize)
44 {
45 	return read_port_etc(port, code, buffer, bufferSize,
46 		B_KILL_CAN_INTERRUPT, 0);
47 }
48 
49 
50 static status_t
51 kill_interruptable_write_port(port_id port, int32 code, const void *buffer,
52 	size_t bufferSize)
53 {
54 	return write_port_etc(port, code, buffer, bufferSize,
55 		B_KILL_CAN_INTERRUPT, 0);
56 }
57 
58 
59 static status_t
60 debugger_write(port_id port, int32 code, const void *buffer, size_t bufferSize,
61 	bool dontWait)
62 {
63 	TRACE(("debugger_write(): thread: %ld, team %ld, port: %ld, code: %lx, message: %p, "
64 		"size: %lu, dontWait: %d\n", thread_get_current_thread()->id,
65 		thread_get_current_thread()->team->id, port, code, buffer, bufferSize,
66 		dontWait));
67 
68 	status_t error = B_OK;
69 
70 	// get the team debug info
71 	team_debug_info teamDebugInfo;
72 	get_team_debug_info(teamDebugInfo);
73 	sem_id writeLock = teamDebugInfo.debugger_write_lock;
74 
75 	// get the write lock
76 	TRACE(("debugger_write(): acquiring write lock...\n"));
77 	error = acquire_sem_etc(writeLock, 1,
78 		(dontWait ? B_RELATIVE_TIMEOUT : B_KILL_CAN_INTERRUPT), 0);
79 	if (error != B_OK) {
80 		TRACE(("debugger_write() done1: %lx\n", error));
81 		return error;
82 	}
83 
84 	// re-get the team debug info
85 	get_team_debug_info(teamDebugInfo);
86 
87 	if (teamDebugInfo.debugger_port != port
88 		|| (teamDebugInfo.flags & B_TEAM_DEBUG_DEBUGGER_HANDOVER)) {
89 		// The debugger has changed in the meantime or we are about to be
90 		// handed over to a new debugger. In either case we don't send the
91 		// message.
92 		TRACE(("debugger_write(): %s\n",
93 			(teamDebugInfo.debugger_port != port ? "debugger port changed"
94 				: "handover flag set")));
95 	} else {
96 		TRACE(("debugger_write(): writing to port...\n"));
97 
98 		error = write_port_etc(port, code, buffer, bufferSize,
99 			(dontWait ? B_RELATIVE_TIMEOUT : B_KILL_CAN_INTERRUPT), 0);
100 	}
101 
102 	// release the write lock
103 	release_sem(writeLock);
104 
105 	TRACE(("debugger_write() done: %lx\n", error));
106 
107 	return error;
108 }
109 
110 
111 /**
112  *	For the first initialization the function must be called with \a initLock
113  *	set to \c true. If it would be possible that another thread accesses the
114  *	structure at the same time, `lock' must be held when calling the function.
115  */
116 void
117 clear_team_debug_info(struct team_debug_info *info, bool initLock)
118 {
119 	if (info) {
120 		arch_clear_team_debug_info(&info->arch_info);
121 		atomic_set(&info->flags, B_TEAM_DEBUG_DEFAULT_FLAGS);
122 		info->debugger_team = -1;
123 		info->debugger_port = -1;
124 		info->nub_thread = -1;
125 		info->nub_port = -1;
126 		info->debugger_write_lock = -1;
127 
128 		if (initLock)
129 			info->lock = 0;
130 	}
131 }
132 
133 /**
134  *  `lock' must not be held nor may interrupts be disabled.
135  *  \a info must not be a member of a team struct (or the team struct must no
136  *  longer be accessible, i.e. the team should already be removed).
137  *
138  *	In case the team is still accessible, the procedure is:
139  *	1. get `lock'
140  *	2. copy the team debug info on stack
141  *	3. call clear_team_debug_info() on the team debug info
142  *	4. release `lock'
143  *	5. call destroy_team_debug_info() on the copied team debug info
144  */
145 void
146 destroy_team_debug_info(struct team_debug_info *info)
147 {
148 	if (info) {
149 		arch_destroy_team_debug_info(&info->arch_info);
150 
151 		// delete the debugger port write lock
152 		if (info->debugger_write_lock >= 0) {
153 			delete_sem(info->debugger_write_lock);
154 			info->debugger_write_lock = -1;
155 		}
156 
157 		// delete the nub port
158 		if (info->nub_port >= 0) {
159 			set_port_owner(info->nub_port, B_CURRENT_TEAM);
160 			delete_port(info->nub_port);
161 			info->nub_port = -1;
162 		}
163 
164 		// wait for the nub thread
165 		if (info->nub_thread >= 0) {
166 			if (info->nub_thread != thread_get_current_thread()->id) {
167 				int32 result;
168 				wait_for_thread(info->nub_thread, &result);
169 			}
170 
171 			info->nub_thread = -1;
172 		}
173 
174 		atomic_set(&info->flags, 0);
175 		info->debugger_team = -1;
176 		info->debugger_port = -1;
177 	}
178 }
179 
180 
181 void
182 clear_thread_debug_info(struct thread_debug_info *info, bool dying)
183 {
184 	if (info) {
185 		arch_clear_thread_debug_info(&info->arch_info);
186 		atomic_set(&info->flags,
187 			B_THREAD_DEBUG_DEFAULT_FLAGS | (dying ? B_THREAD_DEBUG_DYING : 0));
188 		info->debug_port = -1;
189 		info->ignore_signals = 0;
190 		info->ignore_signals_once = 0;
191 	}
192 }
193 
194 
195 void
196 destroy_thread_debug_info(struct thread_debug_info *info)
197 {
198 	if (info) {
199 		arch_destroy_thread_debug_info(&info->arch_info);
200 
201 		if (info->debug_port >= 0) {
202 			delete_port(info->debug_port);
203 			info->debug_port = -1;
204 		}
205 
206 		info->ignore_signals = 0;
207 		info->ignore_signals_once = 0;
208 
209 		atomic_set(&info->flags, 0);
210 	}
211 }
212 
213 
214 void
215 user_debug_prepare_for_exec()
216 {
217 	struct thread *thread = thread_get_current_thread();
218 	struct team *team = thread->team;
219 
220 	// If a debugger is installed for the team and the thread debug stuff
221 	// initialized, changed the ownership of the debug port for the thread
222 	// to the kernel team, since exec_team() deletes all ports owned by this
223 	// team. We change the ownership back later.
224 	if (atomic_get(&team->debug_info.flags) & B_TEAM_DEBUG_DEBUGGER_INSTALLED) {
225 		// get the port
226 		port_id debugPort = -1;
227 
228 		cpu_status state = disable_interrupts();
229 		GRAB_THREAD_LOCK();
230 
231 		if (thread->debug_info.flags & B_THREAD_DEBUG_INITIALIZED)
232 			debugPort = thread->debug_info.debug_port;
233 
234 		RELEASE_THREAD_LOCK();
235 		restore_interrupts(state);
236 
237 		// set the new port ownership
238 		if (debugPort >= 0)
239 			set_port_owner(debugPort, team_get_kernel_team_id());
240 	}
241 }
242 
243 
244 void
245 user_debug_finish_after_exec()
246 {
247 	struct thread *thread = thread_get_current_thread();
248 	struct team *team = thread->team;
249 
250 	// If a debugger is installed for the team and the thread debug stuff
251 	// initialized for this thread, change the ownership of its debug port
252 	// back to this team.
253 	if (atomic_get(&team->debug_info.flags) & B_TEAM_DEBUG_DEBUGGER_INSTALLED) {
254 		// get the port
255 		port_id debugPort = -1;
256 
257 		cpu_status state = disable_interrupts();
258 		GRAB_THREAD_LOCK();
259 
260 		if (thread->debug_info.flags & B_THREAD_DEBUG_INITIALIZED)
261 			debugPort = thread->debug_info.debug_port;
262 
263 		RELEASE_THREAD_LOCK();
264 		restore_interrupts(state);
265 
266 		// set the new port ownership
267 		if (debugPort >= 0)
268 			set_port_owner(debugPort, team->id);
269 	}
270 }
271 
272 
273 void
274 init_user_debug()
275 {
276 	#ifdef ARCH_INIT_USER_DEBUG
277 		ARCH_INIT_USER_DEBUG();
278 	#endif
279 }
280 
281 
282 static void
283 get_team_debug_info(team_debug_info &teamDebugInfo)
284 {
285 	struct thread *thread = thread_get_current_thread();
286 
287 	cpu_status state = disable_interrupts();
288 	GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info);
289 
290 	memcpy(&teamDebugInfo, &thread->team->debug_info, sizeof(team_debug_info));
291 
292 	RELEASE_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info);
293 	restore_interrupts(state);
294 }
295 
296 
297 static status_t
298 thread_hit_debug_event_internal(debug_debugger_message event,
299 	const void *message, int32 size, bool requireDebugger, bool &restart)
300 {
301 	restart = false;
302 	struct thread *thread = thread_get_current_thread();
303 
304 	TRACE(("thread_hit_debug_event(): thread: %ld, event: %lu, message: %p, "
305 		"size: %ld\n", thread->id, (uint32)event, message, size));
306 
307 	// check, if there's a debug port already
308 	bool setPort = !(atomic_get(&thread->debug_info.flags)
309 		& B_THREAD_DEBUG_INITIALIZED);
310 
311 	// create a port, if there is none yet
312 	port_id port = -1;
313 	if (setPort) {
314 		char nameBuffer[128];
315 		snprintf(nameBuffer, sizeof(nameBuffer), "nub to thread %ld",
316 			thread->id);
317 
318 		port = create_port(1, nameBuffer);
319 		if (port < 0) {
320 			dprintf("thread_hit_debug_event(): Failed to create debug port: "
321 				"%s\n", strerror(port));
322 			return port;
323 		}
324 
325 		setPort = true;
326 	}
327 
328 	// check the debug info structures once more: get the debugger port, set
329 	// the thread's debug port, and update the thread's debug flags
330 	port_id deletePort = port;
331 	port_id debuggerPort = -1;
332 	port_id nubPort = -1;
333 	status_t error = B_OK;
334 	cpu_status state = disable_interrupts();
335 	GRAB_THREAD_LOCK();
336 	GRAB_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info);
337 
338 	uint32 threadFlags = thread->debug_info.flags;
339 	threadFlags &= ~B_THREAD_DEBUG_STOP;
340 	bool debuggerInstalled
341 		= (thread->team->debug_info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED);
342 	if (thread->id == thread->team->debug_info.nub_thread) {
343 		// Ugh, we're the nub thread. We shouldn't be here.
344 		TRACE(("thread_hit_debug_event(): Misdirected nub thread: %ld\n",
345 			thread->id));
346 
347 		error = B_ERROR;
348 
349 	} else if (debuggerInstalled || !requireDebugger) {
350 		if (debuggerInstalled) {
351 			debuggerPort = thread->team->debug_info.debugger_port;
352 			nubPort = thread->team->debug_info.nub_port;
353 		}
354 
355 		if (setPort) {
356 			if (threadFlags & B_THREAD_DEBUG_INITIALIZED) {
357 				// someone created a port for us (the port we've created will
358 				// be deleted below)
359 				port = thread->debug_info.debug_port;
360 			} else {
361 				thread->debug_info.debug_port = port;
362 				deletePort = -1;	// keep the port
363 				threadFlags |= B_THREAD_DEBUG_INITIALIZED;
364 			}
365 		} else {
366 			if (threadFlags & B_THREAD_DEBUG_INITIALIZED) {
367 				port = thread->debug_info.debug_port;
368 			} else {
369 				// someone deleted our port
370 				error = B_ERROR;
371 			}
372 		}
373 	} else
374 		error = B_ERROR;
375 
376 	// update the flags
377 	if (error == B_OK)
378 		threadFlags |= B_THREAD_DEBUG_STOPPED;
379 	atomic_set(&thread->debug_info.flags, threadFlags);
380 
381 	RELEASE_TEAM_DEBUG_INFO_LOCK(thread->team->debug_info);
382 	RELEASE_THREAD_LOCK();
383 	restore_interrupts(state);
384 
385 	// delete the superfluous port
386 	if (deletePort >= 0)
387 		delete_port(deletePort);
388 
389 	if (error != B_OK) {
390 		TRACE(("thread_hit_debug_event() error: thread: %ld, error: %lx\n",
391 			thread->id, error));
392 		return error;
393 	}
394 
395 	// send a message to the debugger port
396 	if (debuggerInstalled) {
397 		// update the message's origin info first
398 		debug_origin *origin = (debug_origin *)message;
399 		origin->thread = thread->id;
400 		origin->team = thread->team->id;
401 		origin->nub_port = nubPort;
402 
403 		TRACE(("thread_hit_debug_event(): thread: %ld, sending message to "
404 			"debugger port %ld\n", thread->id, debuggerPort));
405 
406 		error = debugger_write(debuggerPort, event, message, size, false);
407 	}
408 
409 	status_t result = B_THREAD_DEBUG_HANDLE_EVENT;
410 	bool singleStep = false;
411 
412 	if (error == B_OK) {
413 		bool done = false;
414 		while (!done) {
415 			// read a command from the debug port
416 			int32 command;
417 			debugged_thread_message_data commandMessage;
418 			ssize_t commandMessageSize = kill_interruptable_read_port(port,
419 				&command, &commandMessage, sizeof(commandMessage));
420 			if (commandMessageSize < 0) {
421 				error = commandMessageSize;
422 				TRACE(("thread_hit_debug_event(): thread: %ld, failed "
423 					"to receive message from port %ld: %lx\n",
424 					thread->id, port, error));
425 				break;
426 			}
427 
428 			switch (command) {
429 				case B_DEBUGGED_THREAD_MESSAGE_CONTINUE:
430 					TRACE(("thread_hit_debug_event(): thread: %ld: "
431 						"B_DEBUGGED_THREAD_MESSAGE_CONTINUE\n",
432 						thread->id));
433 					result = commandMessage.continue_thread.handle_event;
434 
435 					singleStep = commandMessage.continue_thread.single_step;
436 					done = true;
437 					break;
438 
439 				case B_DEBUGGED_THREAD_SET_CPU_STATE:
440 				{
441 					TRACE(("thread_hit_debug_event(): thread: %ld: "
442 						"B_DEBUGGED_THREAD_SET_CPU_STATE\n",
443 						thread->id));
444 					arch_set_debug_cpu_state(
445 						&commandMessage.set_cpu_state.cpu_state);
446 
447 					break;
448 				}
449 
450 				case B_DEBUGGED_THREAD_GET_CPU_STATE:
451 				{
452 					port_id replyPort = commandMessage.get_cpu_state.reply_port;
453 
454 					// prepare the message
455 					debug_nub_get_cpu_state_reply replyMessage;
456 					replyMessage.error = B_OK;
457 					replyMessage.message = event;
458 					arch_get_debug_cpu_state(&replyMessage.cpu_state);
459 
460 					// send it
461 					error = kill_interruptable_write_port(replyPort, event,
462 						&replyMessage, sizeof(replyMessage));
463 
464 					break;
465 				}
466 
467 				case B_DEBUGGED_THREAD_DEBUGGER_CHANGED:
468 				{
469 					// Check, if the debugger really changed, i.e. is different
470 					// than the one we know.
471 					team_debug_info teamDebugInfo;
472 					get_team_debug_info(teamDebugInfo);
473 
474 					if (teamDebugInfo.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED) {
475 						if (!debuggerInstalled
476 							|| teamDebugInfo.debugger_port != debuggerPort) {
477 							// debugger was installed or has changed: restart
478 							// this function
479 							restart = true;
480 							done = true;
481 						}
482 					} else {
483 						if (debuggerInstalled) {
484 							// debugger is gone: continue the thread normally
485 							done = true;
486 						}
487 					}
488 
489 					break;
490 				}
491 			}
492 		}
493 	} else {
494 		TRACE(("thread_hit_debug_event(): thread: %ld, failed to send "
495 			"message to debugger port %ld: %lx\n", thread->id,
496 			debuggerPort, error));
497 	}
498 
499 	// update the thread debug info
500 	bool destroyThreadInfo = false;
501 	thread_debug_info threadDebugInfo;
502 
503 	state = disable_interrupts();
504 	GRAB_THREAD_LOCK();
505 
506 	// check, if the team is still being debugged
507 	int32 teamDebugFlags = atomic_get(&thread->team->debug_info.flags);
508 	if (teamDebugFlags & B_TEAM_DEBUG_DEBUGGER_INSTALLED) {
509 		// update the single-step flag
510 		if (singleStep) {
511 			atomic_or(&thread->debug_info.flags,
512 				B_THREAD_DEBUG_SINGLE_STEP);
513 		} else {
514 			atomic_and(&thread->debug_info.flags,
515 				~B_THREAD_DEBUG_SINGLE_STEP);
516 		}
517 
518 		// unset the "stopped" state
519 		atomic_and(&thread->debug_info.flags, ~B_THREAD_DEBUG_STOPPED);
520 
521 	} else {
522 		// the debugger is gone: cleanup our info completely
523 		threadDebugInfo = thread->debug_info;
524 		clear_thread_debug_info(&thread->debug_info, false);
525 		destroyThreadInfo = true;
526 	}
527 
528 	RELEASE_THREAD_LOCK();
529 	restore_interrupts(state);
530 
531 	if (destroyThreadInfo)
532 		destroy_thread_debug_info(&threadDebugInfo);
533 
534 	return (error == B_OK ? result : error);
535 }
536 
537 
538 static status_t
539 thread_hit_debug_event(debug_debugger_message event, const void *message,
540 	int32 size, bool requireDebugger)
541 {
542 	status_t result;
543 	bool restart;
544 	do {
545 		restart = false;
546 		result = thread_hit_debug_event_internal(event, message, size,
547 			requireDebugger, restart);
548 	} while (result >= 0 && restart);
549 
550 	return result;
551 }
552 
553 
554 void
555 user_debug_pre_syscall(uint32 syscall, void *args)
556 {
557 	// check whether a debugger is installed
558 	struct thread *thread = thread_get_current_thread();
559 	int32 teamDebugFlags = atomic_get(&thread->team->debug_info.flags);
560 	if (!(teamDebugFlags & B_TEAM_DEBUG_DEBUGGER_INSTALLED))
561 		return;
562 
563 	// check whether pre-syscall tracing is enabled for team or thread
564 	int32 threadDebugFlags = atomic_get(&thread->debug_info.flags);
565 	if (!(teamDebugFlags & B_TEAM_DEBUG_PRE_SYSCALL)
566 			&& !(threadDebugFlags & B_THREAD_DEBUG_PRE_SYSCALL)) {
567 		return;
568 	}
569 
570 	// prepare the message
571 	debug_pre_syscall message;
572 	message.syscall = syscall;
573 
574 	// copy the syscall args
575 	if (syscall < (uint32)kSyscallCount) {
576 		if (kSyscallInfos[syscall].parameter_size > 0)
577 			memcpy(message.args, args, kSyscallInfos[syscall].parameter_size);
578 	}
579 
580 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_PRE_SYSCALL, &message,
581 		sizeof(message), true);
582 }
583 
584 
585 void
586 user_debug_post_syscall(uint32 syscall, void *args, uint64 returnValue,
587 	bigtime_t startTime)
588 {
589 	// check whether a debugger is installed
590 	struct thread *thread = thread_get_current_thread();
591 	int32 teamDebugFlags = atomic_get(&thread->team->debug_info.flags);
592 	if (!(teamDebugFlags & B_TEAM_DEBUG_DEBUGGER_INSTALLED))
593 		return;
594 
595 	// check whether post-syscall tracing is enabled for team or thread
596 	int32 threadDebugFlags = atomic_get(&thread->debug_info.flags);
597 	if (!(teamDebugFlags & B_TEAM_DEBUG_POST_SYSCALL)
598 			&& !(threadDebugFlags & B_THREAD_DEBUG_POST_SYSCALL)) {
599 		return;
600 	}
601 
602 	// prepare the message
603 	debug_post_syscall message;
604 	message.start_time = startTime;
605 	message.end_time = system_time();
606 	message.return_value = returnValue;
607 	message.syscall = syscall;
608 
609 	// copy the syscall args
610 	if (syscall < (uint32)kSyscallCount) {
611 		if (kSyscallInfos[syscall].parameter_size > 0)
612 			memcpy(message.args, args, kSyscallInfos[syscall].parameter_size);
613 	}
614 
615 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_POST_SYSCALL, &message,
616 		sizeof(message), true);
617 }
618 
619 
620 /**	\brief To be called when an unhandled processor fault (exception/error)
621  *		   occurred.
622  *	\param fault The debug_why_stopped value identifying the kind of fault.
623  *	\return \c true, if the caller shall continue normally, i.e. usually send
624  *			a deadly signal. \c false, if the debugger insists to continue the
625  *			program (e.g. because it has solved the removed the cause of the
626  *			problem).
627  */
628 bool
629 user_debug_exception_occurred(debug_exception_type exception, int signal)
630 {
631 	// ensure that a debugger is installed for this team
632 	struct thread *thread = thread_get_current_thread();
633 	port_id nubPort;
634 	status_t error = ensure_debugger_installed(B_CURRENT_TEAM, &nubPort);
635 	if (error != B_OK) {
636 		dprintf("user_debug_exception_occurred(): Failed to install debugger: "
637 			"thread: %ld: %s\n", thread->id, strerror(error));
638 		return error;
639 	}
640 
641 	// prepare the message
642 	debug_exception_occurred message;
643 	message.exception = exception;
644 	message.signal = signal;
645 
646 	status_t result = thread_hit_debug_event(
647 		B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED, &message, sizeof(message), true);
648 	return (result != B_THREAD_DEBUG_IGNORE_EVENT);
649 }
650 
651 
652 bool
653 user_debug_handle_signal(int signal, struct sigaction *handler, bool deadly)
654 {
655 	// check, if a debugger is installed and is interested in signals
656 	struct thread *thread = thread_get_current_thread();
657 	int32 teamDebugFlags = atomic_get(&thread->team->debug_info.flags);
658 	if (~teamDebugFlags
659 		& (B_TEAM_DEBUG_DEBUGGER_INSTALLED | B_TEAM_DEBUG_SIGNALS)) {
660 		return true;
661 	}
662 
663 	// prepare the message
664 	debug_signal_received message;
665 	message.signal = signal;
666 	message.handler = *handler;
667 	message.deadly = deadly;
668 
669 	status_t result = thread_hit_debug_event(B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED,
670 		&message, sizeof(message), true);
671 	return (result != B_THREAD_DEBUG_IGNORE_EVENT);
672 }
673 
674 
675 void
676 user_debug_stop_thread()
677 {
678 	// ensure that a debugger is installed for this team
679 	struct thread *thread = thread_get_current_thread();
680 	port_id nubPort;
681 	status_t error = ensure_debugger_installed(B_CURRENT_TEAM, &nubPort);
682 	if (error != B_OK) {
683 		dprintf("user_debug_stop_thread(): Failed to install debugger: "
684 			"thread: %ld: %s\n", thread->id, strerror(error));
685 		return;
686 	}
687 
688 	// prepare the message
689 	debug_thread_debugged message;
690 
691 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_THREAD_DEBUGGED, &message,
692 		sizeof(message), true);
693 }
694 
695 
696 void
697 user_debug_team_created(team_id teamID)
698 {
699 	// check, if a debugger is installed and is interested in team creation
700 	// events
701 	struct thread *thread = thread_get_current_thread();
702 	int32 teamDebugFlags = atomic_get(&thread->team->debug_info.flags);
703 	if (~teamDebugFlags
704 		& (B_TEAM_DEBUG_DEBUGGER_INSTALLED | B_TEAM_DEBUG_TEAM_CREATION)) {
705 		return;
706 	}
707 
708 	// prepare the message
709 	debug_team_created message;
710 	message.new_team = teamID;
711 
712 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_TEAM_CREATED, &message,
713 		sizeof(message), true);
714 }
715 
716 
717 void
718 user_debug_team_deleted(team_id teamID, port_id debuggerPort)
719 {
720 	if (debuggerPort >= 0) {
721 		TRACE(("user_debug_team_deleted(team: %ld, debugger port: %ld)\n",
722 			teamID, debuggerPort));
723 
724 		debug_team_deleted message;
725 		message.origin.thread = -1;
726 		message.origin.team = teamID;
727 		message.origin.nub_port = -1;
728 		write_port_etc(debuggerPort, B_DEBUGGER_MESSAGE_TEAM_DELETED, &message,
729 			sizeof(message), B_RELATIVE_TIMEOUT, 0);
730 			// TODO: Would it be OK to wait here?
731 	}
732 }
733 
734 
735 void
736 user_debug_thread_created(thread_id threadID)
737 {
738 	// check, if a debugger is installed and is interested in thread events
739 	struct thread *thread = thread_get_current_thread();
740 	int32 teamDebugFlags = atomic_get(&thread->team->debug_info.flags);
741 	if (~teamDebugFlags
742 		& (B_TEAM_DEBUG_DEBUGGER_INSTALLED | B_TEAM_DEBUG_THREADS)) {
743 		return;
744 	}
745 
746 	// prepare the message
747 	debug_thread_created message;
748 	message.new_thread = threadID;
749 
750 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_THREAD_CREATED, &message,
751 		sizeof(message), true);
752 }
753 
754 
755 void
756 user_debug_thread_deleted(team_id teamID, thread_id threadID)
757 {
758 	// get the team debug flags and debugger port
759 	cpu_status state = disable_interrupts();
760 	GRAB_TEAM_LOCK();
761 
762 	struct team *team = team_get_team_struct_locked(teamID);
763 
764 	int32 teamDebugFlags = 0;
765 	port_id debuggerPort = -1;
766 	if (team) {
767 		GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
768 
769 		teamDebugFlags = atomic_get(&team->debug_info.flags);
770 		debuggerPort = team->debug_info.debugger_port;
771 
772 		RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
773 	}
774 
775 	RELEASE_TEAM_LOCK();
776 	restore_interrupts(state);
777 
778 	// check, if a debugger is installed and is interested in thread events
779 	if (~teamDebugFlags
780 		& (B_TEAM_DEBUG_DEBUGGER_INSTALLED | B_TEAM_DEBUG_THREADS)) {
781 		return;
782 	}
783 
784 	// notify the debugger
785 	if (debuggerPort >= 0) {
786 		debug_thread_deleted message;
787 		message.origin.thread = threadID;
788 		message.origin.team = teamID;
789 		message.origin.nub_port = -1;
790 		debugger_write(debuggerPort, B_DEBUGGER_MESSAGE_THREAD_DELETED,
791 			&message, sizeof(message), true);
792 			// TODO: Would it be OK to wait here?
793 	}
794 }
795 
796 
797 void
798 user_debug_image_created(const image_info *imageInfo)
799 {
800 	// check, if a debugger is installed and is interested in image events
801 	struct thread *thread = thread_get_current_thread();
802 	int32 teamDebugFlags = atomic_get(&thread->team->debug_info.flags);
803 	if (~teamDebugFlags
804 		& (B_TEAM_DEBUG_DEBUGGER_INSTALLED | B_TEAM_DEBUG_IMAGES)) {
805 		return;
806 	}
807 
808 	// prepare the message
809 	debug_image_created message;
810 	memcpy(&message.info, imageInfo, sizeof(image_info));
811 
812 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_IMAGE_CREATED, &message,
813 		sizeof(message), true);
814 }
815 
816 
817 void
818 user_debug_image_deleted(const image_info *imageInfo)
819 {
820 	// check, if a debugger is installed and is interested in image events
821 	struct thread *thread = thread_get_current_thread();
822 	int32 teamDebugFlags = atomic_get(&thread->team->debug_info.flags);
823 	if (~teamDebugFlags
824 		& (B_TEAM_DEBUG_DEBUGGER_INSTALLED | B_TEAM_DEBUG_IMAGES)) {
825 		return;
826 	}
827 
828 	// prepare the message
829 	debug_image_deleted message;
830 	memcpy(&message.info, imageInfo, sizeof(image_info));
831 
832 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_IMAGE_CREATED, &message,
833 		sizeof(message), true);
834 }
835 
836 
837 void
838 user_debug_breakpoint_hit(bool software)
839 {
840 	// ensure that a debugger is installed for this team
841 	struct thread *thread = thread_get_current_thread();
842 	port_id nubPort;
843 	status_t error = ensure_debugger_installed(B_CURRENT_TEAM, &nubPort);
844 	if (error != B_OK) {
845 		dprintf("user_debug_breakpoint_hit(): Failed to install debugger: "
846 			"thread: %ld: %s\n", thread->id, strerror(error));
847 		return;
848 	}
849 
850 	// prepare the message
851 	debug_breakpoint_hit message;
852 	message.software = software;
853 	arch_get_debug_cpu_state(&message.cpu_state);
854 
855 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_BREAKPOINT_HIT, &message,
856 		sizeof(message), true);
857 }
858 
859 
860 void
861 user_debug_watchpoint_hit()
862 {
863 	// ensure that a debugger is installed for this team
864 	struct thread *thread = thread_get_current_thread();
865 	port_id nubPort;
866 	status_t error = ensure_debugger_installed(B_CURRENT_TEAM, &nubPort);
867 	if (error != B_OK) {
868 		dprintf("user_debug_watchpoint_hit(): Failed to install debugger: "
869 			"thread: %ld: %s\n", thread->id, strerror(error));
870 		return;
871 	}
872 
873 	// prepare the message
874 	debug_watchpoint_hit message;
875 	arch_get_debug_cpu_state(&message.cpu_state);
876 
877 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_WATCHPOINT_HIT, &message,
878 		sizeof(message), true);
879 }
880 
881 
882 void
883 user_debug_single_stepped()
884 {
885 	// ensure that a debugger is installed for this team
886 	struct thread *thread = thread_get_current_thread();
887 	port_id nubPort;
888 	status_t error = ensure_debugger_installed(B_CURRENT_TEAM, &nubPort);
889 	if (error != B_OK) {
890 		dprintf("user_debug_watchpoint_hit(): Failed to install debugger: "
891 			"thread: %ld: %s\n", thread->id, strerror(error));
892 		return;
893 	}
894 
895 	// prepare the message
896 	debug_single_step message;
897 	arch_get_debug_cpu_state(&message.cpu_state);
898 
899 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_SINGLE_STEP, &message,
900 		sizeof(message), true);
901 }
902 
903 
904 /**	\brief Called by the debug nub thread of a team to broadcast a message
905  *		   that are initialized for debugging (and thus have a debug port).
906  */
907 static void
908 broadcast_debugged_thread_message(struct thread *nubThread, int32 code,
909 	const void *message, int32 size)
910 {
911 	// iterate through the threads
912 	thread_info threadInfo;
913 	int32 cookie = 0;
914 	while (get_next_thread_info(nubThread->team->id, &cookie, &threadInfo)
915 			== B_OK) {
916 		// find the thread and get its debug port
917 		cpu_status state = disable_interrupts();
918 		GRAB_THREAD_LOCK();
919 
920 		port_id threadDebugPort = -1;
921 		thread_id threadID = -1;
922 		struct thread *thread
923 			= thread_get_thread_struct_locked(threadInfo.thread);
924 		if (thread && thread != nubThread && thread->team == nubThread->team
925 			&& thread->debug_info.flags & B_THREAD_DEBUG_INITIALIZED) {
926 			threadDebugPort = thread->debug_info.debug_port;
927 			threadID = thread->id;
928 		}
929 
930 		RELEASE_THREAD_LOCK();
931 		restore_interrupts(state);
932 
933 		// send the message to the thread
934 		if (threadDebugPort >= 0) {
935 			status_t error = kill_interruptable_write_port(threadDebugPort,
936 				code, message, size);
937 			if (error != B_OK) {
938 				TRACE(("broadcast_debugged_thread_message(): Failed to send "
939 					"message to thread %ld: %lx\n", threadID, error));
940 			}
941 		}
942 	}
943 }
944 
945 
946 static void
947 nub_thread_cleanup(struct thread *nubThread)
948 {
949 	TRACE(("nub_thread_cleanup(%ld): debugger port: %ld\n", nubThread->id,
950 		nubThread->team->debug_info.debugger_port));
951 
952 	team_debug_info teamDebugInfo;
953 	bool destroyDebugInfo = false;
954 
955 	cpu_status state = disable_interrupts();
956 	GRAB_TEAM_LOCK();
957 	GRAB_TEAM_DEBUG_INFO_LOCK(nubThread->team->debug_info);
958 
959 	team_debug_info &info = nubThread->team->debug_info;
960 	if (info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED
961 		&& info.nub_thread == nubThread->id) {
962 		teamDebugInfo = info;
963 		clear_team_debug_info(&info, false);
964 		destroyDebugInfo = true;
965 	}
966 
967 	RELEASE_TEAM_DEBUG_INFO_LOCK(nubThread->team->debug_info);
968 	RELEASE_TEAM_LOCK();
969 	restore_interrupts(state);
970 
971 	if (destroyDebugInfo)
972 		destroy_team_debug_info(&teamDebugInfo);
973 
974 	// notify all threads that the debugger is gone
975 	broadcast_debugged_thread_message(nubThread,
976 		B_DEBUGGED_THREAD_DEBUGGER_CHANGED, NULL, 0);
977 }
978 
979 
980 /**	\brief Reads data from user memory.
981  *
982  *	Tries to read \a size bytes of data from user memory address \a address
983  *	into the supplied buffer \a buffer. If only a part could be read the
984  *	function won't fail. The number of bytes actually read is return through
985  *	\a bytesRead.
986  *
987  *	\param address The user memory address from which to read.
988  *	\param buffer The buffer into which to write.
989  *	\param size The number of bytes to read.
990  *	\param bytesRead Will be set to the number of bytes actually read.
991  *	\return \c B_OK, if reading went fine. Then \a bytesRead will be set to
992  *			the amount of data actually read. An error indicates that nothing
993  *			has been read.
994  */
995 static status_t
996 read_user_memory(const void *_address, void *_buffer, int32 size,
997 	int32 &bytesRead)
998 {
999 	const char *address = (const char*)_address;
1000 	char *buffer = (char*)_buffer;
1001 
1002 	// check the parameters
1003 	if (!IS_USER_ADDRESS(address))
1004 		return B_BAD_ADDRESS;
1005 	if (size <= 0)
1006 		return B_BAD_VALUE;
1007 
1008 	// If the region to be read crosses page boundaries, we split it up into
1009 	// smaller chunks.
1010 	status_t error = B_OK;
1011 	bytesRead = 0;
1012 	while (size > 0) {
1013 		// check whether we're still in user address space
1014 		if (!IS_USER_ADDRESS(address)) {
1015 			error = B_BAD_ADDRESS;
1016 			break;
1017 		}
1018 
1019 		// don't cross page boundaries in a single read
1020 		int32 toRead = size;
1021 		int32 maxRead = B_PAGE_SIZE - (addr_t)address % B_PAGE_SIZE;
1022 		if (toRead > maxRead)
1023 			toRead = maxRead;
1024 
1025 		error = user_memcpy(buffer, address, toRead);
1026 		if (error != B_OK)
1027 			break;
1028 
1029 		bytesRead += toRead;
1030 		address += toRead;
1031 		buffer += toRead;
1032 		size -= toRead;
1033 	}
1034 
1035 	// If reading fails, we only fail, if we haven't read anything yet.
1036 	if (error != B_OK) {
1037 		if (bytesRead > 0)
1038 			return B_OK;
1039 		return error;
1040 	}
1041 
1042 	return B_OK;
1043 }
1044 
1045 
1046 static status_t
1047 write_user_memory(void *_address, const void *_buffer, int32 size,
1048 	int32 &bytesWritten)
1049 {
1050 	char *address = (char*)_address;
1051 	const char *buffer = (const char*)_buffer;
1052 
1053 	// check the parameters
1054 	if (!IS_USER_ADDRESS(address))
1055 		return B_BAD_ADDRESS;
1056 	if (size <= 0)
1057 		return B_BAD_VALUE;
1058 
1059 	// If the region to be written crosses area boundaries, we split it up into
1060 	// smaller chunks.
1061 	status_t error = B_OK;
1062 	bytesWritten = 0;
1063 	while (size > 0) {
1064 		// check whether we're still in user address space
1065 		if (!IS_USER_ADDRESS(address)) {
1066 			error = B_BAD_ADDRESS;
1067 			break;
1068 		}
1069 
1070 		// get the area for the address (we need to use _user_area_for(), since
1071 		// we're looking for a user area)
1072 		area_id area = _user_area_for((void*)address);
1073 		if (area < 0) {
1074 			TRACE(("write_user_memory(): area not found for address: %p: "
1075 				"%lx\n", address, area));
1076 			error = area;
1077 			break;
1078 		}
1079 
1080 		area_info areaInfo;
1081 		status_t error = get_area_info(area, &areaInfo);
1082 		if (error != B_OK) {
1083 			TRACE(("write_user_memory(): failed to get info for area %ld: "
1084 				"%lx\n", area, error));
1085 			error = B_BAD_ADDRESS;
1086 			break;
1087 		}
1088 
1089 		// restrict this round of writing to the found area
1090 		int32 toWrite = size;
1091 		int32 maxWrite = (char*)areaInfo.address + areaInfo.size - address;
1092 		if (toWrite > maxWrite)
1093 			toWrite = maxWrite;
1094 
1095 		// if the area is read-only, we temporarily need to make it writable
1096 		bool protectionChanged = false;
1097 		if (!(areaInfo.protection & (B_WRITE_AREA | B_KERNEL_WRITE_AREA))) {
1098 			error = set_area_protection(area,
1099 				areaInfo.protection | B_WRITE_AREA);
1100 			if (error != B_OK) {
1101 				TRACE(("write_user_memory(): failed to set new protection for "
1102 					"area %ld: %lx\n", area, error));
1103 				break;
1104 			}
1105 			protectionChanged = true;
1106 		}
1107 
1108 		// copy the memory
1109 		error = user_memcpy(address, buffer, toWrite);
1110 
1111 		// reset the area protection
1112 		if (protectionChanged)
1113 			set_area_protection(area, areaInfo.protection);
1114 
1115 		if (error != B_OK) {
1116 			TRACE(("write_user_memory(): user_memcpy() failed: %lx\n", error));
1117 			break;
1118 		}
1119 
1120 		bytesWritten += toWrite;
1121 		address += toWrite;
1122 		buffer += toWrite;
1123 		size -= toWrite;
1124 	}
1125 
1126 	// If writing fails, we only fail, if we haven't written anything yet.
1127 	if (error != B_OK) {
1128 		if (bytesWritten > 0)
1129 			return B_OK;
1130 		return error;
1131 	}
1132 
1133 	return B_OK;
1134 }
1135 
1136 
1137 /**	\brief Debug nub thread helper function that returns the debug port of
1138  *		   a thread of the same team.
1139  */
1140 static status_t
1141 debug_nub_thread_get_thread_debug_port(struct thread *nubThread,
1142 	thread_id threadID, port_id &threadDebugPort)
1143 {
1144 	status_t result = B_OK;
1145 	threadDebugPort = -1;
1146 
1147 	cpu_status state = disable_interrupts();
1148 	GRAB_THREAD_LOCK();
1149 
1150 	struct thread *thread = thread_get_thread_struct_locked(threadID);
1151 	if (thread) {
1152 		if (thread->team != nubThread->team)
1153 			result = B_BAD_VALUE;
1154 		else if (thread->debug_info.flags & B_THREAD_DEBUG_STOPPED)
1155 			threadDebugPort = thread->debug_info.debug_port;
1156 		else
1157 			result = B_BAD_VALUE;
1158 	} else
1159 		result = B_BAD_THREAD_ID;
1160 
1161 	RELEASE_THREAD_LOCK();
1162 	restore_interrupts(state);
1163 
1164 	if (result == B_OK && threadDebugPort < 0)
1165 		result = B_ERROR;
1166 
1167 	return result;
1168 }
1169 
1170 
1171 static status_t
1172 debug_nub_thread(void *)
1173 {
1174 	struct thread *nubThread = thread_get_current_thread();
1175 
1176 	// check, if we're still the current nub thread and get our port
1177 	cpu_status state = disable_interrupts();
1178 
1179 	GRAB_TEAM_DEBUG_INFO_LOCK(nubThread->team->debug_info);
1180 
1181 	if (nubThread->team->debug_info.nub_thread != nubThread->id)
1182 		return 0;
1183 
1184 	port_id port = nubThread->team->debug_info.nub_port;
1185 	sem_id writeLock = nubThread->team->debug_info.debugger_write_lock;
1186 
1187 	RELEASE_TEAM_DEBUG_INFO_LOCK(nubThread->team->debug_info);
1188 	restore_interrupts(state);
1189 
1190 	TRACE(("debug_nub_thread() thread: %ld, team %ld, nub port: %ld\n",
1191 		nubThread->id, nubThread->team->id, port));
1192 
1193 	// notify all threads that a debugger has been installed
1194 	broadcast_debugged_thread_message(nubThread,
1195 		B_DEBUGGED_THREAD_DEBUGGER_CHANGED, NULL, 0);
1196 
1197 	// command processing loop
1198 	while (true) {
1199 		int32 command;
1200 		debug_nub_message_data message;
1201 		ssize_t messageSize = kill_interruptable_read_port(port, &command,
1202 			&message, sizeof(message));
1203 
1204 		if (messageSize < 0) {
1205 			// The port is not longer valid or we were interrupted by a kill
1206 			// signal: If we are still listed in the team's debug info as nub
1207 			// thread, we need to update that.
1208 			nub_thread_cleanup(nubThread);
1209 
1210 			TRACE(("nub thread %ld: terminating: %lx\n", nubThread->id,
1211 				messageSize));
1212 
1213 			return messageSize;
1214 		}
1215 
1216 		bool sendReply = false;
1217 		union {
1218 			debug_nub_read_memory_reply			read_memory;
1219 			debug_nub_write_memory_reply		write_memory;
1220 			debug_nub_get_cpu_state_reply		get_cpu_state;
1221 			debug_nub_set_breakpoint_reply		set_breakpoint;
1222 			debug_nub_set_watchpoint_reply		set_watchpoint;
1223 			debug_nub_get_signal_masks_reply	get_signal_masks;
1224 			debug_nub_get_signal_handler_reply	get_signal_handler;
1225 		} reply;
1226 		int32 replySize = 0;
1227 		port_id replyPort = -1;
1228 
1229 		// process the command
1230 		switch (command) {
1231 			case B_DEBUG_MESSAGE_READ_MEMORY:
1232 			{
1233 				// get the parameters
1234 				replyPort = message.read_memory.reply_port;
1235 				void *address = message.read_memory.address;
1236 				int32 size = message.read_memory.size;
1237 				status_t result = B_OK;
1238 
1239 				// check the parameters
1240 				if (!IS_USER_ADDRESS(address))
1241 					result = B_BAD_ADDRESS;
1242 				else if (size <= 0 || size > B_MAX_READ_WRITE_MEMORY_SIZE)
1243 					result = B_BAD_VALUE;
1244 
1245 				// read the memory
1246 				int32 bytesRead = 0;
1247 				if (result == B_OK) {
1248 					result = read_user_memory(address, reply.read_memory.data,
1249 						size, bytesRead);
1250 				}
1251 				reply.read_memory.error = result;
1252 
1253 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_READ_MEMORY: "
1254 					"reply port: %ld, address: %p, size: %ld, result: %lx, "
1255 					"read: %ld\n", nubThread->id, replyPort, address, size,
1256 					result, bytesRead));
1257 
1258 				// send only as much data as necessary
1259 				reply.read_memory.size = bytesRead;
1260 				replySize = reply.read_memory.data + bytesRead - (char*)&reply;
1261 				sendReply = true;
1262 				break;
1263 			}
1264 
1265 			case B_DEBUG_MESSAGE_WRITE_MEMORY:
1266 			{
1267 				// get the parameters
1268 				replyPort = message.write_memory.reply_port;
1269 				void *address = message.write_memory.address;
1270 				int32 size = message.write_memory.size;
1271 				const char *data = message.write_memory.data;
1272 				int32 realSize = (char*)&message + messageSize - data;
1273 				status_t result = B_OK;
1274 
1275 				// check the parameters
1276 				if (!IS_USER_ADDRESS(address))
1277 					result = B_BAD_ADDRESS;
1278 				else if (size <= 0 || size > realSize)
1279 					result = B_BAD_VALUE;
1280 
1281 				// write the memory
1282 				int32 bytesWritten = 0;
1283 				if (result == B_OK) {
1284 					result = write_user_memory(address, data, size,
1285 						bytesWritten);
1286 				}
1287 				reply.write_memory.error = result;
1288 
1289 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_WRITE_MEMORY: "
1290 					"reply port: %ld, address: %p, size: %ld, result: %lx, "
1291 					"written: %ld\n", nubThread->id, replyPort, address, size,
1292 					result, bytesWritten));
1293 
1294 				reply.write_memory.size = bytesWritten;
1295 				sendReply = true;
1296 				replySize = sizeof(debug_nub_write_memory_reply);
1297 				break;
1298 			}
1299 
1300 			case B_DEBUG_MESSAGE_SET_TEAM_FLAGS:
1301 			{
1302 				// get the parameters
1303 				int32 flags = message.set_team_flags.flags
1304 					& B_TEAM_DEBUG_USER_FLAG_MASK;
1305 
1306 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_TEAM_FLAGS: "
1307 					"flags: %lx\n", nubThread->id, flags));
1308 
1309 				struct team *team = thread_get_current_thread()->team;
1310 
1311 				// set the flags
1312 				cpu_status state = disable_interrupts();
1313 				GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
1314 
1315 				flags |= team->debug_info.flags & B_TEAM_DEBUG_KERNEL_FLAG_MASK;
1316 				atomic_set(&team->debug_info.flags, flags);
1317 
1318 				RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
1319 				restore_interrupts(state);
1320 
1321 				break;
1322 			}
1323 
1324 			case B_DEBUG_MESSAGE_SET_THREAD_FLAGS:
1325 			{
1326 				// get the parameters
1327 				thread_id threadID = message.set_thread_flags.thread;
1328 				int32 flags = message.set_thread_flags.flags
1329 					& B_THREAD_DEBUG_USER_FLAG_MASK;
1330 
1331 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_THREAD_FLAGS: "
1332 					"thread: %ld, flags: %lx\n", nubThread->id, threadID,
1333 					flags));
1334 
1335 				// set the flags
1336 				cpu_status state = disable_interrupts();
1337 				GRAB_THREAD_LOCK();
1338 
1339 				struct thread *thread
1340 					= thread_get_thread_struct_locked(threadID);
1341 				if (thread
1342 					&& thread->team == thread_get_current_thread()->team) {
1343 					flags |= thread->debug_info.flags
1344 						& B_THREAD_DEBUG_KERNEL_FLAG_MASK;
1345 					atomic_set(&thread->debug_info.flags, flags);
1346 				}
1347 
1348 				RELEASE_THREAD_LOCK();
1349 				restore_interrupts(state);
1350 
1351 				break;
1352 			}
1353 
1354 			case B_DEBUG_MESSAGE_CONTINUE_THREAD:
1355 			{
1356 				// get the parameters
1357 				thread_id threadID;
1358 				uint32 handleEvent;
1359 				bool singleStep;
1360 
1361 				threadID = message.continue_thread.thread;
1362 				handleEvent = message.continue_thread.handle_event;
1363 				singleStep = message.continue_thread.single_step;
1364 
1365 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CONTINUE_THREAD: "
1366 					"thread: %ld, handle event: %lu, single step: %d\n",
1367 					nubThread->id, threadID, handleEvent, singleStep));
1368 
1369 				// find the thread and get its debug port
1370 				port_id threadDebugPort = -1;
1371 				status_t result = debug_nub_thread_get_thread_debug_port(
1372 					nubThread, threadID, threadDebugPort);
1373 
1374 				// send a message to the debugged thread
1375 				if (result == B_OK) {
1376 					debugged_thread_continue commandMessage;
1377 					commandMessage.handle_event = handleEvent;
1378 					commandMessage.single_step = singleStep;
1379 
1380 					result = write_port(threadDebugPort,
1381 						B_DEBUGGED_THREAD_MESSAGE_CONTINUE,
1382 						&commandMessage, sizeof(commandMessage));
1383 				}
1384 
1385 				break;
1386 			}
1387 
1388 			case B_DEBUG_MESSAGE_SET_CPU_STATE:
1389 			{
1390 				// get the parameters
1391 				thread_id threadID = message.set_cpu_state.thread;
1392 				const debug_cpu_state &cpuState
1393 					= message.set_cpu_state.cpu_state;
1394 
1395 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_CPU_STATE: "
1396 					"thread: %ld\n", nubThread->id, threadID));
1397 
1398 				// find the thread and get its debug port
1399 				port_id threadDebugPort = -1;
1400 				status_t result = debug_nub_thread_get_thread_debug_port(
1401 					nubThread, threadID, threadDebugPort);
1402 
1403 				// send a message to the debugged thread
1404 				if (result == B_OK) {
1405 					debugged_thread_set_cpu_state commandMessage;
1406 					memcpy(&commandMessage.cpu_state, &cpuState,
1407 						sizeof(debug_cpu_state));
1408 					write_port(threadDebugPort,
1409 						B_DEBUGGED_THREAD_SET_CPU_STATE,
1410 						&commandMessage, sizeof(commandMessage));
1411 				}
1412 
1413 				break;
1414 			}
1415 
1416 			case B_DEBUG_MESSAGE_GET_CPU_STATE:
1417 			{
1418 				// get the parameters
1419 				thread_id threadID = message.get_cpu_state.thread;
1420 				replyPort = message.get_cpu_state.reply_port;
1421 
1422 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_CPU_STATE: "
1423 					"thread: %ld\n", nubThread->id, threadID));
1424 
1425 				// find the thread and get its debug port
1426 				port_id threadDebugPort = -1;
1427 				status_t result = debug_nub_thread_get_thread_debug_port(
1428 					nubThread, threadID, threadDebugPort);
1429 
1430 				// send a message to the debugged thread
1431 				if (threadDebugPort >= 0) {
1432 					debugged_thread_get_cpu_state commandMessage;
1433 					commandMessage.reply_port = replyPort;
1434 					result = write_port(threadDebugPort,
1435 						B_DEBUGGED_THREAD_GET_CPU_STATE, &commandMessage,
1436 						sizeof(commandMessage));
1437 				}
1438 
1439 				// send a reply to the debugger in case of error
1440 				if (result != B_OK) {
1441 					reply.get_cpu_state.error = result;
1442 					sendReply = true;
1443 					replySize = sizeof(reply.get_cpu_state);
1444 				}
1445 
1446 				break;
1447 			}
1448 
1449 			case B_DEBUG_MESSAGE_SET_BREAKPOINT:
1450 			{
1451 				// get the parameters
1452 				replyPort = message.set_breakpoint.reply_port;
1453 				void *address = message.set_breakpoint.address;
1454 
1455 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_BREAKPOINT: "
1456 					"address: %p\n", nubThread->id, address));
1457 
1458 				// check the address
1459 				status_t result = B_OK;
1460 				if (address == NULL || !IS_USER_ADDRESS(address))
1461 					result = B_BAD_ADDRESS;
1462 
1463 				// set the breakpoint
1464 				if (result == B_OK)
1465 					result = arch_set_breakpoint(address);
1466 
1467 				// prepare the reply
1468 				reply.set_breakpoint.error = result;
1469 				replySize = sizeof(reply.set_breakpoint);
1470 				sendReply = true;
1471 
1472 				break;
1473 			}
1474 
1475 			case B_DEBUG_MESSAGE_CLEAR_BREAKPOINT:
1476 			{
1477 				// get the parameters
1478 				void *address = message.clear_breakpoint.address;
1479 
1480 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CLEAR_BREAKPOINT: "
1481 					"address: %p\n", nubThread->id, address));
1482 
1483 				// check the address
1484 				status_t result = B_OK;
1485 				if (address == NULL || !IS_USER_ADDRESS(address))
1486 					result = B_BAD_ADDRESS;
1487 
1488 				// clear the breakpoint
1489 				if (result == B_OK)
1490 					result = arch_clear_breakpoint(address);
1491 
1492 				break;
1493 			}
1494 
1495 			case B_DEBUG_MESSAGE_SET_WATCHPOINT:
1496 			{
1497 				// get the parameters
1498 				replyPort = message.set_watchpoint.reply_port;
1499 				void *address = message.set_watchpoint.address;
1500 				uint32 type = message.set_watchpoint.type;
1501 				int32 length = message.set_watchpoint.length;
1502 
1503 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_WATCHPOINT: "
1504 					"address: %p, type: %lu, length: %ld\n", nubThread->id,
1505 					address, type, length));
1506 
1507 				// check the address and size
1508 				status_t result = B_OK;
1509 				if (address == NULL || !IS_USER_ADDRESS(address))
1510 					result = B_BAD_ADDRESS;
1511 				if (length < 0)
1512 					result = B_BAD_VALUE;
1513 
1514 				// set the watchpoint
1515 				if (result == B_OK)
1516 					result = arch_set_watchpoint(address, type, length);
1517 
1518 				// prepare the reply
1519 				reply.set_watchpoint.error = result;
1520 				replySize = sizeof(reply.set_watchpoint);
1521 				sendReply = true;
1522 
1523 				break;
1524 			}
1525 
1526 			case B_DEBUG_MESSAGE_CLEAR_WATCHPOINT:
1527 			{
1528 				// get the parameters
1529 				void *address = message.clear_watchpoint.address;
1530 
1531 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_CLEAR_WATCHPOINT: "
1532 					"address: %p\n", nubThread->id, address));
1533 
1534 				// check the address
1535 				status_t result = B_OK;
1536 				if (address == NULL || !IS_USER_ADDRESS(address))
1537 					result = B_BAD_ADDRESS;
1538 
1539 				// clear the watchpoint
1540 				if (result == B_OK)
1541 					result = arch_clear_watchpoint(address);
1542 
1543 				break;
1544 			}
1545 
1546 			case B_DEBUG_MESSAGE_SET_SIGNAL_MASKS:
1547 			{
1548 				// get the parameters
1549 				thread_id threadID = message.set_signal_masks.thread;
1550 				uint64 ignore = message.set_signal_masks.ignore_mask;
1551 				uint64 ignoreOnce = message.set_signal_masks.ignore_once_mask;
1552 				uint32 ignoreOp = message.set_signal_masks.ignore_op;
1553 				uint32 ignoreOnceOp = message.set_signal_masks.ignore_once_op;
1554 
1555 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_SIGNAL_MASKS: "
1556 					"thread: %ld, ignore: %llx (op: %lu), ignore once: %llx "
1557 					"(op: %lu)\n", nubThread->id, threadID, ignore,
1558 						ignoreOp, ignoreOnce, ignoreOnceOp));
1559 
1560 				// set the masks
1561 				cpu_status state = disable_interrupts();
1562 				GRAB_THREAD_LOCK();
1563 
1564 				struct thread *thread
1565 					= thread_get_thread_struct_locked(threadID);
1566 				if (thread
1567 					&& thread->team == thread_get_current_thread()->team) {
1568 					thread_debug_info &threadDebugInfo = thread->debug_info;
1569 					// set ignore mask
1570 					switch (ignoreOp) {
1571 						case B_DEBUG_SIGNAL_MASK_AND:
1572 							threadDebugInfo.ignore_signals &= ignore;
1573 							break;
1574 						case B_DEBUG_SIGNAL_MASK_OR:
1575 							threadDebugInfo.ignore_signals |= ignore;
1576 							break;
1577 						case B_DEBUG_SIGNAL_MASK_SET:
1578 							threadDebugInfo.ignore_signals = ignore;
1579 							break;
1580 					}
1581 
1582 					// set ignore once mask
1583 					switch (ignoreOnceOp) {
1584 						case B_DEBUG_SIGNAL_MASK_AND:
1585 							threadDebugInfo.ignore_signals_once &= ignoreOnce;
1586 							break;
1587 						case B_DEBUG_SIGNAL_MASK_OR:
1588 							threadDebugInfo.ignore_signals_once |= ignoreOnce;
1589 							break;
1590 						case B_DEBUG_SIGNAL_MASK_SET:
1591 							threadDebugInfo.ignore_signals_once = ignoreOnce;
1592 							break;
1593 					}
1594 				}
1595 
1596 				RELEASE_THREAD_LOCK();
1597 				restore_interrupts(state);
1598 
1599 				break;
1600 			}
1601 
1602 			case B_DEBUG_MESSAGE_GET_SIGNAL_MASKS:
1603 			{
1604 				// get the parameters
1605 				replyPort = message.get_signal_masks.reply_port;
1606 				thread_id threadID = message.get_signal_masks.thread;
1607 				status_t result = B_OK;
1608 
1609 				// get the masks
1610 				uint64 ignore = 0;
1611 				uint64 ignoreOnce = 0;
1612 
1613 				cpu_status state = disable_interrupts();
1614 				GRAB_THREAD_LOCK();
1615 
1616 				struct thread *thread
1617 					= thread_get_thread_struct_locked(threadID);
1618 				if (thread) {
1619 					ignore = thread->debug_info.ignore_signals;
1620 					ignoreOnce = thread->debug_info.ignore_signals_once;
1621 				} else
1622 					result = B_BAD_THREAD_ID;
1623 
1624 				RELEASE_THREAD_LOCK();
1625 				restore_interrupts(state);
1626 
1627 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_SIGNAL_MASKS: "
1628 					"reply port: %ld, thread: %ld, ignore: %llx, "
1629 					"ignore once: %llx, result: %lx\n", nubThread->id,
1630 					replyPort, threadID, ignore, ignoreOnce, result));
1631 
1632 				// prepare the message
1633 				reply.get_signal_masks.error = result;
1634 				reply.get_signal_masks.ignore_mask = ignore;
1635 				reply.get_signal_masks.ignore_once_mask = ignoreOnce;
1636 				replySize = sizeof(reply.get_signal_masks);
1637 				sendReply = true;
1638 				break;
1639 			}
1640 
1641 			case B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER:
1642 			{
1643 				// get the parameters
1644 				thread_id threadID = message.set_signal_handler.thread;
1645 				int signal = message.set_signal_handler.signal;
1646 				struct sigaction &handler = message.set_signal_handler.handler;
1647 
1648 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_SET_SIGNAL_HANDLER: "
1649 					"thread: %ld, signal: %d, handler: %p\n", nubThread->id,
1650 					threadID, signal, handler.sa_handler));
1651 
1652 				// check, if the thread exists and is ours
1653 				cpu_status state = disable_interrupts();
1654 				GRAB_THREAD_LOCK();
1655 
1656 				struct thread *thread
1657 					= thread_get_thread_struct_locked(threadID);
1658 				if (thread
1659 					&& thread->team != thread_get_current_thread()->team) {
1660 					thread = NULL;
1661 				}
1662 
1663 				RELEASE_THREAD_LOCK();
1664 				restore_interrupts(state);
1665 
1666 				// set the handler
1667 				if (thread)
1668 					sigaction_etc(threadID, signal, &handler, NULL);
1669 
1670 				break;
1671 			}
1672 
1673 			case B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER:
1674 			{
1675 				// get the parameters
1676 				replyPort = message.get_signal_handler.reply_port;
1677 				thread_id threadID = message.get_signal_handler.thread;
1678 				int signal = message.get_signal_handler.signal;
1679 				status_t result = B_OK;
1680 
1681 				// check, if the thread exists and is ours
1682 				cpu_status state = disable_interrupts();
1683 				GRAB_THREAD_LOCK();
1684 
1685 				struct thread *thread
1686 					= thread_get_thread_struct_locked(threadID);
1687 				if (thread) {
1688 					if (thread->team != thread_get_current_thread()->team)
1689 						result = B_BAD_VALUE;
1690 				} else
1691 					result = B_BAD_THREAD_ID;
1692 
1693 				RELEASE_THREAD_LOCK();
1694 				restore_interrupts(state);
1695 
1696 				// get the handler
1697 				if (result == B_OK) {
1698 					result = sigaction_etc(threadID, signal, NULL,
1699 						&reply.get_signal_handler.handler);
1700 				}
1701 
1702 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_GET_SIGNAL_HANDLER: "
1703 					"reply port: %ld, thread: %ld, signal: %d, "
1704 					"handler: %p\n", nubThread->id, replyPort,
1705 					threadID, signal,
1706 					reply.get_signal_handler.handler.sa_handler));
1707 
1708 				// prepare the message
1709 				reply.get_signal_handler.error = result;
1710 				replySize = sizeof(reply.get_signal_handler);
1711 				sendReply = true;
1712 				break;
1713 			}
1714 
1715 			case B_DEBUG_MESSAGE_PREPARE_HANDOVER:
1716 			{
1717 				TRACE(("nub thread %ld: B_DEBUG_MESSAGE_PREPARE_HANDOVER\n",
1718 					nubThread->id));
1719 
1720 				struct team *team = nubThread->team;
1721 
1722 				// Acquire the debugger write lock. As soon as we have it and
1723 				// have set the B_TEAM_DEBUG_DEBUGGER_HANDOVER flag, no thread
1724 				// will write anything to the debugger port anymore.
1725 				status_t result = acquire_sem_etc(writeLock, 1,
1726 					B_KILL_CAN_INTERRUPT, 0);
1727 				if (result == B_OK) {
1728 					// set the respective team debug flag
1729 					cpu_status state = disable_interrupts();
1730 					GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
1731 
1732 					atomic_or(&team->debug_info.flags,
1733 						B_TEAM_DEBUG_DEBUGGER_HANDOVER);
1734 
1735 					RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
1736 					restore_interrupts(state);
1737 
1738 					release_sem(writeLock);
1739 				} else {
1740 					// We probably got a SIGKILL. If so, we will terminate when
1741 					// reading the next message fails.
1742 				}
1743 
1744 				break;
1745 			}
1746 
1747 			case B_DEBUG_MESSAGE_HANDED_OVER:
1748 			{
1749 				// notify all threads that the debugger has changed
1750 				broadcast_debugged_thread_message(nubThread,
1751 					B_DEBUGGED_THREAD_DEBUGGER_CHANGED, NULL, 0);
1752 
1753 				break;
1754 			}
1755 		}
1756 
1757 		// send the reply, if necessary
1758 		if (sendReply) {
1759 			status_t error = kill_interruptable_write_port(replyPort, command,
1760 				&reply, replySize);
1761 
1762 			if (error != B_OK) {
1763 				// The debugger port is either not longer existing or we got
1764 				// interrupted by a kill signal. In either case we terminate.
1765 				TRACE(("nub thread %ld: failed to send reply to port %ld: %s\n",
1766 					nubThread->id, replyPort, strerror(error)));
1767 
1768 				nub_thread_cleanup(nubThread);
1769 				return error;
1770 			}
1771 		}
1772 	}
1773 }
1774 
1775 
1776 /**	\brief Helper function for install_team_debugger(), that sets up the team
1777  *		   and thread debug infos.
1778  *
1779  *	Interrupts must be enabled and the team debug info lock of the team to be
1780  *	debugged must be held. The function will release the lock, but leave
1781  *	interrupts disabled.
1782  */
1783 static void
1784 install_team_debugger_init_debug_infos(struct team *team, team_id debuggerTeam,
1785 	port_id debuggerPort, port_id nubPort, thread_id nubThread,
1786 	sem_id debuggerPortWriteLock)
1787 {
1788 	atomic_set(&team->debug_info.flags,
1789 		B_TEAM_DEBUG_DEFAULT_FLAGS | B_TEAM_DEBUG_DEBUGGER_INSTALLED);
1790 	team->debug_info.nub_port = nubPort;
1791 	team->debug_info.nub_thread = nubThread;
1792 	team->debug_info.debugger_team = debuggerTeam;
1793 	team->debug_info.debugger_port = debuggerPort;
1794 	team->debug_info.debugger_write_lock = debuggerPortWriteLock;
1795 
1796 	RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
1797 
1798 	// set the user debug flags and signal masks of all threads to the default
1799 	GRAB_THREAD_LOCK();
1800 
1801 	for (struct thread *thread = team->thread_list;
1802 		 thread;
1803 		 thread = thread->team_next) {
1804 		if (thread->id == nubThread) {
1805 			atomic_set(&thread->debug_info.flags, B_THREAD_DEBUG_NUB_THREAD);
1806 		} else {
1807 			int32 flags = thread->debug_info.flags
1808 				& ~B_THREAD_DEBUG_USER_FLAG_MASK;
1809 			atomic_set(&thread->debug_info.flags,
1810 				flags | B_THREAD_DEBUG_DEFAULT_FLAGS);
1811 			thread->debug_info.ignore_signals = 0;
1812 			thread->debug_info.ignore_signals_once = 0;
1813 		}
1814 	}
1815 
1816 	RELEASE_THREAD_LOCK();
1817 }
1818 
1819 
1820 static port_id
1821 install_team_debugger(team_id teamID, port_id debuggerPort, bool useDefault,
1822 	bool dontFail)
1823 {
1824 	TRACE(("install_team_debugger(team: %ld, port: %ld, default: %d, "
1825 		"dontFail: %d)\n", teamID, debuggerPort, useDefault, dontFail));
1826 
1827 	if (useDefault)
1828 		debuggerPort = atomic_get(&sDefaultDebuggerPort);
1829 
1830 	// get the debugger team
1831 	port_info debuggerPortInfo;
1832 	status_t error = get_port_info(debuggerPort, &debuggerPortInfo);
1833 	if (error != B_OK) {
1834 		TRACE(("install_team_debugger(): Failed to get debugger port info: "
1835 			"%lx\n", error));
1836 		return error;
1837 	}
1838 	team_id debuggerTeam = debuggerPortInfo.team;
1839 
1840 	// check the debugger team: It must neither be the kernel team nor the
1841 	// debugged team
1842 	if (debuggerTeam == team_get_kernel_team_id() || debuggerTeam == teamID) {
1843 		TRACE(("install_team_debugger(): Can't debug kernel or debugger team. "
1844 			"debugger: %ld, debugged: %ld\n", debuggerTeam, teamID));
1845 		return B_NOT_ALLOWED;
1846 	}
1847 
1848 	// check, if a debugger is already installed
1849 
1850 	bool done = false;
1851 	port_id result = B_ERROR;
1852 	bool handOver = false;
1853 	bool releaseDebugInfoLock = true;
1854 	port_id oldDebuggerPort = -1;
1855 	port_id nubPort = -1;
1856 
1857 	cpu_status state = disable_interrupts();
1858 	GRAB_TEAM_LOCK();
1859 
1860 	// get a real team ID
1861 	// We look up the team by ID, even in case of the current team, so we can be
1862 	// sure, that the team is not already dying.
1863 	if (teamID == B_CURRENT_TEAM)
1864 		teamID = thread_get_current_thread()->team->id;
1865 
1866 	struct team *team = team_get_team_struct_locked(teamID);
1867 
1868 	if (team) {
1869 		GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
1870 
1871 		int32 teamDebugFlags = team->debug_info.flags;
1872 
1873 		if (team == team_get_kernel_team()) {
1874 			// don't allow to debug the kernel
1875 			error = B_NOT_ALLOWED;
1876 		} else if (teamDebugFlags & B_TEAM_DEBUG_DEBUGGER_INSTALLED) {
1877 			if (teamDebugFlags & B_TEAM_DEBUG_DEBUGGER_HANDOVER) {
1878 				// a handover to another debugger is requested
1879 				// clear the flag
1880 				atomic_and(& team->debug_info.flags,
1881 					~B_TEAM_DEBUG_DEBUGGER_HANDOVER);
1882 
1883 				oldDebuggerPort = team->debug_info.debugger_port;
1884 				result = nubPort = team->debug_info.nub_port;
1885 
1886 				// set the new debugger
1887 				install_team_debugger_init_debug_infos(team, debuggerTeam,
1888 					debuggerPort, nubPort, team->debug_info.nub_thread,
1889 					team->debug_info.debugger_write_lock);
1890 
1891 				releaseDebugInfoLock = false;
1892 				handOver = true;
1893 				done = true;
1894 
1895 				// finally set the new port owner
1896 				if (set_port_owner(nubPort, debuggerTeam) != B_OK) {
1897 					// The old debugger must just have died. Just proceed as
1898 					// if there was no debugger installed. We may still be too
1899 					// early, in which case we'll fail, but this race condition
1900 					// should be unbelievably rare and relatively harmless.
1901 					handOver = false;
1902 					done = false;
1903 				}
1904 
1905 			} else {
1906 				// there's already a debugger installed
1907 				error = (dontFail ? B_OK : B_BAD_VALUE);
1908 				done = true;
1909 				result = team->debug_info.nub_port;
1910 			}
1911 		}
1912 
1913 		// in case of a handover the lock has already been released
1914 		if (releaseDebugInfoLock)
1915 			RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
1916 	} else
1917 		error = B_BAD_TEAM_ID;
1918 
1919 	RELEASE_TEAM_LOCK();
1920 	restore_interrupts(state);
1921 
1922 	if (handOver) {
1923 		// notify the nub thread
1924 		kill_interruptable_write_port(nubPort, B_DEBUG_MESSAGE_HANDED_OVER,
1925 			NULL, 0);
1926 
1927 		// notify the old debugger
1928 		debug_handed_over notification;
1929 		notification.origin.thread = -1;
1930 		notification.origin.team = teamID;
1931 		notification.origin.nub_port = nubPort;
1932 		notification.debugger = debuggerTeam;
1933 		notification.debugger_port = debuggerPort;
1934 
1935 		error = write_port_etc(oldDebuggerPort,
1936 			B_DEBUGGER_MESSAGE_HANDED_OVER, &notification,
1937 			sizeof(notification), B_RELATIVE_TIMEOUT, 0);
1938 		if (error != B_OK) {
1939 			TRACE(("install_team_debugger(): Failed to send message to old "
1940 				"debugger: %s\n", strerror(error)));
1941 		}
1942 
1943 		TRACE(("install_team_debugger() done: handed over to debugger: team: "
1944 			"%ld, port: %ld\n", debuggerTeam, debuggerPort));
1945 
1946 		return result;
1947 	}
1948 
1949 	if (done || error != B_OK) {
1950 		TRACE(("install_team_debugger() done1: %ld\n",
1951 			(error == B_OK ? result : error)));
1952 		return (error == B_OK ? result : error);
1953 	}
1954 
1955 	// create the debugger write lock semaphore
1956 	char nameBuffer[B_OS_NAME_LENGTH];
1957 	snprintf(nameBuffer, sizeof(nameBuffer), "team %ld debugger port write",
1958 		teamID);
1959 	sem_id debuggerWriteLock = create_sem(1, nameBuffer);
1960 	if (debuggerWriteLock < 0)
1961 		error = debuggerWriteLock;
1962 
1963 	// create the nub port
1964 	snprintf(nameBuffer, sizeof(nameBuffer), "team %ld debug", teamID);
1965 	if (error == B_OK) {
1966 		nubPort = create_port(1, nameBuffer);
1967 		if (nubPort < 0)
1968 			error = nubPort;
1969 		else
1970 			result = nubPort;
1971 	}
1972 
1973 	// make the debugger team the port owner; thus we know, if the debugger is
1974 	// gone and can cleanup
1975 	if (error == B_OK)
1976 		error = set_port_owner(nubPort, debuggerTeam);
1977 
1978 	// spawn the nub thread
1979 	thread_id nubThread = -1;
1980 	if (error == B_OK) {
1981 		snprintf(nameBuffer, sizeof(nameBuffer), "team %ld debug task", teamID);
1982 		nubThread = spawn_kernel_thread_etc(debug_nub_thread, nameBuffer,
1983 			B_NORMAL_PRIORITY, NULL, teamID, -1);
1984 		if (nubThread < 0)
1985 			error = nubThread;
1986 	}
1987 
1988 	// now adjust the debug info accordingly
1989 	if (error == B_OK) {
1990 		state = disable_interrupts();
1991 		GRAB_TEAM_LOCK();
1992 
1993 		// look up again, to make sure the team isn't dying
1994 		team = team_get_team_struct_locked(teamID);
1995 
1996 		if (team) {
1997 			GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
1998 
1999 			if (team->debug_info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED) {
2000 				// there's already a debugger installed
2001 				error = (dontFail ? B_OK : B_BAD_VALUE);
2002 				done = true;
2003 				result = team->debug_info.nub_port;
2004 
2005 				RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
2006 			} else {
2007 				install_team_debugger_init_debug_infos(team, debuggerTeam,
2008 					debuggerPort, nubPort, nubThread, debuggerWriteLock);
2009 			}
2010 		} else
2011 			error = B_BAD_TEAM_ID;
2012 
2013 		RELEASE_TEAM_LOCK();
2014 		restore_interrupts(state);
2015 	}
2016 
2017 	// if everything went fine, resume the nub thread, otherwise clean up
2018 	if (error == B_OK && !done) {
2019 		resume_thread(nubThread);
2020 	} else {
2021 		// delete port and terminate thread
2022 		if (nubPort >= 0) {
2023 			set_port_owner(nubPort, B_CURRENT_TEAM);
2024 			delete_port(nubPort);
2025 		}
2026 		if (nubThread >= 0) {
2027 			int32 result;
2028 			wait_for_thread(nubThread, &result);
2029 		}
2030 	}
2031 
2032 	TRACE(("install_team_debugger() done2: %ld\n",
2033 		(error == B_OK ? result : error)));
2034 	return (error == B_OK ? result : error);
2035 }
2036 
2037 
2038 static status_t
2039 ensure_debugger_installed(team_id teamID, port_id *_port)
2040 {
2041 	port_id port = install_team_debugger(teamID, -1, true, true);
2042 	if (port < 0)
2043 		return port;
2044 
2045 	if (_port)
2046 		*_port = port;
2047 	return B_OK;
2048 }
2049 
2050 
2051 // #pragma mark -
2052 
2053 
2054 void
2055 _user_debugger(const char *userMessage)
2056 {
2057 	// install the default debugger, if there is none yet
2058 	struct thread *thread = thread_get_current_thread();
2059 	port_id nubPort;
2060 	status_t error = ensure_debugger_installed(B_CURRENT_TEAM, &nubPort);
2061 	if (error != B_OK) {
2062 		// time to commit suicide
2063 		char buffer[128];
2064 		ssize_t length = user_strlcpy(buffer, userMessage, sizeof(buffer));
2065 		if (length >= 0) {
2066 			dprintf("_user_debugger(): Failed to install debugger. Message is: "
2067 				"`%s'\n", buffer);
2068 		} else {
2069 			dprintf("_user_debugger(): Failed to install debugger. Message is: "
2070 				"%p (%s)\n", userMessage, strerror(length));
2071 		}
2072 		_user_exit_team(1);
2073 	}
2074 
2075 	// prepare the message
2076 	debug_debugger_call message;
2077 	message.message = (void*)userMessage;
2078 
2079 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_DEBUGGER_CALL, &message,
2080 		sizeof(message), true);
2081 }
2082 
2083 
2084 int
2085 _user_disable_debugger(int state)
2086 {
2087 	struct team *team = thread_get_current_thread()->team;
2088 
2089 	cpu_status cpuState = disable_interrupts();
2090 	GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
2091 
2092 	int32 oldFlags;
2093 	if (state)
2094 		oldFlags = atomic_and(&team->debug_info.flags, ~B_TEAM_DEBUG_SIGNALS);
2095 	else
2096 		oldFlags = atomic_or(&team->debug_info.flags, B_TEAM_DEBUG_SIGNALS);
2097 
2098 	RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
2099 	restore_interrupts(cpuState);
2100 
2101 	// TODO: Check, if the return value is really the old state.
2102 	return !(oldFlags & B_TEAM_DEBUG_SIGNALS);
2103 }
2104 
2105 
2106 status_t
2107 _user_install_default_debugger(port_id debuggerPort)
2108 {
2109 	// if supplied, check whether the port is a valid port
2110 	if (debuggerPort >= 0) {
2111 		port_info portInfo;
2112 		status_t error = get_port_info(debuggerPort, &portInfo);
2113 		if (error != B_OK)
2114 			return error;
2115 
2116 		// the debugger team must not be the kernel team
2117 		if (portInfo.team == team_get_kernel_team_id())
2118 			return B_NOT_ALLOWED;
2119 	}
2120 
2121 	atomic_set(&sDefaultDebuggerPort, debuggerPort);
2122 
2123 	return B_OK;
2124 }
2125 
2126 
2127 port_id
2128 _user_install_team_debugger(team_id teamID, port_id debuggerPort)
2129 {
2130 	return install_team_debugger(teamID, debuggerPort, false, false);
2131 }
2132 
2133 
2134 status_t
2135 _user_remove_team_debugger(team_id teamID)
2136 {
2137 	struct team_debug_info info;
2138 
2139 	status_t error = B_OK;
2140 
2141 	cpu_status state = disable_interrupts();
2142 	GRAB_TEAM_LOCK();
2143 
2144 	struct team *team = (teamID == B_CURRENT_TEAM
2145 		? thread_get_current_thread()->team
2146 		: team_get_team_struct_locked(teamID));
2147 
2148 	if (team) {
2149 		GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
2150 
2151 		if (team->debug_info.flags & B_TEAM_DEBUG_DEBUGGER_INSTALLED) {
2152 			// there's a debugger installed
2153 			info = team->debug_info;
2154 			clear_team_debug_info(&team->debug_info, false);
2155 		} else {
2156 			// no debugger installed
2157 			error = B_BAD_VALUE;
2158 		}
2159 
2160 		RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
2161 	} else
2162 		error = B_BAD_TEAM_ID;
2163 
2164 	RELEASE_TEAM_LOCK();
2165 	restore_interrupts(state);
2166 
2167 	// clean up the info, if there was a debugger installed
2168 	if (error == B_OK)
2169 		destroy_team_debug_info(&info);
2170 
2171 	return error;
2172 }
2173 
2174 
2175 status_t
2176 _user_debug_thread(thread_id threadID)
2177 {
2178 	// tell the thread to stop as soon as possible
2179 	status_t error = B_OK;
2180 	cpu_status state = disable_interrupts();
2181 	GRAB_THREAD_LOCK();
2182 
2183 	struct thread *thread = thread_get_thread_struct_locked(threadID);
2184 	if (!thread) {
2185 		// thread doesn't exist any longer
2186 		error = B_BAD_THREAD_ID;
2187 	} else if (thread->team == team_get_kernel_team()) {
2188 		// we can't debug the kernel team
2189 		error = B_NOT_ALLOWED;
2190 	} else if (thread->debug_info.flags & B_THREAD_DEBUG_DYING) {
2191 		// the thread is already dying -- too late to debug it
2192 		error = B_BAD_THREAD_ID;
2193 	} else if (thread->debug_info.flags & B_THREAD_DEBUG_NUB_THREAD) {
2194 		// don't debug the nub thread
2195 		error = B_NOT_ALLOWED;
2196 	} else if (!(thread->debug_info.flags & B_THREAD_DEBUG_STOPPED)) {
2197 		// set the flag that tells the thread to stop as soon as possible
2198 		atomic_or(&thread->debug_info.flags, B_THREAD_DEBUG_STOP);
2199 
2200 		switch (thread->state) {
2201 			case B_THREAD_SUSPENDED:
2202 				// thread suspended: wake it up
2203 				thread->state = thread->next_state = B_THREAD_READY;
2204 				scheduler_enqueue_in_run_queue(thread);
2205 				break;
2206 
2207 			case B_THREAD_WAITING:
2208 				// thread waiting: interrupt it
2209 				sem_interrupt_thread(thread);
2210 				break;
2211 		}
2212 	}
2213 
2214 	RELEASE_THREAD_LOCK();
2215 	restore_interrupts(state);
2216 
2217 	return error;
2218 }
2219 
2220 void
2221 _user_wait_for_debugger(void)
2222 {
2223 	debug_thread_debugged message;
2224 	thread_hit_debug_event(B_DEBUGGER_MESSAGE_THREAD_DEBUGGED, &message,
2225 		sizeof(message), false);
2226 }
2227 
2228 
2229