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