xref: /haiku/src/kits/debugger/model/Team.cpp (revision 2897df967633aab846ff4917b53e2af7d1e54eeb)
1 /*
2  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2013-2015, Rene Gollent, rene@gollent.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include "Team.h"
9 
10 #include <new>
11 
12 #include <AutoLocker.h>
13 
14 #include "Breakpoint.h"
15 #include "DisassembledCode.h"
16 #include "FileSourceCode.h"
17 #include "Function.h"
18 #include "ImageDebugInfo.h"
19 #include "SignalDispositionTypes.h"
20 #include "SourceCode.h"
21 #include "SpecificImageDebugInfo.h"
22 #include "Statement.h"
23 #include "TeamDebugInfo.h"
24 #include "Tracing.h"
25 #include "Value.h"
26 #include "Watchpoint.h"
27 
28 
29 // #pragma mark - BreakpointByAddressPredicate
30 
31 
32 struct Team::BreakpointByAddressPredicate
33 	: UnaryPredicate<Breakpoint> {
34 	BreakpointByAddressPredicate(target_addr_t address)
35 		:
36 		fAddress(address)
37 	{
38 	}
39 
40 	virtual int operator()(const Breakpoint* breakpoint) const
41 	{
42 		return -Breakpoint::CompareAddressBreakpoint(&fAddress, breakpoint);
43 	}
44 
45 private:
46 	target_addr_t	fAddress;
47 };
48 
49 
50 // #pragma mark - WatchpointByAddressPredicate
51 
52 
53 struct Team::WatchpointByAddressPredicate
54 	: UnaryPredicate<Watchpoint> {
55 	WatchpointByAddressPredicate(target_addr_t address)
56 		:
57 		fAddress(address)
58 	{
59 	}
60 
61 	virtual int operator()(const Watchpoint* watchpoint) const
62 	{
63 		return -Watchpoint::CompareAddressWatchpoint(&fAddress, watchpoint);
64 	}
65 
66 private:
67 	target_addr_t	fAddress;
68 };
69 
70 
71 // #pragma mark - Team
72 
73 
74 Team::Team(team_id teamID, TeamMemory* teamMemory, Architecture* architecture,
75 	TeamDebugInfo* debugInfo, TeamTypeInformation* typeInformation)
76 	:
77 	fLock("team lock"),
78 	fID(teamID),
79 	fTeamMemory(teamMemory),
80 	fTypeInformation(typeInformation),
81 	fArchitecture(architecture),
82 	fDebugInfo(debugInfo),
83 	fStopOnImageLoad(false),
84 	fStopImageNameListEnabled(false),
85 	fDefaultSignalDisposition(SIGNAL_DISPOSITION_IGNORE)
86 {
87 	fDebugInfo->AcquireReference();
88 }
89 
90 
91 Team::~Team()
92 {
93 	while (UserBreakpoint* userBreakpoint = fUserBreakpoints.RemoveHead())
94 		userBreakpoint->ReleaseReference();
95 
96 	for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++)
97 		breakpoint->ReleaseReference();
98 
99 	for (int32 i = 0; Watchpoint* watchpoint = fWatchpoints.ItemAt(i); i++)
100 		watchpoint->ReleaseReference();
101 
102 	while (Image* image = fImages.RemoveHead())
103 		image->ReleaseReference();
104 
105 	while (Thread* thread = fThreads.RemoveHead())
106 		thread->ReleaseReference();
107 
108 	fDebugInfo->ReleaseReference();
109 }
110 
111 
112 status_t
113 Team::Init()
114 {
115 	return fLock.InitCheck();
116 }
117 
118 
119 void
120 Team::SetName(const BString& name)
121 {
122 	fName = name;
123 	_NotifyTeamRenamed();
124 }
125 
126 
127 void
128 Team::AddThread(Thread* thread)
129 {
130 	fThreads.Add(thread);
131 	_NotifyThreadAdded(thread);
132 }
133 
134 
135 
136 status_t
137 Team::AddThread(const ThreadInfo& threadInfo, Thread** _thread)
138 {
139 	Thread* thread = new(std::nothrow) Thread(this, threadInfo.ThreadID());
140 	if (thread == NULL)
141 		return B_NO_MEMORY;
142 
143 	status_t error = thread->Init();
144 	if (error != B_OK) {
145 		delete thread;
146 		return error;
147 	}
148 
149 	thread->SetName(threadInfo.Name());
150 	AddThread(thread);
151 
152 	if (_thread != NULL)
153 		*_thread = thread;
154 
155 	return B_OK;
156 }
157 
158 
159 void
160 Team::RemoveThread(Thread* thread)
161 {
162 	fThreads.Remove(thread);
163 	_NotifyThreadRemoved(thread);
164 }
165 
166 
167 bool
168 Team::RemoveThread(thread_id threadID)
169 {
170 	Thread* thread = ThreadByID(threadID);
171 	if (thread == NULL)
172 		return false;
173 
174 	RemoveThread(thread);
175 	thread->ReleaseReference();
176 	return true;
177 }
178 
179 
180 Thread*
181 Team::ThreadByID(thread_id threadID) const
182 {
183 	for (ThreadList::ConstIterator it = fThreads.GetIterator();
184 			Thread* thread = it.Next();) {
185 		if (thread->ID() == threadID)
186 			return thread;
187 	}
188 
189 	return NULL;
190 }
191 
192 
193 const ThreadList&
194 Team::Threads() const
195 {
196 	return fThreads;
197 }
198 
199 
200 status_t
201 Team::AddImage(const ImageInfo& imageInfo, LocatableFile* imageFile,
202 	Image** _image)
203 {
204 	Image* image = new(std::nothrow) Image(this, imageInfo, imageFile);
205 	if (image == NULL)
206 		return B_NO_MEMORY;
207 
208 	status_t error = image->Init();
209 	if (error != B_OK) {
210 		delete image;
211 		return error;
212 	}
213 
214 	if (image->Type() == B_APP_IMAGE)
215 		SetName(image->Name());
216 
217 	fImages.Add(image);
218 	_NotifyImageAdded(image);
219 
220 	if (_image != NULL)
221 		*_image = image;
222 
223 	return B_OK;
224 }
225 
226 
227 void
228 Team::RemoveImage(Image* image)
229 {
230 	fImages.Remove(image);
231 	_NotifyImageRemoved(image);
232 }
233 
234 
235 bool
236 Team::RemoveImage(image_id imageID)
237 {
238 	Image* image = ImageByID(imageID);
239 	if (image == NULL)
240 		return false;
241 
242 	RemoveImage(image);
243 	image->ReleaseReference();
244 	return true;
245 }
246 
247 
248 Image*
249 Team::ImageByID(image_id imageID) const
250 {
251 	for (ImageList::ConstIterator it = fImages.GetIterator();
252 			Image* image = it.Next();) {
253 		if (image->ID() == imageID)
254 			return image;
255 	}
256 
257 	return NULL;
258 }
259 
260 
261 Image*
262 Team::ImageByAddress(target_addr_t address) const
263 {
264 	for (ImageList::ConstIterator it = fImages.GetIterator();
265 			Image* image = it.Next();) {
266 		if (image->ContainsAddress(address))
267 			return image;
268 	}
269 
270 	return NULL;
271 }
272 
273 
274 const ImageList&
275 Team::Images() const
276 {
277 	return fImages;
278 }
279 
280 
281 void
282 Team::ClearImages()
283 {
284 	while (!fImages.IsEmpty())
285 		RemoveImage(fImages.First());
286 }
287 
288 
289 bool
290 Team::AddStopImageName(const BString& name)
291 {
292 	if (!fStopImageNames.Add(name))
293 		return false;
294 
295 	fStopImageNames.Sort();
296 
297 	NotifyStopImageNameAdded(name);
298 	return true;
299 }
300 
301 
302 void
303 Team::RemoveStopImageName(const BString& name)
304 {
305 	fStopImageNames.Remove(name);
306 	NotifyStopImageNameRemoved(name);
307 }
308 
309 
310 void
311 Team::SetStopOnImageLoad(bool enabled, bool useImageNameList)
312 {
313 	fStopOnImageLoad = enabled;
314 	fStopImageNameListEnabled = useImageNameList;
315 	NotifyStopOnImageLoadChanged(enabled, useImageNameList);
316 }
317 
318 
319 const BStringList&
320 Team::StopImageNames() const
321 {
322 	return fStopImageNames;
323 }
324 
325 
326 void
327 Team::SetDefaultSignalDisposition(int32 disposition)
328 {
329 	if (disposition != fDefaultSignalDisposition) {
330 		fDefaultSignalDisposition = disposition;
331 		NotifyDefaultSignalDispositionChanged(disposition);
332 	}
333 }
334 
335 
336 bool
337 Team::SetCustomSignalDisposition(int32 signal, int32 disposition)
338 {
339 	SignalDispositionMappings::iterator it = fCustomSignalDispositions.find(
340 		signal);
341 	if (it != fCustomSignalDispositions.end() && it->second == disposition)
342 		return true;
343 
344 	try {
345 		fCustomSignalDispositions[signal] = disposition;
346 	} catch (...) {
347 		return false;
348 	}
349 
350 	NotifyCustomSignalDispositionChanged(signal, disposition);
351 
352 	return true;
353 }
354 
355 
356 void
357 Team::RemoveCustomSignalDisposition(int32 signal)
358 {
359 	SignalDispositionMappings::iterator it = fCustomSignalDispositions.find(
360 		signal);
361 	if (it == fCustomSignalDispositions.end())
362 		return;
363 
364 	fCustomSignalDispositions.erase(it);
365 
366 	NotifyCustomSignalDispositionRemoved(signal);
367 }
368 
369 
370 int32
371 Team::SignalDispositionFor(int32 signal) const
372 {
373 	SignalDispositionMappings::const_iterator it
374 		= fCustomSignalDispositions.find(signal);
375 	if (it != fCustomSignalDispositions.end())
376 		return it->second;
377 
378 	return fDefaultSignalDisposition;
379 }
380 
381 
382 const SignalDispositionMappings&
383 Team::GetSignalDispositionMappings() const
384 {
385 	return fCustomSignalDispositions;
386 }
387 
388 
389 void
390 Team::ClearSignalDispositionMappings()
391 {
392 	fCustomSignalDispositions.clear();
393 }
394 
395 
396 bool
397 Team::AddBreakpoint(Breakpoint* breakpoint)
398 {
399 	if (fBreakpoints.BinaryInsert(breakpoint, &Breakpoint::CompareBreakpoints))
400 		return true;
401 
402 	breakpoint->ReleaseReference();
403 	return false;
404 }
405 
406 
407 void
408 Team::RemoveBreakpoint(Breakpoint* breakpoint)
409 {
410 	int32 index = fBreakpoints.BinarySearchIndex(*breakpoint,
411 		&Breakpoint::CompareBreakpoints);
412 	if (index < 0)
413 		return;
414 
415 	fBreakpoints.RemoveItemAt(index);
416 	breakpoint->ReleaseReference();
417 }
418 
419 
420 int32
421 Team::CountBreakpoints() const
422 {
423 	return fBreakpoints.CountItems();
424 }
425 
426 
427 Breakpoint*
428 Team::BreakpointAt(int32 index) const
429 {
430 	return fBreakpoints.ItemAt(index);
431 }
432 
433 
434 Breakpoint*
435 Team::BreakpointAtAddress(target_addr_t address) const
436 {
437 	return fBreakpoints.BinarySearchByKey(address,
438 		&Breakpoint::CompareAddressBreakpoint);
439 }
440 
441 
442 void
443 Team::GetBreakpointsInAddressRange(TargetAddressRange range,
444 	BObjectList<UserBreakpoint>& breakpoints) const
445 {
446 	int32 index = fBreakpoints.FindBinaryInsertionIndex(
447 		BreakpointByAddressPredicate(range.Start()));
448 	for (; Breakpoint* breakpoint = fBreakpoints.ItemAt(index); index++) {
449 		if (breakpoint->Address() > range.End())
450 			break;
451 
452 		for (UserBreakpointInstanceList::ConstIterator it
453 				= breakpoint->UserBreakpoints().GetIterator();
454 			UserBreakpointInstance* instance = it.Next();) {
455 			breakpoints.AddItem(instance->GetUserBreakpoint());
456 		}
457 	}
458 
459 	// TODO: Avoid duplicates!
460 }
461 
462 
463 void
464 Team::GetBreakpointsForSourceCode(SourceCode* sourceCode,
465 	BObjectList<UserBreakpoint>& breakpoints) const
466 {
467 	if (DisassembledCode* disassembledCode
468 			= dynamic_cast<DisassembledCode*>(sourceCode)) {
469 		GetBreakpointsInAddressRange(disassembledCode->StatementAddressRange(),
470 			breakpoints);
471 		return;
472 	}
473 
474 	LocatableFile* sourceFile = sourceCode->GetSourceFile();
475 	if (sourceFile == NULL)
476 		return;
477 
478 	// TODO: This can probably be optimized. Maybe by registering the user
479 	// breakpoints with the team and sorting them by source code.
480 	for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++) {
481 		UserBreakpointInstance* userBreakpointInstance
482 			= breakpoint->FirstUserBreakpoint();
483 		if (userBreakpointInstance == NULL)
484 			continue;
485 
486 		UserBreakpoint* userBreakpoint
487 			= userBreakpointInstance->GetUserBreakpoint();
488 		if (userBreakpoint->Location().SourceFile() == sourceFile)
489 			breakpoints.AddItem(userBreakpoint);
490 	}
491 }
492 
493 
494 void
495 Team::AddUserBreakpoint(UserBreakpoint* userBreakpoint)
496 {
497 	fUserBreakpoints.Add(userBreakpoint);
498 	userBreakpoint->AcquireReference();
499 }
500 
501 
502 void
503 Team::RemoveUserBreakpoint(UserBreakpoint* userBreakpoint)
504 {
505 	fUserBreakpoints.Remove(userBreakpoint);
506 	userBreakpoint->ReleaseReference();
507 }
508 
509 
510 bool
511 Team::AddWatchpoint(Watchpoint* watchpoint)
512 {
513 	if (fWatchpoints.BinaryInsert(watchpoint, &Watchpoint::CompareWatchpoints))
514 		return true;
515 
516 	watchpoint->ReleaseReference();
517 	return false;
518 }
519 
520 
521 void
522 Team::RemoveWatchpoint(Watchpoint* watchpoint)
523 {
524 	int32 index = fWatchpoints.BinarySearchIndex(*watchpoint,
525 		&Watchpoint::CompareWatchpoints);
526 	if (index < 0)
527 		return;
528 
529 	fWatchpoints.RemoveItemAt(index);
530 	watchpoint->ReleaseReference();
531 }
532 
533 
534 int32
535 Team::CountWatchpoints() const
536 {
537 	return fWatchpoints.CountItems();
538 }
539 
540 
541 Watchpoint*
542 Team::WatchpointAt(int32 index) const
543 {
544 	return fWatchpoints.ItemAt(index);
545 }
546 
547 
548 Watchpoint*
549 Team::WatchpointAtAddress(target_addr_t address) const
550 {
551 	return fWatchpoints.BinarySearchByKey(address,
552 		&Watchpoint::CompareAddressWatchpoint);
553 }
554 
555 
556 void
557 Team::GetWatchpointsInAddressRange(TargetAddressRange range,
558 	BObjectList<Watchpoint>& watchpoints) const
559 {
560 	int32 index = fWatchpoints.FindBinaryInsertionIndex(
561 		WatchpointByAddressPredicate(range.Start()));
562 	for (; Watchpoint* watchpoint = fWatchpoints.ItemAt(index); index++) {
563 		if (watchpoint->Address() > range.End())
564 			break;
565 
566 		watchpoints.AddItem(watchpoint);
567 	}
568 }
569 
570 
571 status_t
572 Team::GetStatementAtAddress(target_addr_t address, FunctionInstance*& _function,
573 	Statement*& _statement)
574 {
575 	TRACE_CODE("Team::GetStatementAtAddress(%#" B_PRIx64 ")\n", address);
576 
577 	// get the image at the address
578 	Image* image = ImageByAddress(address);
579 	if (image == NULL) {
580 		TRACE_CODE("  -> no image\n");
581 		return B_ENTRY_NOT_FOUND;
582 	}
583 
584 	ImageDebugInfo* imageDebugInfo = image->GetImageDebugInfo();
585 	if (imageDebugInfo == NULL) {
586 		TRACE_CODE("  -> no image debug info\n");
587 		return B_ENTRY_NOT_FOUND;
588 	}
589 
590 	// get the function
591 	FunctionInstance* functionInstance
592 		= imageDebugInfo->FunctionAtAddress(address);
593 	if (functionInstance == NULL) {
594 		TRACE_CODE("  -> no function instance\n");
595 		return B_ENTRY_NOT_FOUND;
596 	}
597 
598 	// If the function instance has disassembled code attached, we can get the
599 	// statement directly.
600 	if (DisassembledCode* code = functionInstance->GetSourceCode()) {
601 		Statement* statement = code->StatementAtAddress(address);
602 		if (statement == NULL)
603 			return B_ENTRY_NOT_FOUND;
604 
605 		statement->AcquireReference();
606 		_statement = statement;
607 		_function = functionInstance;
608 		return B_OK;
609 	}
610 
611 	// get the statement from the image debug info
612 	FunctionDebugInfo* functionDebugInfo
613 		= functionInstance->GetFunctionDebugInfo();
614 	status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
615 		->GetStatement(functionDebugInfo, address, _statement);
616 	if (error != B_OK) {
617 		TRACE_CODE("  -> no statement from the specific image debug info\n");
618 		return error;
619 	}
620 
621 	_function = functionInstance;
622 	return B_OK;
623 }
624 
625 
626 status_t
627 Team::GetStatementAtSourceLocation(SourceCode* sourceCode,
628 	const SourceLocation& location, Statement*& _statement)
629 {
630 	TRACE_CODE("Team::GetStatementAtSourceLocation(%p, (%" B_PRId32 ", %"
631 		B_PRId32 "))\n", sourceCode, location.Line(), location.Column());
632 
633 	// If we're lucky the source code can provide us with a statement.
634 	if (DisassembledCode* code = dynamic_cast<DisassembledCode*>(sourceCode)) {
635 		Statement* statement = code->StatementAtLocation(location);
636 		if (statement == NULL)
637 			return B_ENTRY_NOT_FOUND;
638 
639 		statement->AcquireReference();
640 		_statement = statement;
641 		return B_OK;
642 	}
643 
644 	// Go the long and stony way over the source file and the team debug info.
645 	// get the source file for the source code
646 	LocatableFile* sourceFile = sourceCode->GetSourceFile();
647 	if (sourceFile == NULL)
648 		return B_ENTRY_NOT_FOUND;
649 
650 	// get the function at the source location
651 	Function* function = fDebugInfo->FunctionAtSourceLocation(sourceFile,
652 		location);
653 	if (function == NULL)
654 		return B_ENTRY_NOT_FOUND;
655 
656 	// Get some function instance and ask its image debug info to provide us
657 	// with a statement.
658 	FunctionInstance* functionInstance = function->FirstInstance();
659 	if (functionInstance == NULL)
660 		return B_ENTRY_NOT_FOUND;
661 
662 	FunctionDebugInfo* functionDebugInfo
663 		= functionInstance->GetFunctionDebugInfo();
664 	return functionDebugInfo->GetSpecificImageDebugInfo()
665 		->GetStatementAtSourceLocation(functionDebugInfo, location, _statement);
666 }
667 
668 
669 Function*
670 Team::FunctionByID(FunctionID* functionID) const
671 {
672 	return fDebugInfo->FunctionByID(functionID);
673 }
674 
675 
676 void
677 Team::AddListener(Listener* listener)
678 {
679 	AutoLocker<Team> locker(this);
680 	fListeners.Add(listener);
681 }
682 
683 
684 void
685 Team::RemoveListener(Listener* listener)
686 {
687 	AutoLocker<Team> locker(this);
688 	fListeners.Remove(listener);
689 }
690 
691 
692 void
693 Team::NotifyThreadStateChanged(Thread* thread)
694 {
695 	for (ListenerList::Iterator it = fListeners.GetIterator();
696 			Listener* listener = it.Next();) {
697 		listener->ThreadStateChanged(
698 			ThreadEvent(TEAM_EVENT_THREAD_STATE_CHANGED, thread));
699 	}
700 }
701 
702 
703 void
704 Team::NotifyThreadCpuStateChanged(Thread* thread)
705 {
706 	for (ListenerList::Iterator it = fListeners.GetIterator();
707 			Listener* listener = it.Next();) {
708 		listener->ThreadCpuStateChanged(
709 			ThreadEvent(TEAM_EVENT_THREAD_CPU_STATE_CHANGED, thread));
710 	}
711 }
712 
713 
714 void
715 Team::NotifyThreadStackTraceChanged(Thread* thread)
716 {
717 	for (ListenerList::Iterator it = fListeners.GetIterator();
718 			Listener* listener = it.Next();) {
719 		listener->ThreadStackTraceChanged(
720 			ThreadEvent(TEAM_EVENT_THREAD_STACK_TRACE_CHANGED, thread));
721 	}
722 }
723 
724 
725 void
726 Team::NotifyImageDebugInfoChanged(Image* image)
727 {
728 	for (ListenerList::Iterator it = fListeners.GetIterator();
729 			Listener* listener = it.Next();) {
730 		listener->ImageDebugInfoChanged(
731 			ImageEvent(TEAM_EVENT_IMAGE_DEBUG_INFO_CHANGED, image));
732 	}
733 }
734 
735 
736 void
737 Team::NotifyStopOnImageLoadChanged(bool enabled, bool useImageNameList)
738 {
739 	for (ListenerList::Iterator it = fListeners.GetIterator();
740 			Listener* listener = it.Next();) {
741 		listener->StopOnImageLoadSettingsChanged(
742 			ImageLoadEvent(TEAM_EVENT_IMAGE_LOAD_SETTINGS_CHANGED, this,
743 				enabled, useImageNameList));
744 	}
745 }
746 
747 
748 void
749 Team::NotifyStopImageNameAdded(const BString& name)
750 {
751 	for (ListenerList::Iterator it = fListeners.GetIterator();
752 			Listener* listener = it.Next();) {
753 		listener->StopOnImageLoadNameAdded(
754 			ImageLoadNameEvent(TEAM_EVENT_IMAGE_LOAD_NAME_ADDED, this, name));
755 	}
756 }
757 
758 
759 void
760 Team::NotifyStopImageNameRemoved(const BString& name)
761 {
762 	for (ListenerList::Iterator it = fListeners.GetIterator();
763 			Listener* listener = it.Next();) {
764 		listener->StopOnImageLoadNameRemoved(
765 			ImageLoadNameEvent(TEAM_EVENT_IMAGE_LOAD_NAME_REMOVED, this,
766 				name));
767 	}
768 }
769 
770 
771 void
772 Team::NotifyDefaultSignalDispositionChanged(int32 disposition)
773 {
774 	for (ListenerList::Iterator it = fListeners.GetIterator();
775 			Listener* listener = it.Next();) {
776 		listener->DefaultSignalDispositionChanged(
777 			DefaultSignalDispositionEvent(
778 				TEAM_EVENT_DEFAULT_SIGNAL_DISPOSITION_CHANGED, this,
779 				disposition));
780 	}
781 }
782 
783 
784 void
785 Team::NotifyCustomSignalDispositionChanged(int32 signal, int32 disposition)
786 {
787 	for (ListenerList::Iterator it = fListeners.GetIterator();
788 			Listener* listener = it.Next();) {
789 		listener->CustomSignalDispositionChanged(
790 			CustomSignalDispositionEvent(
791 				TEAM_EVENT_CUSTOM_SIGNAL_DISPOSITION_CHANGED, this,
792 				signal, disposition));
793 	}
794 }
795 
796 
797 void
798 Team::NotifyCustomSignalDispositionRemoved(int32 signal)
799 {
800 	for (ListenerList::Iterator it = fListeners.GetIterator();
801 			Listener* listener = it.Next();) {
802 		listener->CustomSignalDispositionRemoved(
803 			CustomSignalDispositionEvent(
804 				TEAM_EVENT_CUSTOM_SIGNAL_DISPOSITION_REMOVED, this,
805 				signal, SIGNAL_DISPOSITION_IGNORE));
806 	}
807 }
808 
809 
810 void
811 Team::NotifyConsoleOutputReceived(int32 fd, const BString& output)
812 {
813 	for (ListenerList::Iterator it = fListeners.GetIterator();
814 			Listener* listener = it.Next();) {
815 		listener->ConsoleOutputReceived(
816 			ConsoleOutputEvent(TEAM_EVENT_CONSOLE_OUTPUT_RECEIVED, this,
817 				fd, output));
818 	}
819 }
820 
821 
822 void
823 Team::NotifyUserBreakpointChanged(UserBreakpoint* breakpoint)
824 {
825 	for (ListenerList::Iterator it = fListeners.GetIterator();
826 			Listener* listener = it.Next();) {
827 		listener->UserBreakpointChanged(UserBreakpointEvent(
828 			TEAM_EVENT_USER_BREAKPOINT_CHANGED, this, breakpoint));
829 	}
830 }
831 
832 
833 void
834 Team::NotifyWatchpointChanged(Watchpoint* watchpoint)
835 {
836 	for (ListenerList::Iterator it = fListeners.GetIterator();
837 			Listener* listener = it.Next();) {
838 		listener->WatchpointChanged(WatchpointEvent(
839 			TEAM_EVENT_WATCHPOINT_CHANGED, this, watchpoint));
840 	}
841 }
842 
843 
844 void
845 Team::NotifyDebugReportChanged(const char* reportPath, status_t result)
846 {
847 	for (ListenerList::Iterator it = fListeners.GetIterator();
848 			Listener* listener = it.Next();) {
849 		listener->DebugReportChanged(DebugReportEvent(
850 			TEAM_EVENT_DEBUG_REPORT_CHANGED, this, reportPath, result));
851 	}
852 }
853 
854 
855 void
856 Team::NotifyCoreFileChanged(const char* targetPath)
857 {
858 	for (ListenerList::Iterator it = fListeners.GetIterator();
859 			Listener* listener = it.Next();) {
860 		listener->CoreFileChanged(CoreFileChangedEvent(
861 			TEAM_EVENT_CORE_FILE_CHANGED, this, targetPath));
862 	}
863 }
864 
865 
866 void
867 Team::NotifyMemoryChanged(target_addr_t address, target_size_t size)
868 {
869 	for (ListenerList::Iterator it = fListeners.GetIterator();
870 			Listener* listener = it.Next();) {
871 		listener->MemoryChanged(MemoryChangedEvent(
872 			TEAM_EVENT_MEMORY_CHANGED, this, address, size));
873 	}
874 }
875 
876 
877 void
878 Team::_NotifyTeamRenamed()
879 {
880 	for (ListenerList::Iterator it = fListeners.GetIterator();
881 			Listener* listener = it.Next();) {
882 		listener->TeamRenamed(Event(TEAM_EVENT_TEAM_RENAMED, this));
883 	}
884 }
885 
886 
887 void
888 Team::_NotifyThreadAdded(Thread* thread)
889 {
890 	for (ListenerList::Iterator it = fListeners.GetIterator();
891 			Listener* listener = it.Next();) {
892 		listener->ThreadAdded(ThreadEvent(TEAM_EVENT_THREAD_ADDED, thread));
893 	}
894 }
895 
896 
897 void
898 Team::_NotifyThreadRemoved(Thread* thread)
899 {
900 	for (ListenerList::Iterator it = fListeners.GetIterator();
901 			Listener* listener = it.Next();) {
902 		listener->ThreadRemoved(ThreadEvent(TEAM_EVENT_THREAD_REMOVED, thread));
903 	}
904 }
905 
906 
907 void
908 Team::_NotifyImageAdded(Image* image)
909 {
910 	for (ListenerList::Iterator it = fListeners.GetIterator();
911 			Listener* listener = it.Next();) {
912 		listener->ImageAdded(ImageEvent(TEAM_EVENT_IMAGE_ADDED, image));
913 	}
914 }
915 
916 
917 void
918 Team::_NotifyImageRemoved(Image* image)
919 {
920 	for (ListenerList::Iterator it = fListeners.GetIterator();
921 			Listener* listener = it.Next();) {
922 		listener->ImageRemoved(ImageEvent(TEAM_EVENT_IMAGE_REMOVED, image));
923 	}
924 }
925 
926 
927 // #pragma mark - Event
928 
929 
930 Team::Event::Event(uint32 type, Team* team)
931 	:
932 	fEventType(type),
933 	fTeam(team)
934 {
935 }
936 
937 
938 // #pragma mark - ThreadEvent
939 
940 
941 Team::ThreadEvent::ThreadEvent(uint32 type, Thread* thread)
942 	:
943 	Event(type, thread->GetTeam()),
944 	fThread(thread)
945 {
946 }
947 
948 
949 // #pragma mark - ImageEvent
950 
951 
952 Team::ImageEvent::ImageEvent(uint32 type, Image* image)
953 	:
954 	Event(type, image->GetTeam()),
955 	fImage(image)
956 {
957 }
958 
959 
960 // #pragma mark - ImageLoadEvent
961 
962 
963 Team::ImageLoadEvent::ImageLoadEvent(uint32 type, Team* team,
964 	bool stopOnImageLoad, bool stopImageNameListEnabled)
965 	:
966 	Event(type, team),
967 	fStopOnImageLoad(stopOnImageLoad),
968 	fStopImageNameListEnabled(stopImageNameListEnabled)
969 {
970 }
971 
972 
973 // #pragma mark - ImageLoadNameEvent
974 
975 
976 Team::ImageLoadNameEvent::ImageLoadNameEvent(uint32 type, Team* team,
977 	const BString& name)
978 	:
979 	Event(type, team),
980 	fImageName(name)
981 {
982 }
983 
984 
985 // #pragma mark - DefaultSignalDispositionEvent
986 
987 
988 Team::DefaultSignalDispositionEvent::DefaultSignalDispositionEvent(uint32 type,
989 	Team* team, int32 disposition)
990 	:
991 	Event(type, team),
992 	fDefaultDisposition(disposition)
993 {
994 }
995 
996 
997 // #pragma mark - CustomSignalDispositionEvent
998 
999 
1000 Team::CustomSignalDispositionEvent::CustomSignalDispositionEvent(uint32 type,
1001 	Team* team, int32 signal, int32 disposition)
1002 	:
1003 	Event(type, team),
1004 	fSignal(signal),
1005 	fDisposition(disposition)
1006 {
1007 }
1008 
1009 
1010 // #pragma mark - BreakpointEvent
1011 
1012 
1013 Team::BreakpointEvent::BreakpointEvent(uint32 type, Team* team,
1014 	Breakpoint* breakpoint)
1015 	:
1016 	Event(type, team),
1017 	fBreakpoint(breakpoint)
1018 {
1019 }
1020 
1021 
1022 // #pragma mark - ConsoleOutputEvent
1023 
1024 
1025 Team::ConsoleOutputEvent::ConsoleOutputEvent(uint32 type, Team* team,
1026 	int32 fd, const BString& output)
1027 	:
1028 	Event(type, team),
1029 	fDescriptor(fd),
1030 	fOutput(output)
1031 {
1032 }
1033 
1034 
1035 // #pragma mark - DebugReportEvent
1036 
1037 
1038 Team::DebugReportEvent::DebugReportEvent(uint32 type, Team* team,
1039 	const char* reportPath, status_t finalStatus)
1040 	:
1041 	Event(type, team),
1042 	fReportPath(reportPath),
1043 	fFinalStatus(finalStatus)
1044 {
1045 }
1046 
1047 
1048 // #pragma mark - CoreFileChangedEvent
1049 
1050 
1051 Team::CoreFileChangedEvent::CoreFileChangedEvent(uint32 type, Team* team,
1052 	const char* targetPath)
1053 	:
1054 	Event(type, team),
1055 	fTargetPath(targetPath)
1056 {
1057 }
1058 
1059 
1060 // #pragma mark - MemoryChangedEvent
1061 
1062 
1063 Team::MemoryChangedEvent::MemoryChangedEvent(uint32 type, Team* team,
1064 	target_addr_t address, target_size_t size)
1065 	:
1066 	Event(type, team),
1067 	fTargetAddress(address),
1068 	fSize(size)
1069 {
1070 }
1071 
1072 
1073 // #pragma mark - WatchpointEvent
1074 
1075 
1076 Team::WatchpointEvent::WatchpointEvent(uint32 type, Team* team,
1077 	Watchpoint* watchpoint)
1078 	:
1079 	Event(type, team),
1080 	fWatchpoint(watchpoint)
1081 {
1082 }
1083 
1084 
1085 // #pragma mark - UserBreakpointEvent
1086 
1087 
1088 Team::UserBreakpointEvent::UserBreakpointEvent(uint32 type, Team* team,
1089 	UserBreakpoint* breakpoint)
1090 	:
1091 	Event(type, team),
1092 	fBreakpoint(breakpoint)
1093 {
1094 }
1095 
1096 
1097 // #pragma mark - Listener
1098 
1099 
1100 Team::Listener::~Listener()
1101 {
1102 }
1103 
1104 
1105 void
1106 Team::Listener::TeamRenamed(const Team::Event& event)
1107 {
1108 }
1109 
1110 
1111 void
1112 Team::Listener::ThreadAdded(const Team::ThreadEvent& event)
1113 {
1114 }
1115 
1116 
1117 void
1118 Team::Listener::ThreadRemoved(const Team::ThreadEvent& event)
1119 {
1120 }
1121 
1122 
1123 void
1124 Team::Listener::ImageAdded(const Team::ImageEvent& event)
1125 {
1126 }
1127 
1128 
1129 void
1130 Team::Listener::ImageRemoved(const Team::ImageEvent& event)
1131 {
1132 }
1133 
1134 
1135 void
1136 Team::Listener::ThreadStateChanged(const Team::ThreadEvent& event)
1137 {
1138 }
1139 
1140 
1141 void
1142 Team::Listener::ThreadCpuStateChanged(const Team::ThreadEvent& event)
1143 {
1144 }
1145 
1146 
1147 void
1148 Team::Listener::ThreadStackTraceChanged(const Team::ThreadEvent& event)
1149 {
1150 }
1151 
1152 
1153 void
1154 Team::Listener::ImageDebugInfoChanged(const Team::ImageEvent& event)
1155 {
1156 }
1157 
1158 
1159 void
1160 Team::Listener::StopOnImageLoadSettingsChanged(
1161 	const Team::ImageLoadEvent& event)
1162 {
1163 }
1164 
1165 
1166 void
1167 Team::Listener::StopOnImageLoadNameAdded(const Team::ImageLoadNameEvent& event)
1168 {
1169 }
1170 
1171 
1172 void
1173 Team::Listener::StopOnImageLoadNameRemoved(
1174 	const Team::ImageLoadNameEvent& event)
1175 {
1176 }
1177 
1178 
1179 void
1180 Team::Listener::DefaultSignalDispositionChanged(
1181 	const Team::DefaultSignalDispositionEvent& event)
1182 {
1183 }
1184 
1185 
1186 void
1187 Team::Listener::CustomSignalDispositionChanged(
1188 	const Team::CustomSignalDispositionEvent& event)
1189 {
1190 }
1191 
1192 
1193 void
1194 Team::Listener::CustomSignalDispositionRemoved(
1195 	const Team::CustomSignalDispositionEvent& event)
1196 {
1197 }
1198 
1199 
1200 void
1201 Team::Listener::ConsoleOutputReceived(const Team::ConsoleOutputEvent& event)
1202 {
1203 }
1204 
1205 
1206 void
1207 Team::Listener::BreakpointAdded(const Team::BreakpointEvent& event)
1208 {
1209 }
1210 
1211 
1212 void
1213 Team::Listener::BreakpointRemoved(const Team::BreakpointEvent& event)
1214 {
1215 }
1216 
1217 
1218 void
1219 Team::Listener::UserBreakpointChanged(const Team::UserBreakpointEvent& event)
1220 {
1221 }
1222 
1223 
1224 void
1225 Team::Listener::WatchpointAdded(const Team::WatchpointEvent& event)
1226 {
1227 }
1228 
1229 
1230 void
1231 Team::Listener::WatchpointRemoved(const Team::WatchpointEvent& event)
1232 {
1233 }
1234 
1235 
1236 void
1237 Team::Listener::WatchpointChanged(const Team::WatchpointEvent& event)
1238 {
1239 }
1240 
1241 
1242 void
1243 Team::Listener::DebugReportChanged(const Team::DebugReportEvent& event)
1244 {
1245 }
1246 
1247 
1248 void
1249 Team::Listener::CoreFileChanged(const Team::CoreFileChangedEvent& event)
1250 {
1251 }
1252 
1253 
1254 void
1255 Team::Listener::MemoryChanged(const Team::MemoryChangedEvent& event)
1256 {
1257 }
1258