| // Copyright 2019 The SwiftShader Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef VK_DEBUG_CONTEXT_HPP_ |
| #define VK_DEBUG_CONTEXT_HPP_ |
| |
| #include "ID.hpp" |
| |
| #include <memory> |
| #include <string> |
| #include <unordered_set> |
| #include <vector> |
| |
| namespace vk { |
| namespace dbg { |
| |
| // Forward declarations. |
| class Thread; |
| class File; |
| class Frame; |
| class Scope; |
| class Variables; |
| class ClientEventListener; |
| class ServerEventListener; |
| |
| // Context holds the full state of the debugger, including all current files, |
| // threads, frames and variables. It also holds a list of EventListeners that |
| // can be broadcast to using the Context::broadcast() interface. |
| // Context requires locking before accessing any state. The lock is |
| // non-reentrant and careful use is required to prevent accidentical |
| // double-locking by the same thread. |
| class Context |
| { |
| class Impl; |
| |
| public: |
| // Lock is the interface to the Context's state. |
| // The lock is automatically released when the Lock is destructed. |
| class Lock |
| { |
| public: |
| Lock(Impl *); |
| Lock(Lock &&); |
| ~Lock(); |
| |
| // move-assignment operator. |
| Lock &operator=(Lock &&); |
| |
| // unlock() explicitly unlocks before the Lock destructor is called. |
| // It is illegal to call any other methods after calling unlock(). |
| void unlock(); |
| |
| // currentThread() creates (or returns an existing) a Thread that |
| // represents the currently executing thread. |
| std::shared_ptr<Thread> currentThread(); |
| |
| // get() returns the thread with the given ID, or null if the thread |
| // does not exist or no longer has any external shared_ptr references. |
| std::shared_ptr<Thread> get(ID<Thread>); |
| |
| // threads() returns the full list of threads that still have an |
| // external shared_ptr reference. |
| std::vector<std::shared_ptr<Thread>> threads(); |
| |
| // createVirtualFile() returns a new file that is not backed by the |
| // filesystem. |
| // name is the unique name of the file. |
| // source is the content of the file. |
| std::shared_ptr<File> createVirtualFile(const std::string &name, |
| const std::string &source); |
| |
| // createPhysicalFile() returns a new file that is backed by the file |
| // at path. |
| std::shared_ptr<File> createPhysicalFile(const std::string &path); |
| |
| // get() returns the file with the given ID, or null if the file |
| // does not exist or no longer has any external shared_ptr references. |
| std::shared_ptr<File> get(ID<File>); |
| |
| // findFile() returns the file with the given path, or nullptr if not |
| // found. |
| std::shared_ptr<File> findFile(const std::string &path); |
| |
| // files() returns the full list of files. |
| std::vector<std::shared_ptr<File>> files(); |
| |
| // createFrame() returns a new frame for the given file and function |
| // name. |
| std::shared_ptr<Frame> createFrame( |
| const std::shared_ptr<File> &file, std::string function); |
| |
| // get() returns the frame with the given ID, or null if the frame |
| // does not exist or no longer has any external shared_ptr references. |
| std::shared_ptr<Frame> get(ID<Frame>); |
| |
| // createScope() returns a new scope for the given file. |
| std::shared_ptr<Scope> createScope( |
| const std::shared_ptr<File> &file); |
| |
| // get() returns the scope with the given ID, or null if the scope |
| // does not exist. |
| std::shared_ptr<Scope> get(ID<Scope>); |
| |
| // track() registers the variables with the context so it can be |
| // retrieved by get(). Note that the context does not hold a strong |
| // reference to the variables, and get() will return nullptr if all |
| // strong external references are dropped. |
| void track(const std::shared_ptr<Variables> &); |
| |
| // get() returns the variables with the given ID, or null if the |
| // variables does not exist or no longer has any external shared_ptr |
| // references. |
| std::shared_ptr<Variables> get(ID<Variables>); |
| |
| // clearFunctionBreakpoints() removes all function breakpoints. |
| void clearFunctionBreakpoints(); |
| |
| // addFunctionBreakpoint() adds a breakpoint to the start of the |
| // function with the given name. |
| void addFunctionBreakpoint(const std::string &name); |
| |
| // addPendingBreakpoints() adds a number of breakpoints to the file with |
| // the given name which has not yet been created with a call to |
| // createVirtualFile() or createPhysicalFile(). |
| void addPendingBreakpoints(const std::string &name, const std::vector<int> &lines); |
| |
| // isFunctionBreakpoint() returns true if the function with the given |
| // name has a function breakpoint set. |
| bool isFunctionBreakpoint(const std::string &name); |
| |
| // getFunctionBreakpoints() returns all the set function breakpoints. |
| std::unordered_set<std::string> getFunctionBreakpoints(); |
| |
| private: |
| Lock(const Lock &) = delete; |
| Lock &operator=(const Lock &) = delete; |
| Impl *ctx; |
| }; |
| |
| // create() creates and returns a new Context. |
| static std::shared_ptr<Context> create(); |
| |
| virtual ~Context() = default; |
| |
| // lock() returns a Lock which exclusively locks the context for state |
| // access. |
| virtual Lock lock() = 0; |
| |
| // addListener() registers an ClientEventListener for event notifications. |
| virtual void addListener(ClientEventListener *) = 0; |
| |
| // removeListener() unregisters an ClientEventListener that was previously |
| // registered by a call to addListener(). |
| virtual void removeListener(ClientEventListener *) = 0; |
| |
| // clientEventBroadcast() returns an ClientEventListener that will broadcast |
| // all method calls on to all registered ServerEventListeners. |
| virtual ClientEventListener *clientEventBroadcast() = 0; |
| |
| // addListener() registers an ServerEventListener for event notifications. |
| virtual void addListener(ServerEventListener *) = 0; |
| |
| // removeListener() unregisters an ServerEventListener that was previously |
| // registered by a call to addListener(). |
| virtual void removeListener(ServerEventListener *) = 0; |
| |
| // serverEventBroadcast() returns an ServerEventListener that will broadcast |
| // all method calls on to all registered ServerEventListeners. |
| virtual ServerEventListener *serverEventBroadcast() = 0; |
| }; |
| |
| } // namespace dbg |
| } // namespace vk |
| |
| #endif // VK_DEBUG_CONTEXT_HPP_ |