diff options
30 files changed, 1533 insertions, 3 deletions
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h index 93bc3bc121e..e094b639659 100644 --- a/lldb/include/lldb/API/LLDB.h +++ b/lldb/include/lldb/API/LLDB.h @@ -40,6 +40,8 @@ #include "lldb/API/SBListener.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBProcess.h" +#include "lldb/API/SBQueue.h" +#include "lldb/API/SBQueueItem.h" #include "lldb/API/SBSourceManager.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" diff --git a/lldb/include/lldb/API/SBAddress.h b/lldb/include/lldb/API/SBAddress.h index c5e8cc685a4..58a7d2bfb1d 100644 --- a/lldb/include/lldb/API/SBAddress.h +++ b/lldb/include/lldb/API/SBAddress.h @@ -118,6 +118,7 @@ protected: friend class SBTarget; friend class SBThread; friend class SBValue; + friend class SBQueueItem; lldb_private::Address * operator->(); diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4ecaeaa4992..ccf63b44fa0 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -13,6 +13,7 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" #include "lldb/API/SBTarget.h" +#include "lldb/API/SBQueue.h" #include <stdio.h> namespace lldb { @@ -142,6 +143,15 @@ public: SetSelectedThreadByIndexID (uint32_t index_id); //------------------------------------------------------------------ + // Queue related functions + //------------------------------------------------------------------ + uint32_t + GetNumQueues (); + + lldb::SBQueue + GetQueueAtIndex (size_t index); + + //------------------------------------------------------------------ // Stepping related functions //------------------------------------------------------------------ @@ -312,6 +322,7 @@ protected: friend class SBTarget; friend class SBThread; friend class SBValue; + friend class SBQueue; lldb::ProcessSP GetSP() const; diff --git a/lldb/include/lldb/API/SBQueue.h b/lldb/include/lldb/API/SBQueue.h new file mode 100644 index 00000000000..84b0f8cc300 --- /dev/null +++ b/lldb/include/lldb/API/SBQueue.h @@ -0,0 +1,83 @@ +//===-- SBQueue.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBQueue_h_ +#define LLDB_SBQueue_h_ + +#include <vector> + +#include "lldb/lldb-forward.h" +#include "lldb/Host/Mutex.h" +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBQueueItem.h" + +namespace lldb { + +class SBQueue +{ +public: + SBQueue (); + + SBQueue (const QueueSP& queue_sp); + + ~SBQueue(); + + bool + IsValid() const; + + void + Clear (); + + lldb::SBProcess + GetProcess (); + + lldb::queue_id_t + GetQueueID () const; + + const char * + GetName () const; + + uint32_t + GetIndexID () const; + + uint32_t + GetNumThreads (); + + lldb::SBThread + GetThreadAtIndex (uint32_t); + + uint32_t + GetNumItems (); + + lldb::SBQueueItem + GetItemAtIndex (uint32_t); + +protected: + friend class SBProcess; + + void + SetQueue (const lldb::QueueSP& queue_sp); + + void + FetchThreads (); + + void + FetchItems (); + +private: + lldb::QueueWP m_queue_wp; + std::vector<lldb::ThreadWP> m_threads; // threads currently executing this queue's items + bool m_thread_list_fetched; // have we tried to fetch the threads list already? + std::vector<lldb::QueueItemSP> m_items; // items currently enqueued + bool m_queue_items_fetched; // have we tried to fetch the item list already? +}; + +} // namespace lldb + +#endif // LLDB_SBQueue_h_ diff --git a/lldb/include/lldb/API/SBQueueItem.h b/lldb/include/lldb/API/SBQueueItem.h new file mode 100644 index 00000000000..23d06e2ac9c --- /dev/null +++ b/lldb/include/lldb/API/SBQueueItem.h @@ -0,0 +1,58 @@ +//===-- SBQueueItem.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBQueueItem_h_ +#define LLDB_SBQueueItem_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/Core/Address.h" +#include "lldb/API/SBAddress.h" + +namespace lldb { + +class SBQueueItem +{ +public: + SBQueueItem (); + + SBQueueItem (const lldb::QueueItemSP& queue_item_sp); + + ~SBQueueItem(); + + bool + IsValid() const; + + void + Clear (); + + lldb::QueueItemKind + GetKind () const; + + void + SetKind (lldb::QueueItemKind kind); + + lldb::SBAddress + GetAddress () const; + + void + SetAddress (lldb::SBAddress addr); + + void + SetQueueItem (const lldb::QueueItemSP& queue_item_sp); + + SBThread + GetExtendedBacktraceThread (const char *type); + +private: + lldb::QueueItemSP m_queue_item_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBQueueItem_h_ diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h index 6542dca1f95..c8c882bc2bb 100644 --- a/lldb/include/lldb/API/SBThread.h +++ b/lldb/include/lldb/API/SBThread.h @@ -214,6 +214,8 @@ protected: friend class SBProcess; friend class SBDebugger; friend class SBValue; + friend class SBQueue; + friend class SBQueueItem; void SetThread (const lldb::ThreadSP& lldb_object_sp); diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 6ad6d7de79a..ce910944579 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -43,6 +43,7 @@ #include "lldb/Interpreter/Options.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Memory.h" +#include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/PseudoTerminal.h" @@ -3317,10 +3318,10 @@ public: { return m_thread_list.Threads(); } - + uint32_t GetNextThreadIndexID (uint64_t thread_id); - + lldb::ThreadSP CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context); @@ -3333,6 +3334,36 @@ public: uint32_t AssignIndexIDToThread(uint64_t thread_id); + // Returns true if an index id has been assigned to a queue. + bool + HasAssignedIndexIDToQueue(lldb::queue_id_t queue_id); + + // Given a queue_id, it will assign a more reasonable index id for display to the user. + // If the queue_id has previously been assigned, the same index id will be used. + uint32_t + AssignIndexIDToQueue(lldb::queue_id_t queue_id); + + //------------------------------------------------------------------ + // Queue Queries + //------------------------------------------------------------------ + + void + UpdateQueueListIfNeeded (); + + QueueList & + GetQueueList () + { + UpdateQueueListIfNeeded(); + return m_queue_list; + } + + QueueList::QueueIterable + Queues () + { + UpdateQueueListIfNeeded(); + return m_queue_list.Queues(); + } + //------------------------------------------------------------------ // Event Handling //------------------------------------------------------------------ @@ -3676,7 +3707,9 @@ protected: ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations. uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used. + uint32_t m_queue_index_id; ///< Each queue is created with a 1 based index that won't get re-used. std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map; + std::map<uint64_t, uint32_t> m_queue_id_to_index_id_map; int m_exit_status; ///< The exit status of the process, or -1 if not set. std::string m_exit_string; ///< A textual description of why a process exited. Mutex m_thread_mutex; @@ -3685,6 +3718,8 @@ protected: ///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads ThreadList m_extended_thread_list; ///< Owner for extended threads that may be generated, cleared on natural stops uint32_t m_extended_thread_stop_id; ///< The natural stop id when extended_thread_list was last updated + QueueList m_queue_list; ///< The list of libdispatch queues at a given stop point + uint32_t m_queue_list_stop_id; ///< The natural stop id when queue list was last fetched std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver. std::vector<lldb::addr_t> m_image_tokens; Listener &m_listener; diff --git a/lldb/include/lldb/Target/Queue.h b/lldb/include/lldb/Target/Queue.h new file mode 100644 index 00000000000..0d30613f733 --- /dev/null +++ b/lldb/include/lldb/Target/Queue.h @@ -0,0 +1,140 @@ +//===-- Queue.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Queue_h_ +#define liblldb_Queue_h_ + +#include <vector> +#include <string> + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// Queue: +// This class represents a libdispatch aka Grand Central Dispatch +// queue in the process. +// +// A program using libdispatch will create queues, put work items +// (functions, blocks) on the queues. The system will create / +// reassign pthreads to execute the work items for the queues. A +// serial queue will be associated with a single thread (or possibly +// no thread, if it is not doing any work). A concurrent queue may +// be associated with multiple threads. +//------------------------------------------------------------------ + + +class Queue : + public std::enable_shared_from_this<Queue> +{ +public: + + Queue (lldb::ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue_name); + + ~Queue (); + + //------------------------------------------------------------------ + /// Get the QueueID for this Queue + /// + /// A 64-bit ID number that uniquely identifies a queue at this particular + /// stop_id. It is not guaranteed that the same QueueID will not be reused + /// for a different queue later in the process execution after this queue + /// has been deleted. + /// + /// @return + /// The QueueID for this Queue. + //------------------------------------------------------------------ + lldb::queue_id_t + GetID (); + + //------------------------------------------------------------------ + /// Get the name of this Queue + /// + /// @return + /// The name of the queue, if one is available. + /// A NULL pointer is returned if none is available. + //------------------------------------------------------------------ + const char * + GetName (); + + //------------------------------------------------------------------ + /// Get the IndexID for this Queue + /// + /// An IndexID is a small integer value (starting with 1) assigned to + /// each queue that is seen during a Process lifetime. Ideally an + /// IndexID will not be reused (although note that QueueID, which it is + /// based on, is not guaranteed to be unique across the run of a program + /// and IndexID depends on QueueID) - so if a Queue appears as IndexID 5, + /// it will continue to show up as IndexID 5 at every process stop while + /// that queue still exists. + /// + /// @return + /// The IndexID for this queue. + //------------------------------------------------------------------ + uint32_t + GetIndexID (); + + //------------------------------------------------------------------ + /// Return the threads currently associated with this queue + /// + /// Zero, one, or many threads may be executing code for a queue at + /// a given point in time. This call returns the list of threads + /// that are currently executing work for this queue. + /// + /// @return + /// The threads currently performing work for this queue + //------------------------------------------------------------------ + std::vector<lldb::ThreadSP> + GetThreads (); + + //------------------------------------------------------------------ + /// Return the items that are currently enqueued + /// + /// "Enqueued" means that the item has been added to the queue to + /// be done, but has not yet been done. When the item is going to + /// be processed it is "dequeued". + /// + /// @return + /// The vector of enqueued items for this queue + //------------------------------------------------------------------ + const std::vector<lldb::QueueItemSP> & + GetItems() const + { + return m_enqueued_items; + } + + lldb::ProcessSP + GetProcess() const + { + return m_process_wp.lock(); + } + +protected: + lldb::ProcessWP m_process_wp; + lldb::queue_id_t m_queue_id; + uint32_t m_index_id; + std::string m_queue_name; + std::vector<lldb::QueueItemSP> m_enqueued_items; + +private: + //------------------------------------------------------------------ + // For Queue only + //------------------------------------------------------------------ + + DISALLOW_COPY_AND_ASSIGN (Queue); + +}; + +} // namespace lldb_private + +#endif // liblldb_Queue_h_ diff --git a/lldb/include/lldb/Target/QueueItem.h b/lldb/include/lldb/Target/QueueItem.h new file mode 100644 index 00000000000..210f21afa1a --- /dev/null +++ b/lldb/include/lldb/Target/QueueItem.h @@ -0,0 +1,133 @@ +//===-- QueueItem.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_QueueItem_h_ +#define liblldb_QueueItem_h_ + +#include "lldb/lldb-private.h" +#include "lldb/lldb-enumerations.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/ConstString.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// QueueItem: +// This class represents a work item enqueued on a libdispatch aka +// Grand Central Dispatch (GCD) queue. Most often, this will be a +// function or block. +// "enqueued" here means that the work item has been added to a queue +// but it has not yet started executing. When it is "dequeued", +// execution of the item begins. +//------------------------------------------------------------------ + + +class QueueItem +{ +public: + + QueueItem (lldb::QueueSP queue_sp); + + ~QueueItem (); + + //------------------------------------------------------------------ + /// Get the kind of work item this is + /// + /// @return + /// The type of work item that this QueueItem object + /// represents. eQueueItemKindUnknown may be returned. + //------------------------------------------------------------------ + lldb::QueueItemKind + GetKind () const; + + //------------------------------------------------------------------ + /// Set the type of work item this is + /// + /// @param [in] item_kind + /// Set the kind of this work item object. + //------------------------------------------------------------------ + void + SetKind (lldb::QueueItemKind item_kind); + + //------------------------------------------------------------------ + /// Get the code address that will be executed when this work item + /// is executed. + /// + /// @return + /// The address that will be invoked when this work item is + /// executed. Not all types of QueueItems will have an + /// address associated with them; check that the returned + /// Address is valid, or check that the WorkItemKind is a + /// kind that involves an address, such as eQueueItemKindFunction + /// or eQueueItemKindBlock. + //------------------------------------------------------------------ + lldb_private::Address & + GetAddress (); + + //------------------------------------------------------------------ + /// Set the work item address for this object + /// + /// @param [in] addr + /// The address that will be invoked when this work item + /// is executed. + //------------------------------------------------------------------ + void + SetAddress (lldb_private::Address addr); + + //------------------------------------------------------------------ + /// Check if this QueueItem object is valid + /// + /// If the weak pointer to the parent Queue cannot be revivified, + /// it is invalid. + /// + /// @return + /// True if this object is valid. + //------------------------------------------------------------------ + bool + IsValid () + { + return m_queue_wp.lock() != NULL; + } + + //------------------------------------------------------------------ + /// Get an extended backtrace thread for this queue item, if available + /// + /// If the backtrace/thread information was collected when this item + /// was enqueued, this call will provide it. + /// + /// @param [in] type + /// The type of extended backtrace being requested, e.g. "libdispatch" + /// or "pthread". + /// + /// @return + /// A thread shared pointer which will have a reference to an extended + /// thread if one was available. + //------------------------------------------------------------------ + lldb::ThreadSP + GetExtendedBacktraceThread (ConstString type); + +protected: + lldb::QueueWP m_queue_wp; + lldb::QueueItemKind m_kind; + lldb_private::Address m_address; + +private: + //------------------------------------------------------------------ + // For QueueItem only + //------------------------------------------------------------------ + + DISALLOW_COPY_AND_ASSIGN (QueueItem); + +}; + +} // namespace lldb_private + +#endif // liblldb_QueueItem_h_ diff --git a/lldb/include/lldb/Target/QueueList.h b/lldb/include/lldb/Target/QueueList.h new file mode 100644 index 00000000000..964c1099233 --- /dev/null +++ b/lldb/include/lldb/Target/QueueList.h @@ -0,0 +1,141 @@ +//===-- QueueList.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_QueueList_h_ +#define liblldb_QueueList_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +#include "lldb/Utility/Iterable.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// QueueList: +// This is the container for libdispatch aka Grand Central Dispatch +// Queue objects. +// +// Each Process will have a QueueList. When the process execution is +// paused, the QueueList may be populated with Queues by the +// SystemRuntime. +//------------------------------------------------------------------ + +class QueueList +{ +friend class Process; + +public: + + QueueList (Process *process); + + ~QueueList (); + + //------------------------------------------------------------------ + /// Get the number of libdispatch queues that are available + /// + /// @return + /// The number of queues that are stored in the QueueList. + //------------------------------------------------------------------ + uint32_t + GetSize(); + + //------------------------------------------------------------------ + /// Get the Queue at a given index number + /// + /// @param [in] idx + /// The index number (0-based) of the queue. + /// @return + /// The Queue at that index number. + //------------------------------------------------------------------ + lldb::QueueSP + GetQueueAtIndex (uint32_t idx); + + typedef std::vector<lldb::QueueSP> collection; + typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter> QueueIterable; + + //------------------------------------------------------------------ + /// Iterate over the list of queues + /// + /// @return + /// An Iterable object which can be used to loop over the queues + /// that exist. + //------------------------------------------------------------------ + QueueIterable + Queues () + { + return QueueIterable(m_queues, m_mutex); + } + + //------------------------------------------------------------------ + /// Clear out the list of queues from the QueueList + //------------------------------------------------------------------ + void + Clear(); + + //------------------------------------------------------------------ + /// Add a Queue to the QueueList + /// + /// @param [in] queue + /// Used by the SystemRuntime to populate the QueueList + //------------------------------------------------------------------ + void + AddQueue (lldb::QueueSP queue); + + //------------------------------------------------------------------ + /// Find a queue in the QueueList by QueueID + /// + /// @param [in] qid + /// The QueueID (same as returned by Thread::GetQueueID()) to find. + /// + /// @return + /// A QueueSP to the queue requested, if it is present in the QueueList. + /// An empty QueueSP willbe returned if this queue was not found. + //------------------------------------------------------------------ + lldb::QueueSP + FindQueueByID (lldb::queue_id_t qid); + + //------------------------------------------------------------------ + /// Find a queue in the QueueList by IndexID + /// + /// @param [in] index_id + /// Find a queue by IndexID. This is an integer associated with each + /// unique queue seen during a debug session and will not be reused + /// for a different queue. Unlike the QueueID, a 64-bit value, this + /// will tend to be an integral value like 1 or 7. + /// + /// @return + /// A QueueSP to the queue requested, if it is present in the QueueList. + /// An empty QueueSP willbe returned if this queue was not found. + //------------------------------------------------------------------ + lldb::QueueSP + FindQueueByIndexID (uint32_t index_id); + + lldb_private::Mutex & + GetMutex (); + +protected: + + //------------------------------------------------------------------ + // Classes that inherit from Process can see and modify these + //------------------------------------------------------------------ + Process *m_process; ///< The process that manages this queue list. + uint32_t m_stop_id; ///< The process stop ID that this queue list is valid for. + collection m_queues; ///< The queues for this process. + Mutex m_mutex; + +private: + QueueList (); +}; + +} // namespace lldb_private + +#endif // liblldb_QueueList_h_ diff --git a/lldb/include/lldb/Target/SystemRuntime.h b/lldb/include/lldb/Target/SystemRuntime.h index 7a0703e6cc3..8dedb11cb66 100644 --- a/lldb/include/lldb/Target/SystemRuntime.h +++ b/lldb/include/lldb/Target/SystemRuntime.h @@ -20,6 +20,7 @@ #include "lldb/Core/ConstString.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Target/QueueList.h" #include "lldb/lldb-private.h" @@ -160,6 +161,23 @@ public: virtual lldb::ThreadSP GetExtendedBacktraceThread (lldb::ThreadSP thread, ConstString type); + //------------------------------------------------------------------ + /// Populate the Process' QueueList with libdispatch / GCD queues that exist. + /// + /// When process execution is paused, the SystemRuntime may be called to fill + /// in the list of Queues that currently exist. + /// + /// @param [out] queue_list + /// This QueueList will be cleared, and any queues that currently exist + /// will be added. An empty QueueList will be returned if no queues + /// exist or if this Systemruntime does not support libdispatch queues. + //------------------------------------------------------------------ + virtual void + PopulateQueueList (lldb_private::QueueList &queue_list) + { + } + + protected: //------------------------------------------------------------------ // Member variables. diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 0b341575be4..c8294960a7b 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -726,6 +726,19 @@ namespace lldb { eFilePermissionsDirectoryDefault = eFilePermissionsUserRWX, } FilePermissions; + //---------------------------------------------------------------------- + // Queue work item types + // + // The different types of work that can be enqueued on a libdispatch + // aka Grand Central Dispatch (GCD) queue. + //---------------------------------------------------------------------- + typedef enum QueueItemKind + { + eQueueItemKindUnknown = 0, + eQueueItemKindFunction, + eQueueItemKindBlock + } QueueItemKind; + } // namespace lldb diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 435960c2b3c..e3d609cf381 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -216,6 +216,8 @@ class TypeFilterImpl; #ifndef LLDB_DISABLE_PYTHON class ScriptedSyntheticChildren; #endif +class Queue; +class QueueItem; class Target; class TargetList; class Thread; @@ -336,6 +338,9 @@ namespace lldb { typedef std::shared_ptr<lldb_private::RegisterCheckpoint> RegisterCheckpointSP; typedef std::shared_ptr<lldb_private::RegisterContext> RegisterContextSP; typedef std::shared_ptr<lldb_private::RegularExpression> RegularExpressionSP; + typedef std::shared_ptr<lldb_private::Queue> QueueSP; + typedef std::weak_ptr<lldb_private::Queue> QueueWP; + typedef std::shared_ptr<lldb_private::QueueItem> QueueItemSP; typedef std::shared_ptr<lldb_private::ScriptInterpreterObject> ScriptInterpreterObjectSP; #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP; diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index f336771729b..4de129549b6 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -608,10 +608,17 @@ AF061F88182C97ED00B6A19C /* RegisterContextHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F86182C97ED00B6A19C /* RegisterContextHistory.h */; }; AF061F8B182C980000B6A19C /* HistoryThread.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F89182C980000B6A19C /* HistoryThread.h */; }; AF061F8C182C980000B6A19C /* HistoryUnwind.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F8A182C980000B6A19C /* HistoryUnwind.h */; }; + AF0C112818580CD800C4C45B /* QueueItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0C112718580CD800C4C45B /* QueueItem.cpp */; }; + AF0EBBE8185940FB0059E52F /* SBQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0EBBE6185940FB0059E52F /* SBQueue.cpp */; }; + AF0EBBE9185940FB0059E52F /* SBQueueItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0EBBE7185940FB0059E52F /* SBQueueItem.cpp */; }; + AF0EBBEC185941360059E52F /* SBQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = AF0EBBEA185941360059E52F /* SBQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AF0EBBED185941360059E52F /* SBQueueItem.h in Headers */ = {isa = PBXBuildFile; fileRef = AF0EBBEB185941360059E52F /* SBQueueItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; AF1729D6182C907200E0AB97 /* HistoryThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1729D4182C907200E0AB97 /* HistoryThread.cpp */; }; AF1729D7182C907200E0AB97 /* HistoryUnwind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1729D5182C907200E0AB97 /* HistoryUnwind.cpp */; }; AF254E31170CCC33007AE5C9 /* PlatformDarwinKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF254E2F170CCC33007AE5C9 /* PlatformDarwinKernel.cpp */; }; AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */ = {isa = PBXBuildFile; fileRef = AF254E30170CCC33007AE5C9 /* PlatformDarwinKernel.h */; }; + AF26703A1852D01E00B6CC36 /* Queue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2670381852D01E00B6CC36 /* Queue.cpp */; }; + AF26703B1852D01E00B6CC36 /* QueueList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2670391852D01E00B6CC36 /* QueueList.cpp */; }; AF37E10A17C861F20061E18E /* ProcessRunLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF37E10917C861F20061E18E /* ProcessRunLock.cpp */; }; AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */; }; AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = AF90106315AB7C5700FF120D /* lldb.1 */; }; @@ -1777,10 +1784,19 @@ AF061F86182C97ED00B6A19C /* RegisterContextHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextHistory.h; path = Utility/RegisterContextHistory.h; sourceTree = "<group>"; }; AF061F89182C980000B6A19C /* HistoryThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryThread.h; path = Utility/HistoryThread.h; sourceTree = "<group>"; }; AF061F8A182C980000B6A19C /* HistoryUnwind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryUnwind.h; path = Utility/HistoryUnwind.h; sourceTree = "<group>"; }; + AF0C112718580CD800C4C45B /* QueueItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QueueItem.cpp; path = source/Target/QueueItem.cpp; sourceTree = "<group>"; }; + AF0EBBE6185940FB0059E52F /* SBQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBQueue.cpp; path = source/API/SBQueue.cpp; sourceTree = "<group>"; }; + AF0EBBE7185940FB0059E52F /* SBQueueItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBQueueItem.cpp; path = source/API/SBQueueItem.cpp; sourceTree = "<group>"; }; + AF0EBBEA185941360059E52F /* SBQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBQueue.h; path = include/lldb/API/SBQueue.h; sourceTree = "<group>"; }; + AF0EBBEB185941360059E52F /* SBQueueItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBQueueItem.h; path = include/lldb/API/SBQueueItem.h; sourceTree = "<group>"; }; + AF0EBBEE1859419F0059E52F /* SBQueue.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBQueue.i; sourceTree = "<group>"; }; + AF0EBBEF1859419F0059E52F /* SBQueueItem.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBQueueItem.i; sourceTree = "<group>"; }; AF1729D4182C907200E0AB97 /* HistoryThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HistoryThread.cpp; path = Utility/HistoryThread.cpp; sourceTree = "<group>"; }; AF1729D5182C907200E0AB97 /* HistoryUnwind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HistoryUnwind.cpp; path = Utility/HistoryUnwind.cpp; sourceTree = "<group>"; }; AF254E2F170CCC33007AE5C9 /* PlatformDarwinKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformDarwinKernel.cpp; sourceTree = "<group>"; }; AF254E30170CCC33007AE5C9 /* PlatformDarwinKernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformDarwinKernel.h; sourceTree = "<group>"; }; + AF2670381852D01E00B6CC36 /* Queue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Queue.cpp; path = source/Target/Queue.cpp; sourceTree = "<group>"; }; + AF2670391852D01E00B6CC36 /* QueueList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QueueList.cpp; path = source/Target/QueueList.cpp; sourceTree = "<group>"; }; AF37E10917C861F20061E18E /* ProcessRunLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessRunLock.cpp; sourceTree = "<group>"; }; AF68D2541255416E002FF25B /* RegisterContextLLDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextLLDB.cpp; path = Utility/RegisterContextLLDB.cpp; sourceTree = "<group>"; }; AF68D2551255416E002FF25B /* RegisterContextLLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextLLDB.h; path = Utility/RegisterContextLLDB.h; sourceTree = "<group>"; }; @@ -2203,6 +2219,8 @@ 263C493B178B61CC0070F12D /* SBModuleSpec.i */, 262F12B8183546C900AEB384 /* SBPlatform.i */, 2611FF07142D83060017FEA3 /* SBProcess.i */, + AF0EBBEE1859419F0059E52F /* SBQueue.i */, + AF0EBBEF1859419F0059E52F /* SBQueueItem.i */, 2611FF08142D83060017FEA3 /* SBSection.i */, 2611FF09142D83060017FEA3 /* SBSourceManager.i */, 2611FF0A142D83060017FEA3 /* SBStream.i */, @@ -2304,6 +2322,10 @@ 263C4937178B50C40070F12D /* SBModuleSpec.cpp */, 262F12B61835469C00AEB384 /* SBPlatform.h */, 262F12B41835468600AEB384 /* SBPlatform.cpp */, + AF0EBBEA185941360059E52F /* SBQueue.h */, + AF0EBBE6185940FB0059E52F /* SBQueue.cpp */, + AF0EBBEB185941360059E52F /* SBQueueItem.h */, + AF0EBBE7185940FB0059E52F /* SBQueueItem.cpp */, 9A9831041125FC5800A56CB0 /* SBProcess.h */, 9A9831031125FC5800A56CB0 /* SBProcess.cpp */, 26B8283C142D01E9002DBC64 /* SBSection.h */, @@ -3160,6 +3182,9 @@ 264A43BD1320BCEB005B4096 /* Platform.cpp */, 26BC7DF310F1B81A00F91463 /* Process.h */, 26BC7F3610F1B90C00F91463 /* Process.cpp */, + AF2670381852D01E00B6CC36 /* Queue.cpp */, + AF2670391852D01E00B6CC36 /* QueueList.cpp */, + AF0C112718580CD800C4C45B /* QueueItem.cpp */, 26AB54111832DC3400EADFF3 /* RegisterCheckpoint.h */, 26BC7DF410F1B81A00F91463 /* RegisterContext.h */, 26BC7F3710F1B90C00F91463 /* RegisterContext.cpp */, @@ -3628,6 +3653,7 @@ 26680220115FD13D008E1FE4 /* SBDebugger.h in Headers */, 490A966B1628C3BF00F0002E /* SBDeclaration.h in Headers */, 26680221115FD13D008E1FE4 /* SBDefines.h in Headers */, + AF0EBBEC185941360059E52F /* SBQueue.h in Headers */, 26680222115FD13D008E1FE4 /* SBError.h in Headers */, 26680223115FD13D008E1FE4 /* SBEvent.h in Headers */, 26680224115FD13D008E1FE4 /* SBFileSpec.h in Headers */, @@ -3639,6 +3665,7 @@ 9AC7038E117674FB0086C050 /* SBInstruction.h in Headers */, 9AC70390117675270086C050 /* SBInstructionList.h in Headers */, 26DE205911618FE700A093E2 /* SBLineEntry.h in Headers */, + AF0EBBED185941360059E52F /* SBQueueItem.h in Headers */, 26680227115FD13D008E1FE4 /* SBListener.h in Headers */, 26DE204F11618E9800A093E2 /* SBModule.h in Headers */, 2668022A115FD13D008E1FE4 /* SBProcess.h in Headers */, @@ -4073,6 +4100,8 @@ 26DE204D11618E7A00A093E2 /* SBModule.cpp in Sources */, 26DE205D1161901400A093E2 /* SBFunction.cpp in Sources */, 26DE205F1161901B00A093E2 /* SBCompileUnit.cpp in Sources */, + AF0EBBE9185940FB0059E52F /* SBQueueItem.cpp in Sources */, + AF0EBBE8185940FB0059E52F /* SBQueue.cpp in Sources */, 26DE20611161902700A093E2 /* SBBlock.cpp in Sources */, 26DE20631161904200A093E2 /* SBLineEntry.cpp in Sources */, 26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */, @@ -4182,6 +4211,7 @@ 2689004513353E0400698AC0 /* ModuleChild.cpp in Sources */, 2689004613353E0400698AC0 /* ModuleList.cpp in Sources */, 2689004713353E0400698AC0 /* PluginManager.cpp in Sources */, + AF0C112818580CD800C4C45B /* QueueItem.cpp in Sources */, AF254E31170CCC33007AE5C9 /* PlatformDarwinKernel.cpp in Sources */, 2689004813353E0400698AC0 /* RegularExpression.cpp in Sources */, 2689004913353E0400698AC0 /* Scalar.cpp in Sources */, @@ -4313,6 +4343,7 @@ 268900DB13353E6F00698AC0 /* LineTable.cpp in Sources */, 268900DC13353E6F00698AC0 /* ObjectFile.cpp in Sources */, 268900DD13353E6F00698AC0 /* Symbol.cpp in Sources */, + AF26703A1852D01E00B6CC36 /* Queue.cpp in Sources */, 268900DE13353E6F00698AC0 /* SymbolContext.cpp in Sources */, 268900DF13353E6F00698AC0 /* SymbolFile.cpp in Sources */, 268900E013353E6F00698AC0 /* SymbolVendor.cpp in Sources */, @@ -4389,6 +4420,7 @@ 264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */, 26ECA04313665FED008D1F18 /* ARM_DWARF_Registers.cpp in Sources */, AF061F87182C97ED00B6A19C /* RegisterContextHistory.cpp in Sources */, + AF26703B1852D01E00B6CC36 /* QueueList.cpp in Sources */, 267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */, 26BCFC521368AE38006DC050 /* OptionGroupFormat.cpp in Sources */, AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */, diff --git a/lldb/scripts/Python/build-swig-Python.sh b/lldb/scripts/Python/build-swig-Python.sh index 5cbb9644ca0..c424c06f0ae 100755 --- a/lldb/scripts/Python/build-swig-Python.sh +++ b/lldb/scripts/Python/build-swig-Python.sh @@ -107,6 +107,8 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/lldb.h"\ " ${SRC_ROOT}/include/lldb/API/SBModule.h"\ " ${SRC_ROOT}/include/lldb/API/SBModuleSpec.h"\ " ${SRC_ROOT}/include/lldb/API/SBProcess.h"\ +" ${SRC_ROOT}/include/lldb/API/SBQueue.h"\ +" ${SRC_ROOT}/include/lldb/API/SBQueueItem.h"\ " ${SRC_ROOT}/include/lldb/API/SBSourceManager.h"\ " ${SRC_ROOT}/include/lldb/API/SBStream.h"\ " ${SRC_ROOT}/include/lldb/API/SBStringList.h"\ @@ -154,6 +156,8 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBModuleSpec.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBPlatform.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBProcess.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBQueue.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBQueueItem.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBSourceManager.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBStream.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBStringList.i"\ diff --git a/lldb/scripts/Python/interface/SBProcess.i b/lldb/scripts/Python/interface/SBProcess.i index 9798f9aa4a4..7abbf919af2 100644 --- a/lldb/scripts/Python/interface/SBProcess.i +++ b/lldb/scripts/Python/interface/SBProcess.i @@ -180,6 +180,15 @@ public: SetSelectedThreadByIndexID (uint32_t index_id); //------------------------------------------------------------------ + // Queue related functions + //------------------------------------------------------------------ + uint32_t + GetNumQueues (); + + lldb::SBQueue + GetQueueAtIndex (uint32_t index); + + //------------------------------------------------------------------ // Stepping related functions //------------------------------------------------------------------ diff --git a/lldb/scripts/Python/interface/SBQueue.i b/lldb/scripts/Python/interface/SBQueue.i new file mode 100644 index 00000000000..09dbc190a6d --- /dev/null +++ b/lldb/scripts/Python/interface/SBQueue.i @@ -0,0 +1,54 @@ +//===-- SWIG Interface for SBQueue.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class SBQueue +{ +public: + SBQueue (); + + SBQueue (const lldb::QueueSP& queue_sp); + + ~SBQueue(); + + bool + IsValid() const; + + void + Clear (); + + lldb::SBProcess + GetProcess (); + + lldb::queue_id_t + GetQueueID () const; + + const char * + GetName () const; + + uint32_t + GetIndexID () const; + + uint32_t + GetNumThreads (); + + lldb::SBThread + GetThreadAtIndex (uint32_t); + + uint32_t + GetNumItems (); + + lldb::SBQueueItem + GetItemAtIndex (uint32_t); + +}; + +} // namespace lldb + diff --git a/lldb/scripts/Python/interface/SBQueueItem.i b/lldb/scripts/Python/interface/SBQueueItem.i new file mode 100644 index 00000000000..ffa24150b67 --- /dev/null +++ b/lldb/scripts/Python/interface/SBQueueItem.i @@ -0,0 +1,46 @@ +//===-- SWIG Interface for SBQueueItem.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class SBQueueItem +{ +public: + SBQueueItem (); + + SBQueueItem (const lldb::QueueItemSP& queue_item_sp); + + ~SBQueueItem(); + + bool + IsValid() const; + + void + Clear (); + + lldb::QueueItemKind + GetKind () const; + + void + SetKind (lldb::QueueItemKind kind); + + lldb::SBAddress + GetAddress () const; + + void + SetAddress (lldb::SBAddress addr); + + void + SetQueueItem (const lldb::QueueItemSP& queue_item_sp); + + lldb::SBThread + GetExtendedBacktraceThread (const char *type); +}; + +} // namespace lldb diff --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig index acf8492bcee..d53ba8b1878 100644 --- a/lldb/scripts/lldb.swig +++ b/lldb/scripts/lldb.swig @@ -81,6 +81,8 @@ import os #include "lldb/API/SBModuleSpec.h" #include "lldb/API/SBPlatform.h" #include "lldb/API/SBProcess.h" +#include "lldb/API/SBQueue.h" +#include "lldb/API/SBQueueItem.h" #include "lldb/API/SBSection.h" #include "lldb/API/SBSourceManager.h" #include "lldb/API/SBStream.h" @@ -146,6 +148,8 @@ import os %include "./Python/interface/SBModuleSpec.i" %include "./Python/interface/SBPlatform.i" %include "./Python/interface/SBProcess.i" +%include "./Python/interface/SBQueue.i" +%include "./Python/interface/SBQueueItem.i" %include "./Python/interface/SBSection.i" %include "./Python/interface/SBSourceManager.i" %include "./Python/interface/SBStream.i" diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index ac7a484978f..560167e2853 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -30,6 +30,8 @@ add_lldb_library(lldbAPI SBModuleSpec.cpp SBPlatform.cpp SBProcess.cpp + SBQueue.cpp + SBQueueItem.cpp SBSection.cpp SBSourceManager.cpp SBStream.cpp diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index 557006f2434..235388b5f25 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -535,6 +535,53 @@ SBProcess::GetThreadAtIndex (size_t index) } uint32_t +SBProcess::GetNumQueues () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num_queues = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + num_queues = process_sp->GetQueueList().GetSize(); + } + + if (log) + log->Printf ("SBProcess(%p)::GetNumQueues () => %d", process_sp.get(), num_queues); + + return num_queues; +} + +SBQueue +SBProcess::GetQueueAtIndex (size_t index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBQueue sb_queue; + QueueSP queue_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index); + sb_queue.SetQueue (queue_sp); + } + + if (log) + { + log->Printf ("SBProcess(%p)::GetQueueAtIndex (index=%d) => SBQueue(%p)", + process_sp.get(), (uint32_t) index, queue_sp.get()); + } + + return sb_queue; +} + + +uint32_t SBProcess::GetStopID(bool include_expression_stops) { ProcessSP process_sp(GetSP()); diff --git a/lldb/source/API/SBQueue.cpp b/lldb/source/API/SBQueue.cpp new file mode 100644 index 00000000000..58e3fcc495f --- /dev/null +++ b/lldb/source/API/SBQueue.cpp @@ -0,0 +1,256 @@ +//===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +#include "lldb/API/SBQueue.h" + +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBThread.h" +#include "lldb/Core/Log.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueItem.h" +#include "lldb/Target/Thread.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// Constructors +//---------------------------------------------------------------------- +SBQueue::SBQueue () : + m_queue_wp(), + m_threads(), + m_thread_list_fetched(false), + m_items(), + m_queue_items_fetched(false) +{ +} + +SBQueue::SBQueue (const QueueSP& queue_sp) : + m_queue_wp(queue_sp), + m_threads(), + m_thread_list_fetched(false), + m_items(), + m_queue_items_fetched(false) +{ +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBQueue::~SBQueue() +{ + m_threads.clear(); + m_items.clear(); +} + +bool +SBQueue::IsValid() const +{ + QueueSP queue_sp = m_queue_wp.lock(); + return queue_sp.get() != NULL; +} + + +void +SBQueue::Clear () +{ + m_queue_wp.reset(); + m_thread_list_fetched = false; + m_threads.clear(); + m_queue_items_fetched = false; + m_items.clear(); +} + + +void +SBQueue::SetQueue (const QueueSP& queue_sp) +{ + m_queue_wp = queue_sp; + m_thread_list_fetched = false; + m_threads.clear(); + m_queue_items_fetched = false; + m_items.clear(); +} + +lldb::queue_id_t +SBQueue::GetQueueID () const +{ + queue_id_t result = LLDB_INVALID_QUEUE_ID; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result = queue_sp->GetID(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64, this, result); + return result; +} + +uint32_t +SBQueue::GetIndexID () const +{ + uint32_t result = LLDB_INVALID_INDEX32; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result = queue_sp->GetIndexID(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueue(%p)::GetIndexID () => %d", this, result); + return result; +} + +const char * +SBQueue::GetName () const +{ + const char *name = NULL; + QueueSP queue_sp = m_queue_wp.lock (); + if (queue_sp.get()) + { + name = queue_sp->GetName(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueue(%p)::GetName () => %s", this, name ? name : "NULL"); + + return name; +} + +void +SBQueue::FetchThreads () +{ + if (m_thread_list_fetched == false) + { + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock())) + { + const std::vector<ThreadSP> thread_list(queue_sp->GetThreads()); + m_thread_list_fetched = true; + const uint32_t num_threads = thread_list.size(); + for (uint32_t idx = 0; idx < num_threads; ++idx) + { + ThreadSP thread_sp = thread_list[idx]; + if (thread_sp && thread_sp->IsValid()) + { + m_threads.push_back (thread_sp); + } + } + } + } + } +} + +void +SBQueue::FetchItems () +{ + if (m_queue_items_fetched == false) + { + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock())) + { + const std::vector<QueueItemSP> queue_items(queue_sp->GetItems()); + m_queue_items_fetched = true; + const uint32_t num_items = queue_items.size(); + for (uint32_t idx = 0; idx < num_items; ++idx) + { + QueueItemSP item = queue_items[idx]; + if (item && item->IsValid()) + { + m_items.push_back (item); + } + } + } + } + } +} + +uint32_t +SBQueue::GetNumThreads () +{ + uint32_t result = 0; + + FetchThreads(); + if (m_thread_list_fetched) + { + result = m_threads.size(); + } + return result; +} + +SBThread +SBQueue::GetThreadAtIndex (uint32_t idx) +{ + FetchThreads(); + + SBThread sb_thread; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp && idx < m_threads.size()) + { + ProcessSP process_sp = queue_sp->GetProcess(); + if (process_sp) + { + ThreadSP thread_sp = m_threads[idx].lock(); + if (thread_sp) + { + sb_thread.SetThread (thread_sp); + } + } + } + return sb_thread; +} + + +uint32_t +SBQueue::GetNumItems () +{ + uint32_t result = 0; + FetchItems(); + + if (m_queue_items_fetched) + { + result = m_items.size(); + } + return result; +} + +SBQueueItem +SBQueue::GetItemAtIndex (uint32_t idx) +{ + SBQueueItem result; + FetchItems(); + if (m_queue_items_fetched && idx < m_items.size()) + { + result.SetQueueItem (m_items[idx]); + } + return result; +} + +SBProcess +SBQueue::GetProcess () +{ + SBProcess result; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result.SetSP (queue_sp->GetProcess()); + } + return result; +} diff --git a/lldb/source/API/SBQueueItem.cpp b/lldb/source/API/SBQueueItem.cpp new file mode 100644 index 00000000000..b68c40b3e02 --- /dev/null +++ b/lldb/source/API/SBQueueItem.cpp @@ -0,0 +1,119 @@ +//===-- SBQueueItem.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" +#include "lldb/lldb-forward.h" + +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBQueueItem.h" +#include "lldb/API/SBThread.h" +#include "lldb/Core/Address.h" +#include "lldb/Target/QueueItem.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// Constructors +//---------------------------------------------------------------------- +SBQueueItem::SBQueueItem () : + m_queue_item_sp() +{ +} + +SBQueueItem::SBQueueItem (const QueueItemSP& queue_item_sp) : + m_queue_item_sp (queue_item_sp) +{ +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBQueueItem::~SBQueueItem() +{ + m_queue_item_sp.reset(); +} + +bool +SBQueueItem::IsValid() const +{ + return m_queue_item_sp.get() != NULL; +} + + +void +SBQueueItem::Clear () +{ + m_queue_item_sp.reset(); +} + + +void +SBQueueItem::SetQueueItem (const QueueItemSP& queue_item_sp) +{ + m_queue_item_sp = queue_item_sp; +} + + +lldb::QueueItemKind +SBQueueItem::GetKind () const +{ + QueueItemKind result = eQueueItemKindUnknown; + if (m_queue_item_sp) + { + result = m_queue_item_sp->GetKind (); + } + return result; +} + +void +SBQueueItem::SetKind (lldb::QueueItemKind kind) +{ + if (m_queue_item_sp) + { + m_queue_item_sp->SetKind (kind); + } +} + +SBAddress +SBQueueItem::GetAddress () const +{ + SBAddress result; + if (m_queue_item_sp) + { + result.SetAddress (&m_queue_item_sp->GetAddress()); + } + return result; +} + +void +SBQueueItem::SetAddress (SBAddress addr) +{ + if (m_queue_item_sp) + { + m_queue_item_sp->SetAddress (addr.ref()); + } +} + +SBThread +SBQueueItem::GetExtendedBacktraceThread (const char *type) +{ + SBThread result; + if (m_queue_item_sp) + { + ThreadSP thread_sp; + ConstString type_const (type); + thread_sp = m_queue_item_sp->GetExtendedBacktraceThread (type_const); + if (thread_sp) + { + result.SetThread (thread_sp); + } + } + return result; +} diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp index 388264a2d95..5756e7071d7 100644 --- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp +++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp @@ -22,10 +22,11 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "Plugins/Process/Utility/HistoryThread.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueList.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" - #include "SystemRuntimeMacOSX.h" using namespace lldb; @@ -443,6 +444,26 @@ SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP original_thread_sp, Co return new_extended_thread_sp; } +void +SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list) +{ + // For now, iterate over the threads and see what queue each thread is associated with. + // If we haven't already added this queue, add it to the QueueList. + // (a single libdispatch queue may be using multiple threads simultaneously.) + + for (ThreadSP thread_sp : m_process->Threads()) + { + if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID) + { + if (queue_list.FindQueueByID (thread_sp->GetQueueID()).get() == NULL) + { + QueueSP queue_sp (new Queue(m_process->shared_from_this(), thread_sp->GetQueueID(), thread_sp->GetQueueName())); + queue_list.AddQueue (queue_sp); + } + } + } +} + void SystemRuntimeMacOSX::Initialize() diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h index c472bee8572..4c684fee7b2 100644 --- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h +++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h @@ -104,6 +104,9 @@ private: SystemRuntimeMacOSX::ArchivedBacktrace GetLibdispatchExtendedBacktrace (lldb::ThreadSP thread); + void + PopulateQueueList (lldb_private::QueueList &queue_list); + protected: lldb::user_id_t m_break_id; mutable lldb_private::Mutex m_mutex; diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt index 1ba01ea1dc7..fb7badbae26 100644 --- a/lldb/source/Target/CMakeLists.txt +++ b/lldb/source/Target/CMakeLists.txt @@ -13,6 +13,9 @@ add_lldb_library(lldbTarget PathMappingList.cpp Platform.cpp Process.cpp + Queue.cpp + QueueItem.cpp + QueueList.cpp RegisterContext.cpp SectionLoadHistory.cpp SectionLoadList.cpp diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 1de322aee14..81e12a3b2f7 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1017,7 +1017,9 @@ Process::Process(Target &target, Listener &listener) : m_mod_id (), m_process_unique_id(0), m_thread_index_id (0), + m_queue_index_id (0), m_thread_id_to_index_id_map (), + m_queue_id_to_index_id_map (), m_exit_status (-1), m_exit_string (), m_thread_mutex (Mutex::eMutexTypeRecursive), @@ -1025,6 +1027,8 @@ Process::Process(Target &target, Listener &listener) : m_thread_list (this), m_extended_thread_list (this), m_extended_thread_stop_id (0), + m_queue_list (this), + m_queue_list_stop_id (0), m_notifications (), m_image_tokens (), m_listener (listener), @@ -1151,6 +1155,8 @@ Process::Finalize() m_thread_list_real.Destroy(); m_thread_list.Destroy(); m_extended_thread_list.Destroy(); + m_queue_list.Clear(); + m_queue_list_stop_id = 0; std::vector<Notifications> empty_notifications; m_notifications.swap(empty_notifications); m_image_tokens.clear(); @@ -1600,12 +1606,32 @@ Process::UpdateThreadListIfNeeded () // Clear any extended threads that we may have accumulated previously m_extended_thread_list.Clear(); m_extended_thread_stop_id = GetLastNaturalStopID (); + + m_queue_list.Clear(); + m_queue_list_stop_id = GetLastNaturalStopID (); } } } } } +void +Process::UpdateQueueListIfNeeded () +{ + if (m_system_runtime_ap.get()) + { + if (m_queue_list.GetSize() == 0 || m_queue_list_stop_id != GetLastNaturalStopID()) + { + const StateType state = GetPrivateState(); + if (StateIsStoppedState (state, true)) + { + m_system_runtime_ap->PopulateQueueList (m_queue_list); + m_queue_list_stop_id = GetLastNaturalStopID(); + } + } + } +} + ThreadSP Process::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context) { @@ -1653,6 +1679,39 @@ Process::AssignIndexIDToThread(uint64_t thread_id) return result; } +bool +Process::HasAssignedIndexIDToQueue(queue_id_t queue_id) +{ + std::map<uint64_t, uint32_t>::iterator iterator = m_queue_id_to_index_id_map.find(queue_id); + if (iterator == m_queue_id_to_index_id_map.end()) + { + return false; + } + else + { + return true; + } +} + +uint32_t +Process::AssignIndexIDToQueue(queue_id_t queue_id) +{ + uint32_t result = 0; + std::map<uint64_t, uint32_t>::iterator iterator = m_queue_id_to_index_id_map.find(queue_id); + if (iterator == m_queue_id_to_index_id_map.end()) + { + result = ++m_queue_index_id; + m_queue_id_to_index_id_map[queue_id] = result; + } + else + { + result = iterator->second; + } + + return result; +} + + StateType Process::GetState() { @@ -5680,6 +5739,10 @@ void Process::Flush () { m_thread_list.Flush(); + m_extended_thread_list.Flush(); + m_extended_thread_stop_id = 0; + m_queue_list.Clear(); + m_queue_list_stop_id = 0; } void diff --git a/lldb/source/Target/Queue.cpp b/lldb/source/Target/Queue.cpp new file mode 100644 index 00000000000..27f01975e47 --- /dev/null +++ b/lldb/source/Target/Queue.cpp @@ -0,0 +1,68 @@ +//===-- Queue.cpp -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueList.h" +#include "lldb/Target/Thread.h" + +using namespace lldb; +using namespace lldb_private; + +Queue::Queue (ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue_name) : + m_process_wp (process_sp), + m_queue_id (queue_id), + m_queue_name (queue_name), + m_enqueued_items() +{ + m_index_id = process_sp->AssignIndexIDToQueue (queue_id); +} + +Queue::~Queue () +{ +} + +queue_id_t +Queue::GetID () +{ + return m_queue_id; +} + +const char * +Queue::GetName () +{ + const char *result = NULL; + if (m_queue_name.size() > 0) + result = m_queue_name.c_str(); + return result; +} + +uint32_t +Queue::GetIndexID () +{ + return m_index_id; +} + +std::vector<lldb::ThreadSP> +Queue::GetThreads () +{ + std::vector<ThreadSP> result; + ProcessSP process_sp = m_process_wp.lock(); + if (process_sp.get ()) + { + for (ThreadSP thread_sp : process_sp->Threads()) + { + if (thread_sp->GetQueueID() == m_queue_id) + { + result.push_back (thread_sp); + } + } + } + return result; +} diff --git a/lldb/source/Target/QueueItem.cpp b/lldb/source/Target/QueueItem.cpp new file mode 100644 index 00000000000..3b8d3a5d9c2 --- /dev/null +++ b/lldb/source/Target/QueueItem.cpp @@ -0,0 +1,55 @@ +//===-- QueueItem.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueItem.h" + +using namespace lldb; +using namespace lldb_private; + +QueueItem::QueueItem (QueueSP queue_sp) : + m_queue_wp (queue_sp), + m_kind (eQueueItemKindUnknown), + m_address () +{ +} + +QueueItem::~QueueItem () +{ +} + +QueueItemKind +QueueItem::GetKind() const +{ + return m_kind; +} + +void +QueueItem::SetKind (QueueItemKind item_kind) +{ + m_kind = item_kind; +} + +Address & +QueueItem::GetAddress () +{ + return m_address; +} + +void +QueueItem::SetAddress (Address addr) +{ + m_address = addr; +} + +ThreadSP +QueueItem::GetExtendedBacktraceThread (ConstString type) +{ + return ThreadSP(); +} diff --git a/lldb/source/Target/QueueList.cpp b/lldb/source/Target/QueueList.cpp new file mode 100644 index 00000000000..6134f5cc0b2 --- /dev/null +++ b/lldb/source/Target/QueueList.cpp @@ -0,0 +1,102 @@ +//===-- QueueList.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueList.h" + +using namespace lldb; +using namespace lldb_private; + +QueueList::QueueList (Process *process) : + m_process (process), + m_stop_id (0), + m_queues (), + m_mutex () +{ +} + +QueueList::~QueueList () +{ + Clear(); +} + +uint32_t +QueueList::GetSize () +{ + Mutex::Locker locker (m_mutex); + return m_queues.size(); +} + +lldb::QueueSP +QueueList::GetQueueAtIndex (uint32_t idx) +{ + Mutex::Locker locker (m_mutex); + if (idx < m_queues.size()) + { + return m_queues[idx]; + } + else + { + return QueueSP(); + } +} + +void +QueueList::Clear () +{ + Mutex::Locker locker (m_mutex); + m_queues.clear(); +} + +void +QueueList::AddQueue (QueueSP queue_sp) +{ + Mutex::Locker locker (m_mutex); + if (queue_sp.get ()) + { + m_queues.push_back (queue_sp); + } +} + +lldb::QueueSP +QueueList::FindQueueByID (lldb::queue_id_t qid) +{ + QueueSP ret; + for (QueueSP queue_sp : Queues()) + { + if (queue_sp->GetID() == qid) + { + ret = queue_sp; + break; + } + } + return ret; +} + +lldb::QueueSP +QueueList::FindQueueByIndexID (uint32_t index_id) +{ + QueueSP ret; + for (QueueSP queue_sp : Queues()) + { + if (queue_sp->GetIndexID() == index_id) + { + ret = queue_sp; + break; + } + } + return ret; +} + +lldb_private::Mutex & +QueueList::GetMutex () +{ + return m_mutex; +} |