| // 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 <vector> |
| |
| namespace vk { |
| namespace dbg { |
| |
| // Forward declarations. |
| class Thread; |
| class File; |
| class Frame; |
| class Scope; |
| class VariableContainer; |
| class EventListener; |
| |
| // 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>); |
| |
| // 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 variable container with the context so it can |
| // be retrieved by get(). Note that the context does not hold a strong |
| // reference to the variable container, and get() will return nullptr |
| // if all strong external references are dropped. |
| void track(const std::shared_ptr<VariableContainer> &); |
| |
| // get() returns the variable container with the given ID, or null if |
| // the variable container does not exist or no longer has any external |
| // shared_ptr references. |
| std::shared_ptr<VariableContainer> get(ID<VariableContainer>); |
| |
| // 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); |
| |
| 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 EventListener for event notifications. |
| virtual void addListener(EventListener *) = 0; |
| |
| // removeListener() unregisters an EventListener that was previously |
| // registered by a call to addListener(). |
| virtual void removeListener(EventListener *) = 0; |
| |
| // broadcast() returns an EventListener that will broadcast all methods on |
| // to all registered EventListeners. |
| virtual EventListener *broadcast() = 0; |
| }; |
| |
| } // namespace dbg |
| } // namespace vk |
| |
| #endif // VK_DEBUG_CONTEXT_HPP_ |