• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef VK_DEBUG_CONTEXT_HPP_
16 #define VK_DEBUG_CONTEXT_HPP_
17 
18 #include "ID.hpp"
19 
20 #include <memory>
21 #include <string>
22 #include <unordered_set>
23 #include <vector>
24 
25 namespace vk {
26 namespace dbg {
27 
28 // Forward declarations.
29 class Thread;
30 class File;
31 class Frame;
32 class Scope;
33 class Variables;
34 class ClientEventListener;
35 class ServerEventListener;
36 
37 // Context holds the full state of the debugger, including all current files,
38 // threads, frames and variables. It also holds a list of EventListeners that
39 // can be broadcast to using the Context::broadcast() interface.
40 // Context requires locking before accessing any state. The lock is
41 // non-reentrant and careful use is required to prevent accidentical
42 // double-locking by the same thread.
43 class Context
44 {
45 	class Impl;
46 
47 public:
48 	// Lock is the interface to the Context's state.
49 	// The lock is automatically released when the Lock is destructed.
50 	class Lock
51 	{
52 	public:
53 		Lock(Impl *);
54 		Lock(Lock &&);
55 		~Lock();
56 
57 		// move-assignment operator.
58 		Lock &operator=(Lock &&);
59 
60 		// unlock() explicitly unlocks before the Lock destructor is called.
61 		// It is illegal to call any other methods after calling unlock().
62 		void unlock();
63 
64 		// currentThread() creates (or returns an existing) a Thread that
65 		// represents the currently executing thread.
66 		std::shared_ptr<Thread> currentThread();
67 
68 		// get() returns the thread with the given ID, or null if the thread
69 		// does not exist or no longer has any external shared_ptr references.
70 		std::shared_ptr<Thread> get(ID<Thread>);
71 
72 		// threads() returns the full list of threads that still have an
73 		// external shared_ptr reference.
74 		std::vector<std::shared_ptr<Thread>> threads();
75 
76 		// createVirtualFile() returns a new file that is not backed by the
77 		// filesystem.
78 		// name is the unique name of the file.
79 		// source is the content of the file.
80 		std::shared_ptr<File> createVirtualFile(const std::string &name,
81 		                                        const std::string &source);
82 
83 		// createPhysicalFile() returns a new file that is backed by the file
84 		// at path.
85 		std::shared_ptr<File> createPhysicalFile(const std::string &path);
86 
87 		// get() returns the file with the given ID, or null if the file
88 		// does not exist or no longer has any external shared_ptr references.
89 		std::shared_ptr<File> get(ID<File>);
90 
91 		// findFile() returns the file with the given path, or nullptr if not
92 		// found.
93 		std::shared_ptr<File> findFile(const std::string &path);
94 
95 		// files() returns the full list of files.
96 		std::vector<std::shared_ptr<File>> files();
97 
98 		// createFrame() returns a new frame for the given file and function
99 		// name.
100 		std::shared_ptr<Frame> createFrame(
101 		    const std::shared_ptr<File> &file, std::string function);
102 
103 		// get() returns the frame with the given ID, or null if the frame
104 		// does not exist or no longer has any external shared_ptr references.
105 		std::shared_ptr<Frame> get(ID<Frame>);
106 
107 		// createScope() returns a new scope for the given file.
108 		std::shared_ptr<Scope> createScope(
109 		    const std::shared_ptr<File> &file);
110 
111 		// get() returns the scope with the given ID, or null if the scope
112 		// does not exist.
113 		std::shared_ptr<Scope> get(ID<Scope>);
114 
115 		// track() registers the variables with the context so it can be
116 		// retrieved by get(). Note that the context does not hold a strong
117 		// reference to the variables, and get() will return nullptr if all
118 		// strong external references are dropped.
119 		void track(const std::shared_ptr<Variables> &);
120 
121 		// get() returns the variables with the given ID, or null if the
122 		// variables does not exist or no longer has any external shared_ptr
123 		// references.
124 		std::shared_ptr<Variables> get(ID<Variables>);
125 
126 		// clearFunctionBreakpoints() removes all function breakpoints.
127 		void clearFunctionBreakpoints();
128 
129 		// addFunctionBreakpoint() adds a breakpoint to the start of the
130 		// function with the given name.
131 		void addFunctionBreakpoint(const std::string &name);
132 
133 		// addPendingBreakpoints() adds a number of breakpoints to the file with
134 		// the given name which has not yet been created with a call to
135 		// createVirtualFile() or createPhysicalFile().
136 		void addPendingBreakpoints(const std::string &name, const std::vector<int> &lines);
137 
138 		// isFunctionBreakpoint() returns true if the function with the given
139 		// name has a function breakpoint set.
140 		bool isFunctionBreakpoint(const std::string &name);
141 
142 		// getFunctionBreakpoints() returns all the set function breakpoints.
143 		std::unordered_set<std::string> getFunctionBreakpoints();
144 
145 	private:
146 		Lock(const Lock &) = delete;
147 		Lock &operator=(const Lock &) = delete;
148 		Impl *ctx;
149 	};
150 
151 	// create() creates and returns a new Context.
152 	static std::shared_ptr<Context> create();
153 
154 	virtual ~Context() = default;
155 
156 	// lock() returns a Lock which exclusively locks the context for state
157 	// access.
158 	virtual Lock lock() = 0;
159 
160 	// addListener() registers an ClientEventListener for event notifications.
161 	virtual void addListener(ClientEventListener *) = 0;
162 
163 	// removeListener() unregisters an ClientEventListener that was previously
164 	// registered by a call to addListener().
165 	virtual void removeListener(ClientEventListener *) = 0;
166 
167 	// clientEventBroadcast() returns an ClientEventListener that will broadcast
168 	// all method calls on to all registered ServerEventListeners.
169 	virtual ClientEventListener *clientEventBroadcast() = 0;
170 
171 	// addListener() registers an ServerEventListener for event notifications.
172 	virtual void addListener(ServerEventListener *) = 0;
173 
174 	// removeListener() unregisters an ServerEventListener that was previously
175 	// registered by a call to addListener().
176 	virtual void removeListener(ServerEventListener *) = 0;
177 
178 	// serverEventBroadcast() returns an ServerEventListener that will broadcast
179 	// all method calls on to all registered ServerEventListeners.
180 	virtual ServerEventListener *serverEventBroadcast() = 0;
181 };
182 
183 }  // namespace dbg
184 }  // namespace vk
185 
186 #endif  // VK_DEBUG_CONTEXT_HPP_
187