| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_DEVELOPER_DEBUG_ZXDB_DEBUG_ADAPTER_CONTEXT_H_ |
| #define SRC_DEVELOPER_DEBUG_ZXDB_DEBUG_ADAPTER_CONTEXT_H_ |
| |
| #include <dap/protocol.h> |
| #include <dap/session.h> |
| |
| #include "src/developer/debug/shared/stream_buffer.h" |
| #include "src/developer/debug/zxdb/client/frame.h" |
| #include "src/developer/debug/zxdb/client/process_observer.h" |
| #include "src/developer/debug/zxdb/client/session.h" |
| #include "src/developer/debug/zxdb/client/thread_observer.h" |
| #include "src/developer/debug/zxdb/common/err.h" |
| |
| namespace zxdb { |
| |
| class Session; |
| class DebugAdapterServer; |
| class DebugAdapterReader; |
| class DebugAdapterWriter; |
| |
| // Handles processing requests from debug adapter client with help from zxdb client session and dap |
| // library. |
| // Note: All methods in this class need to be executed on main thread to avoid concurrency bugs. |
| class DebugAdapterContext : public ThreadObserver, ProcessObserver { |
| public: |
| explicit DebugAdapterContext(Session* session, debug_ipc::StreamBuffer* stream); |
| |
| virtual ~DebugAdapterContext(); |
| |
| Session* session() { return session_; } |
| dap::Session& dap() { return *dap_; } |
| bool supports_run_in_terminal() { return supports_run_in_terminal_; }; |
| |
| // Notification about the stream. |
| void OnStreamReadable(); |
| |
| // ThreadObserver implementation: |
| void DidCreateThread(Thread* thread) override; |
| void WillDestroyThread(Thread* thread) override; |
| void OnThreadStopped(Thread* thread, const StopInfo& info) override; |
| void OnThreadFramesInvalidated(Thread* thread) override; |
| |
| // ProcessObserver implementation: |
| void DidCreateProcess(Process* process, bool autoattached_to_new_process, |
| uint64_t timestamp) override; |
| |
| Target* GetCurrentTarget(); |
| Process* GetCurrentProcess(); |
| Thread* GetThread(uint64_t koid); |
| |
| // Checks if thread is in stopped state; returns error if not stopped. |
| // `thread` can be nullptr, in which case an error is returned. |
| Err CheckStoppedThread(Thread* thread); |
| |
| // Helper methods to get/set frame to ID mapping |
| int IdForFrame(Frame* frame, int stack_index); |
| Frame* FrameforId(int id); |
| void DeleteFrameIdsForThread(Thread* thread); |
| |
| private: |
| Session* const session_; |
| const std::unique_ptr<dap::Session> dap_; |
| std::shared_ptr<DebugAdapterReader> reader_; |
| std::shared_ptr<DebugAdapterWriter> writer_; |
| |
| bool supports_run_in_terminal_ = false; |
| bool supports_invalidate_event_ = false; |
| bool init_done_ = false; |
| |
| struct FrameRecord { |
| uint64_t thread_koid = 0; |
| int stack_index = 0; |
| }; |
| |
| std::map<int, FrameRecord> id_to_frame_; |
| int next_frame_id_ = 1; |
| |
| void Init(); |
| }; |
| |
| class DebugAdapterReader : public dap::Reader { |
| public: |
| explicit DebugAdapterReader(debug_ipc::StreamBuffer* stream) : stream_(stream) {} |
| size_t read(void* buffer, size_t n) override { |
| if (!stream_) { |
| return 0; |
| } |
| auto ret = stream_->Read(static_cast<char*>(buffer), n); |
| return ret; |
| } |
| bool isOpen() override { return !!stream_; } |
| |
| void close() override { stream_ = nullptr; } |
| |
| private: |
| debug_ipc::StreamBuffer* stream_ = nullptr; |
| }; |
| |
| class DebugAdapterWriter : public dap::Writer { |
| public: |
| explicit DebugAdapterWriter(debug_ipc::StreamBuffer* stream) : stream_(stream) {} |
| bool write(const void* buffer, size_t n) override { |
| if (!stream_) { |
| return false; |
| } |
| stream_->Write( |
| std::vector<char>(static_cast<const char*>(buffer), static_cast<const char*>(buffer) + n)); |
| return true; |
| } |
| bool isOpen() override { return !!stream_; } |
| |
| void close() override { stream_ = nullptr; } |
| |
| private: |
| debug_ipc::StreamBuffer* stream_ = nullptr; |
| }; |
| |
| } // namespace zxdb |
| |
| #endif // SRC_DEVELOPER_DEBUG_ZXDB_DEBUG_ADAPTER_CONTEXT_H_ |