xref: /haiku/src/kits/debugger/debug_managers/WatchpointManager.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 /*
2  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2012, Rene Gollent, rene@gollent.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 #include "WatchpointManager.h"
8 
9 #include <stdio.h>
10 
11 #include <new>
12 
13 #include <AutoLocker.h>
14 
15 #include "DebuggerInterface.h"
16 #include "Team.h"
17 #include "Tracing.h"
18 
19 
20 WatchpointManager::WatchpointManager(Team* team,
21 	DebuggerInterface* debuggerInterface)
22 	:
23 	fLock("watchpoint manager"),
24 	fTeam(team),
25 	fDebuggerInterface(debuggerInterface)
26 {
27 	fDebuggerInterface->AcquireReference();
28 }
29 
30 
31 WatchpointManager::~WatchpointManager()
32 {
33 	fDebuggerInterface->ReleaseReference();
34 }
35 
36 
37 status_t
38 WatchpointManager::Init()
39 {
40 	return fLock.InitCheck();
41 }
42 
43 
44 status_t
45 WatchpointManager::InstallWatchpoint(Watchpoint* watchpoint,
46 	bool enabled)
47 {
48 	status_t error = B_OK;
49 	TRACE_CONTROL("WatchpointManager::InstallUserWatchpoint(%p, %d)\n",
50 		watchpoint, enabled);
51 
52 	AutoLocker<BLocker> installLocker(fLock);
53 	AutoLocker<Team> teamLocker(fTeam);
54 
55 	bool oldEnabled = watchpoint->IsEnabled();
56 	if (enabled == oldEnabled) {
57 		TRACE_CONTROL("  watchpoint already valid and with same enabled "
58 			"state\n");
59 		return B_OK;
60 	}
61 
62 	watchpoint->SetEnabled(enabled);
63 
64 	if (watchpoint->ShouldBeInstalled()) {
65 		error = fDebuggerInterface->InstallWatchpoint(watchpoint->Address(),
66 			watchpoint->Type(), watchpoint->Length());
67 
68 		if (error == B_OK)
69 			watchpoint->SetInstalled(true);
70 	} else {
71 		error = fDebuggerInterface->UninstallWatchpoint(watchpoint->Address());
72 
73 		if (error == B_OK)
74 			watchpoint->SetInstalled(false);
75 	}
76 
77 	if (error == B_OK) {
78 		if (fTeam->WatchpointAtAddress(watchpoint->Address()) == NULL)
79 			fTeam->AddWatchpoint(watchpoint);
80 		fTeam->NotifyWatchpointChanged(watchpoint);
81 	}
82 
83 	return error;
84 }
85 
86 
87 void
88 WatchpointManager::UninstallWatchpoint(Watchpoint* watchpoint)
89 {
90 	AutoLocker<BLocker> installLocker(fLock);
91 	AutoLocker<Team> teamLocker(fTeam);
92 
93 	fTeam->RemoveWatchpoint(watchpoint);
94 
95 	if (!watchpoint->IsInstalled())
96 		return;
97 
98 	status_t error = fDebuggerInterface->UninstallWatchpoint(
99 		watchpoint->Address());
100 
101 	if (error == B_OK) {
102 		watchpoint->SetInstalled(false);
103 		fTeam->NotifyWatchpointChanged(watchpoint);
104 	}
105 }
106