[Lldb-commits] [lldb] r200822 - Change the Mac OS X SystemRuntime plugin from using the placeholder

Jason Molenda jmolenda at apple.com
Tue Feb 4 21:44:55 PST 2014


Author: jmolenda
Date: Tue Feb  4 23:44:54 2014
New Revision: 200822

URL: http://llvm.org/viewvc/llvm-project?rev=200822&view=rev
Log:
Change the Mac OS X SystemRuntime plugin from using the placeholder
libldi library to collect extended backtrace information; switch
to the libBacktraceRecording library and its APIs.  Complete the
work of adding QueueItems to Queues and allow for the QueueItems
to be interrogated about their extended backtraces in turn.

There's still cleanup and documentation to do on this code but the
code is functional and I it's a good time to get the work-in-progress 
checked in.  
<rdar://problem/15314027> 

Added:
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
Modified:
    lldb/trunk/include/lldb/API/SBQueue.h
    lldb/trunk/include/lldb/API/SBQueueItem.h
    lldb/trunk/include/lldb/Expression/ClangFunction.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/Target/Queue.h
    lldb/trunk/include/lldb/Target/QueueItem.h
    lldb/trunk/include/lldb/Target/SystemRuntime.h
    lldb/trunk/include/lldb/lldb-private-log.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/scripts/Python/interface/SBQueue.i
    lldb/trunk/scripts/Python/interface/SBThread.i
    lldb/trunk/source/API/SBQueue.cpp
    lldb/trunk/source/API/SBQueueItem.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
    lldb/trunk/source/Plugins/Process/Utility/HistoryThread.cpp
    lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/Queue.cpp
    lldb/trunk/source/Target/QueueItem.cpp
    lldb/trunk/source/Target/SystemRuntime.cpp
    lldb/trunk/source/lldb-log.cpp

Modified: lldb/trunk/include/lldb/API/SBQueue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBQueue.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBQueue.h (original)
+++ lldb/trunk/include/lldb/API/SBQueue.h Tue Feb  4 23:44:54 2014
@@ -57,10 +57,10 @@ public:
     GetThreadAtIndex (uint32_t);
 
     uint32_t
-    GetNumItems ();
+    GetNumPendingItems ();
 
     lldb::SBQueueItem
-    GetItemAtIndex (uint32_t);
+    GetPendingItemAtIndex (uint32_t);
 
 protected:
     friend class SBProcess;

Modified: lldb/trunk/include/lldb/API/SBQueueItem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBQueueItem.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBQueueItem.h (original)
+++ lldb/trunk/include/lldb/API/SBQueueItem.h Tue Feb  4 23:44:54 2014
@@ -12,6 +12,7 @@
 
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBAddress.h"
+#include "lldb/API/SBThread.h"
 
 namespace lldb {
 

Modified: lldb/trunk/include/lldb/Expression/ClangFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangFunction.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangFunction.h Tue Feb  4 23:44:54 2014
@@ -300,7 +300,7 @@ public:
     /// @param[in] args_addr
     ///     The address of the argument struct.
     ///
-    /// @param[in] ret_value
+    /// @param[out] ret_value
     ///     The value returned by the function.
     ///
     /// @return

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Feb  4 23:44:54 2014
@@ -3369,15 +3369,6 @@ 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
     //------------------------------------------------------------------
@@ -3759,9 +3750,7 @@ 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;

Modified: lldb/trunk/include/lldb/Target/Queue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Queue.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Queue.h (original)
+++ lldb/trunk/include/lldb/Target/Queue.h Tue Feb  4 23:44:54 2014
@@ -16,6 +16,7 @@
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-private.h"
+#include "lldb/Target/QueueItem.h"
 
 
 namespace lldb_private {
@@ -47,9 +48,10 @@ public:
     /// 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.
+    /// stop_id.  Currently the libdispatch serialnum is used for the QueueID;
+    /// it is a number that starts at 1 for each process and increments with 
+    /// each queue.  A serialnum is not reused for a different queue in the
+    /// lifetime of that process execution.
     ///
     /// @return
     ///     The QueueID for this Queue.
@@ -70,13 +72,13 @@ public:
     //------------------------------------------------------------------
     /// 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.
+    /// This is currently the same as GetID().  If it changes in the future,
+    /// it will be  a small integer value (starting with 1) assigned to
+    /// each queue that is seen during a Process lifetime.  
+    /// 
+    /// Both the GetID and GetIndexID are being retained for Queues to
+    /// maintain similar API to the Thread class, and allow for the 
+    /// possibility of GetID changing to a different source in the future.
     ///
     /// @return
     ///     The IndexID for this queue.
@@ -108,10 +110,7 @@ public:
     ///     The vector of enqueued items for this queue
     //------------------------------------------------------------------
     const std::vector<lldb::QueueItemSP> &
-    GetItems() const
-    {
-        return m_enqueued_items;
-    }
+    GetPendingItems();
 
     lldb::ProcessSP
     GetProcess() const
@@ -119,20 +118,70 @@ public:
         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;
+    //------------------------------------------------------------------
+    /// Get the number of work items that this queue is currently running
+    ///
+    /// @return
+    ///     The number of work items currently executing.  For a serial 
+    ///     queue, this will be 0 or 1.  For a concurrent queue, this 
+    ///     may be any number.
+    //------------------------------------------------------------------
+    uint32_t
+    GetNumRunningWorkItems () const;
+
+    //------------------------------------------------------------------
+    /// Get the number of work items enqueued on this queue
+    ///
+    /// @return
+    ///     The number of work items currently enqueued, waiting to
+    ///     execute.
+    //------------------------------------------------------------------
+    uint32_t
+    GetNumPendingWorkItems () const;
+
+    //------------------------------------------------------------------
+    /// Get the dispatch_queue_t structure address for this Queue
+    ///
+    /// Get the address in the inferior process' memory of this Queue's
+    /// dispatch_queue_t structure.
+    ///
+    /// @return
+    ///     The address of the dispatch_queue_t structure, if known.
+    ///     LLDB_INVALID_ADDRESS will be returned if it is unavailable.
+    //------------------------------------------------------------------
+    lldb::addr_t
+    GetLibdispatchQueueAddress () const;
+
+
+    void
+    SetNumRunningWorkItems (uint32_t count);
+
+    void
+    SetNumPendingWorkItems (uint32_t count);
+
+    void
+    SetLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t_addr);
+
+    void
+    PushPendingQueueItem (lldb::QueueItemSP item)
+    {
+        m_pending_items.push_back (item);
+    }
 
 private:
     //------------------------------------------------------------------
     // For Queue only
     //------------------------------------------------------------------
 
-    DISALLOW_COPY_AND_ASSIGN (Queue);
+    lldb::ProcessWP                 m_process_wp;
+    lldb::queue_id_t                m_queue_id;
+    std::string                     m_queue_name;
+    uint32_t                        m_running_work_items_count;
+    uint32_t                        m_pending_work_items_count;
+    std::vector<lldb::QueueItemSP>  m_pending_items;
+    lldb::addr_t                    m_dispatch_queue_t_addr;  // address of libdispatch dispatch_queue_t for this Queue
 
+    DISALLOW_COPY_AND_ASSIGN (Queue);
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Target/QueueItem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/QueueItem.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/QueueItem.h (original)
+++ lldb/trunk/include/lldb/Target/QueueItem.h Tue Feb  4 23:44:54 2014
@@ -10,6 +10,8 @@
 #ifndef liblldb_QueueItem_h_
 #define liblldb_QueueItem_h_
 
+#include <vector>
+
 #include "lldb/lldb-private.h"
 #include "lldb/lldb-enumerations.h"
 
@@ -30,7 +32,8 @@ namespace lldb_private {
 //------------------------------------------------------------------
 
 
-class QueueItem
+class QueueItem :
+    public std::enable_shared_from_this<QueueItem>
 {
 public:
 
@@ -114,11 +117,119 @@ public:
     lldb::ThreadSP
     GetExtendedBacktraceThread (ConstString type);
 
+    void
+    SetItemThatEnqueuedThis (lldb::addr_t address_of_item)
+    {
+        m_item_that_enqueued_this_ref = address_of_item;
+    }
+
+    lldb::addr_t
+    GetItemThatEnqueuedThis ()
+    {
+        return m_item_that_enqueued_this_ref;
+    }
+
+    void
+    SetEnqueueingThreadID (lldb::tid_t tid)
+    {
+        m_enqueueing_thread_id = tid;
+    }
+
+    lldb::tid_t
+    GetEnqueueingThreadID ()
+    {
+        return m_enqueueing_thread_id;
+    }
+
+    void
+    SetEnqueueingQueueID (lldb::queue_id_t qid)
+    {
+        m_enqueueing_queue_id = qid;
+    }
+
+    lldb::queue_id_t
+    GetEnqueueingQueueID ()
+    {
+        return m_enqueueing_queue_id;
+    }
+
+    void
+    SetTargetQueueID (lldb::queue_id_t qid)
+    {
+        m_target_queue_id = qid;
+    }
+
+    void
+    SetStopID (uint32_t stop_id)
+    {
+        m_stop_id = stop_id;
+    }
+
+    uint32_t
+    GetStopID ()
+    {
+        return m_stop_id;
+    }
+
+    void
+    SetEnqueueingBacktrace (std::vector<lldb::addr_t> backtrace)
+    {
+        m_backtrace = backtrace;
+    }
+
+    std::vector<lldb::addr_t> &
+    GetEnqueueingBacktrace ()
+    {
+        return m_backtrace;
+    }
+
+    void
+    SetThreadLabel (std::string thread_name)
+    {
+        m_thread_label = thread_name;
+    }
+
+    std::string
+    GetThreadLabel ()
+    {
+        return m_thread_label;
+    }
+
+    void
+    SetQueueLabel (std::string queue_name)
+    {
+        m_queue_label = queue_name;
+    }
+
+    std::string
+    GetQueueLabel ()
+    {
+        return m_queue_label;
+    }
+
+    void
+    SetTargetQueueLabel (std::string queue_name)
+    {
+        m_target_queue_label = queue_name;
+    }
+
 protected:
     lldb::QueueWP           m_queue_wp;
     lldb::QueueItemKind     m_kind;
     lldb_private::Address   m_address;
 
+    lldb::addr_t            m_item_that_enqueued_this_ref;  // a handle that we can pass into libBacktraceRecording
+                                                            // to get the QueueItem that enqueued this item
+    lldb::tid_t             m_enqueueing_thread_id;    // thread that enqueued this item
+    lldb::queue_id_t        m_enqueueing_queue_id;     // Queue that enqueued this item, if it was a queue
+    lldb::queue_id_t        m_target_queue_id;
+    uint32_t                m_stop_id;                 // indicates when this backtrace was recorded in time
+    std::vector<lldb::addr_t>    m_backtrace;
+    std::string             m_thread_label;
+    std::string             m_queue_label;
+    std::string             m_target_queue_label;
+
+
 private:
     //------------------------------------------------------------------
     // For QueueItem only

Modified: lldb/trunk/include/lldb/Target/SystemRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/SystemRuntime.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/SystemRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/SystemRuntime.h Tue Feb  4 23:44:54 2014
@@ -21,9 +21,9 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Target/QueueList.h"
+#include "lldb/Target/QueueItem.h"
 #include "lldb/lldb-private.h"
 
-
 namespace lldb_private {
 
 //----------------------------------------------------------------------
@@ -104,6 +104,14 @@ public:
     virtual void
     ModulesDidLoad(lldb_private::ModuleList &module_list);
 
+    //------------------------------------------------------------------
+    /// Called before detaching from a process.
+    ///
+    /// This will give a SystemRuntime plugin a chance to free any resources
+    /// in the inferior process before we detach.
+    //------------------------------------------------------------------
+    virtual void
+    Detach ();
 
     //------------------------------------------------------------------
     /// Return a list of thread origin extended backtraces that may 
@@ -162,6 +170,33 @@ public:
     GetExtendedBacktraceThread (lldb::ThreadSP thread, ConstString type);
 
     //------------------------------------------------------------------
+    /// Get the extended backtrace thread for a QueueItem
+    ///
+    /// A QueueItem represents a function/block that will be executed on
+    /// a libdispatch queue in the future, or it represents a function/block
+    /// that is currently executing on a thread.
+    ///
+    /// This method will report a thread backtrace of the function that 
+    /// enqueued it originally, if possible.
+    ///
+    /// @param [in] queue_item_sp
+    ///     The QueueItem that we are getting an extended backtrace for.
+    ///
+    /// @param [in] type
+    ///     The type of extended backtrace to fetch.  The types supported
+    ///     are returned from SystemRuntime::GetExtendedBacktraceTypes.
+    ///
+    /// @return
+    ///     If an extended backtrace is available, it is returned.  Else
+    ///     an empty ThreadSP is returned.
+    //------------------------------------------------------------------
+    virtual lldb::ThreadSP
+    GetExtendedBacktraceForQueueItem (lldb::QueueItemSP queue_item_sp, ConstString type)
+    {
+        return lldb::ThreadSP();
+    }
+
+    //------------------------------------------------------------------
     /// Populate the Process' QueueList with libdispatch / GCD queues that exist.
     ///
     /// When process execution is paused, the SystemRuntime may be called to fill
@@ -177,6 +212,63 @@ public:
     {
     }
 
+    //------------------------------------------------------------------
+    /// Get the queue name for a thread given a thread's dispatch_qaddr.
+    ///
+    /// On systems using libdispatch queues, a thread may be associated with a queue.
+    /// There will be a call to get the thread's dispatch_qaddr.  At the dispatch_qaddr
+    /// we will find the address of this thread's dispatch_queue_t structure.
+    /// Given the address of the dispatch_queue_t structure for a thread,
+    /// get the queue name and return it.
+    ///
+    /// @param [in] dispatch_qaddr
+    ///     The address of the dispatch_queue_t structure for this thread.
+    ///
+    /// @return
+    ///     The string of this queue's name.  An empty string is returned if the
+    ///     name could not be found.
+    //------------------------------------------------------------------
+    virtual std::string
+    GetQueueNameFromThreadQAddress (lldb::addr_t dispatch_qaddr)
+    {
+        return "";
+    }
+
+    //------------------------------------------------------------------
+    /// Get the QueueID for the libdispatch queue given the thread's dispatch_qaddr.
+    ///
+    /// On systems using libdispatch queues, a thread may be associated with a queue.
+    /// There will be a call to get the thread's dispatch_qaddr.  At the dispatch_qaddr
+    /// we will find the address of this thread's dispatch_queue_t structure.
+    /// Given the address of the dispatch_queue_t structure for a thread,
+    /// get the queue ID and return it.
+    /// 
+    /// @param [in] dispatch_qaddr
+    ///     The address of the dispatch_queue_t structure for this thread.
+    ///
+    /// @return
+    ///     The queue ID, or if it could not be retrieved, LLDB_INVALID_QUEUE_ID.
+    //------------------------------------------------------------------
+    virtual lldb::queue_id_t
+    GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr)
+    {
+        return LLDB_INVALID_QUEUE_ID;
+    }
+
+    //------------------------------------------------------------------
+    /// Get the pending work items for a libdispatch Queue
+    ///
+    /// If this system/process is using libdispatch and the runtime can do so,
+    /// retrieve the list of pending work items for the specified Queue and
+    /// add it to the Queue.
+    ///
+    /// @param [in] queue
+    ///     The queue of interest.
+    //------------------------------------------------------------------
+    virtual void
+    PopulatePendingItemsForQueue (lldb_private::Queue *queue)
+    {
+    }
 
 protected:
     //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/lldb-private-log.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-log.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-log.h (original)
+++ lldb/trunk/include/lldb/lldb-private-log.h Tue Feb  4 23:44:54 2014
@@ -45,6 +45,7 @@
 #define LIBLLDB_LOG_MMAP                (1u << 23)
 #define LIBLLDB_LOG_OS                  (1u << 24)
 #define LIBLLDB_LOG_PLATFORM            (1u << 25)
+#define LIBLLDB_LOG_SYSTEM_RUNTIME      (1u << 26)
 #define LIBLLDB_LOG_ALL                 (UINT32_MAX)
 #define LIBLLDB_LOG_DEFAULT             (LIBLLDB_LOG_PROCESS              |\
                                          LIBLLDB_LOG_THREAD               |\

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Feb  4 23:44:54 2014
@@ -616,17 +616,25 @@
 		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 */; };
+		AF0E22F018A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0E22EE18A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp */; };
+		AF0E22F118A09FB20009B7D1 /* AppleGetItemInfoHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AF0E22EF18A09FB20009B7D1 /* AppleGetItemInfoHandler.h */; };
 		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 */; };
+		AF1F7B07189C904B0087DB9C /* AppleGetPendingItemsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1F7B05189C904B0087DB9C /* AppleGetPendingItemsHandler.cpp */; };
+		AF1F7B08189C904B0087DB9C /* AppleGetPendingItemsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AF1F7B06189C904B0087DB9C /* AppleGetPendingItemsHandler.h */; };
 		AF254E31170CCC33007AE5C9 /* PlatformDarwinKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF254E2F170CCC33007AE5C9 /* PlatformDarwinKernel.cpp */; };
 		AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */ = {isa = PBXBuildFile; fileRef = AF254E30170CCC33007AE5C9 /* PlatformDarwinKernel.h */; };
+		AF25AB26188F685C0030DEC3 /* AppleGetQueuesHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF25AB24188F685C0030DEC3 /* AppleGetQueuesHandler.cpp */; };
+		AF25AB27188F685C0030DEC3 /* AppleGetQueuesHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AF25AB25188F685C0030DEC3 /* AppleGetQueuesHandler.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 */; };
+		AF45FDE518A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF45FDE318A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp */; };
+		AF45FDE618A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AF45FDE418A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h */; };
 		AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */; };
 		AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = AF90106315AB7C5700FF120D /* lldb.1 */; };
 		AF9B8F33182DB52900DA866F /* SystemRuntimeMacOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9B8F31182DB52900DA866F /* SystemRuntimeMacOSX.cpp */; };
@@ -1791,6 +1799,8 @@
 		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>"; };
+		AF0E22EE18A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppleGetItemInfoHandler.cpp; sourceTree = "<group>"; };
+		AF0E22EF18A09FB20009B7D1 /* AppleGetItemInfoHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleGetItemInfoHandler.h; 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>"; };
@@ -1799,11 +1809,17 @@
 		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>"; };
+		AF1F7B05189C904B0087DB9C /* AppleGetPendingItemsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppleGetPendingItemsHandler.cpp; sourceTree = "<group>"; };
+		AF1F7B06189C904B0087DB9C /* AppleGetPendingItemsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleGetPendingItemsHandler.h; 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>"; };
+		AF25AB24188F685C0030DEC3 /* AppleGetQueuesHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppleGetQueuesHandler.cpp; sourceTree = "<group>"; };
+		AF25AB25188F685C0030DEC3 /* AppleGetQueuesHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleGetQueuesHandler.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>"; };
+		AF45FDE318A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppleGetThreadItemInfoHandler.cpp; sourceTree = "<group>"; };
+		AF45FDE418A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleGetThreadItemInfoHandler.h; 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>"; };
 		AF68D32F1255A110002FF25B /* UnwindLLDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindLLDB.cpp; path = Utility/UnwindLLDB.cpp; sourceTree = "<group>"; };
@@ -3619,6 +3635,14 @@
 		AF11CB35182CA85A00D9B618 /* MacOSX */ = {
 			isa = PBXGroup;
 			children = (
+				AF0E22EE18A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp */,
+				AF0E22EF18A09FB20009B7D1 /* AppleGetItemInfoHandler.h */,
+				AF1F7B05189C904B0087DB9C /* AppleGetPendingItemsHandler.cpp */,
+				AF1F7B06189C904B0087DB9C /* AppleGetPendingItemsHandler.h */,
+				AF25AB24188F685C0030DEC3 /* AppleGetQueuesHandler.cpp */,
+				AF25AB25188F685C0030DEC3 /* AppleGetQueuesHandler.h */,
+				AF45FDE318A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp */,
+				AF45FDE418A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h */,
 				AF9B8F31182DB52900DA866F /* SystemRuntimeMacOSX.cpp */,
 				AF9B8F32182DB52900DA866F /* SystemRuntimeMacOSX.h */,
 			);
@@ -3717,8 +3741,10 @@
 				4C6649A014EEE7F100B0316F /* StreamCallback.h in Headers */,
 				26B7564F14F89356008D9CB3 /* PlatformiOSSimulator.h in Headers */,
 				26FFC19A14FC072100087D58 /* AuxVector.h in Headers */,
+				AF25AB27188F685C0030DEC3 /* AppleGetQueuesHandler.h in Headers */,
 				26CA97A2172B1FD5005DC71B /* RegisterContextThreadMemory.h in Headers */,
 				26FFC19C14FC072100087D58 /* DYLDRendezvous.h in Headers */,
+				AF1F7B08189C904B0087DB9C /* AppleGetPendingItemsHandler.h in Headers */,
 				26FFC19E14FC072100087D58 /* DynamicLoaderPOSIXDYLD.h in Headers */,
 				AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */,
 				2694E99E14FC0BB30076DE67 /* PlatformFreeBSD.h in Headers */,
@@ -3728,12 +3754,14 @@
 				945759681534941F005A9070 /* PlatformPOSIX.h in Headers */,
 				26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */,
 				260CC62E15D04377002BF2E0 /* OptionValueArgs.h in Headers */,
+				AF0E22F118A09FB20009B7D1 /* AppleGetItemInfoHandler.h in Headers */,
 				260CC62F15D04377002BF2E0 /* OptionValueArray.h in Headers */,
 				260CC63015D04377002BF2E0 /* OptionValueBoolean.h in Headers */,
 				260CC63115D04377002BF2E0 /* OptionValueProperties.h in Headers */,
 				260CC63215D04377002BF2E0 /* OptionValueDictionary.h in Headers */,
 				262173A118395D3800C52091 /* SectionLoadHistory.h in Headers */,
 				260CC63315D04377002BF2E0 /* OptionValueEnumeration.h in Headers */,
+				AF45FDE618A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h in Headers */,
 				260A63171861008E00FECF8E /* IOHandler.h in Headers */,
 				260CC63415D04377002BF2E0 /* OptionValueFileSpec.h in Headers */,
 				26CFDCA11861638D000E63E5 /* Editline.h in Headers */,
@@ -4232,6 +4260,7 @@
 				2689004C13353E0400698AC0 /* SourceManager.cpp in Sources */,
 				2689004D13353E0400698AC0 /* State.cpp in Sources */,
 				94D0B10D16D5535900EA9C70 /* LibStdcpp.cpp in Sources */,
+				AF0E22F018A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp in Sources */,
 				2689004E13353E0400698AC0 /* Stream.cpp in Sources */,
 				2689004F13353E0400698AC0 /* StreamFile.cpp in Sources */,
 				2689005013353E0400698AC0 /* StreamString.cpp in Sources */,
@@ -4412,6 +4441,7 @@
 				2689011213353E8200698AC0 /* StringExtractorGDBRemote.cpp in Sources */,
 				2689011313353E8200698AC0 /* PseudoTerminal.cpp in Sources */,
 				94D6A0AA16CEB55F00833B6E /* NSArray.cpp in Sources */,
+				AF1F7B07189C904B0087DB9C /* AppleGetPendingItemsHandler.cpp in Sources */,
 				26B1FCC21338115F002886E2 /* Host.mm in Sources */,
 				26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */,
 				26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */,
@@ -4422,6 +4452,7 @@
 				2671A0D013482601003A87BB /* ConnectionMachPort.cpp in Sources */,
 				4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */,
 				4CD0BD0F134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp in Sources */,
+				AF45FDE518A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp in Sources */,
 				26D5E15F135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp in Sources */,
 				26D5E163135BB054006EA0A7 /* OptionGroupPlatform.cpp in Sources */,
 				26BD407F135D2AE000237D80 /* FileLineResolver.cpp in Sources */,
@@ -4523,6 +4554,7 @@
 				94BA8B6D176F8C9B005A91B5 /* Range.cpp in Sources */,
 				26DAED6315D327C200E15819 /* OptionValuePathMappings.cpp in Sources */,
 				B2B7CCEB15D1BD6700EEFB57 /* CommandObjectWatchpointCommand.cpp in Sources */,
+				AF25AB26188F685C0030DEC3 /* AppleGetQueuesHandler.cpp in Sources */,
 				B2B7CCF015D1C20F00EEFB57 /* WatchpointOptions.cpp in Sources */,
 				2640E19F15DC78FD00F23B50 /* Property.cpp in Sources */,
 				26491E3E15E1DB9F00CBFFC2 /* OptionValueRegex.cpp in Sources */,

Modified: lldb/trunk/scripts/Python/interface/SBQueue.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBQueue.i?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBQueue.i (original)
+++ lldb/trunk/scripts/Python/interface/SBQueue.i Tue Feb  4 23:44:54 2014
@@ -43,10 +43,10 @@ public:
     GetThreadAtIndex (uint32_t);
 
     uint32_t
-    GetNumItems ();
+    GetNumPendingItems ();
 
     lldb::SBQueueItem
-    GetItemAtIndex (uint32_t);
+    GetPendingItemAtIndex (uint32_t);
 
 };
 

Modified: lldb/trunk/scripts/Python/interface/SBThread.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBThread.i?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBThread.i (original)
+++ lldb/trunk/scripts/Python/interface/SBThread.i Tue Feb  4 23:44:54 2014
@@ -121,9 +121,28 @@ public:
     SBValue
     GetStopReturnValue ();
 
+    %feature("autodoc", "
+    Returns a unique thread identifier (type lldb::tid_t, typically a 64-bit type)
+    for the current SBThread that will remain constant throughout the thread's
+    lifetime in this process and will not be reused by another thread during this
+    process lifetime.  On Mac OS X systems, this is a system-wide unique thread
+    identifier; this identifier is also used by other tools like sample which helps
+    to associate data from those tools with lldb.  See related GetIndexID.
+    ")
+    GetThreadID;
     lldb::tid_t
     GetThreadID () const;
 
+    %feature("autodoc", "
+    Return the index number for this SBThread.  The index number is the same thing
+    that a user gives as an argument to 'thread select' in the command line lldb.
+    These numbers start at 1 (for the first thread lldb sees in a debug session)
+    and increments up throughout the process lifetime.  An index number will not be
+    reused for a different thread later in a process - thread 1 will always be
+    associated with the same thread.  See related GetThreadID.
+    This method returns a uint32_t index number, takes no arguments.
+    ")
+    GetIndexID;
     uint32_t
     GetIndexID () const;
 

Modified: lldb/trunk/source/API/SBQueue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBQueue.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/API/SBQueue.cpp (original)
+++ lldb/trunk/source/API/SBQueue.cpp Tue Feb  4 23:44:54 2014
@@ -32,8 +32,8 @@ namespace lldb_private
             m_queue_wp(),
             m_threads(),
             m_thread_list_fetched(false),
-            m_items(),
-            m_queue_items_fetched(false)
+            m_pending_items(),
+            m_pending_items_fetched(false)
         {
         }
 
@@ -41,8 +41,8 @@ namespace lldb_private
             m_queue_wp(),
             m_threads(),
             m_thread_list_fetched(false),
-            m_items(),
-            m_queue_items_fetched(false)
+            m_pending_items(),
+            m_pending_items_fetched(false)
         {
             m_queue_wp = queue_sp;
         }
@@ -54,8 +54,8 @@ namespace lldb_private
             m_queue_wp = rhs.m_queue_wp;
             m_threads = rhs.m_threads;
             m_thread_list_fetched = rhs.m_thread_list_fetched;
-            m_items = rhs.m_items;
-            m_queue_items_fetched = rhs.m_queue_items_fetched;
+            m_pending_items = rhs.m_pending_items;
+            m_pending_items_fetched = rhs.m_pending_items_fetched;
         }
 
         ~QueueImpl ()
@@ -74,8 +74,8 @@ namespace lldb_private
             m_queue_wp.reset();
             m_thread_list_fetched = false;
             m_threads.clear();
-            m_queue_items_fetched = false;
-            m_items.clear();
+            m_pending_items_fetched = false;
+            m_pending_items.clear();
         }
 
         void
@@ -162,7 +162,7 @@ namespace lldb_private
         void
         FetchItems ()
         {
-            if (m_queue_items_fetched == false)
+            if (m_pending_items_fetched == false)
             {
                 QueueSP queue_sp = m_queue_wp.lock();
                 if (queue_sp)
@@ -170,15 +170,15 @@ namespace lldb_private
                     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)
+                        const std::vector<QueueItemSP> queue_items(queue_sp->GetPendingItems());
+                        m_pending_items_fetched = true;
+                        const uint32_t num_pending_items = queue_items.size();
+                        for (uint32_t idx = 0; idx < num_pending_items; ++idx)
                         {
                             QueueItemSP item = queue_items[idx];
                             if (item && item->IsValid())
                             {
-                                m_items.push_back (item);
+                                m_pending_items.push_back (item);
                             }
                         }
                     }
@@ -223,26 +223,26 @@ namespace lldb_private
         
         
         uint32_t
-        GetNumItems ()
+        GetNumPendingItems ()
         {
             uint32_t result = 0;
             FetchItems();
         
-            if (m_queue_items_fetched)
+            if (m_pending_items_fetched)
             {
-                result = m_items.size();
+                result = m_pending_items.size();
             }
             return result;
         }
         
         lldb::SBQueueItem
-        GetItemAtIndex (uint32_t idx)
+        GetPendingItemAtIndex (uint32_t idx)
         {
             SBQueueItem result;
             FetchItems();
-            if (m_queue_items_fetched && idx < m_items.size())
+            if (m_pending_items_fetched && idx < m_pending_items.size())
             {
-                result.SetQueueItem (m_items[idx]);
+                result.SetQueueItem (m_pending_items[idx]);
             }
             return result;
         }
@@ -263,8 +263,8 @@ namespace lldb_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?
+        std::vector<lldb::QueueItemSP>  m_pending_items;       // items currently enqueued
+        bool                            m_pending_items_fetched;  // have we tried to fetch the item list already?
     };
 
 }
@@ -350,15 +350,15 @@ SBQueue::GetThreadAtIndex (uint32_t idx)
 
 
 uint32_t
-SBQueue::GetNumItems ()
+SBQueue::GetNumPendingItems ()
 {
-    return m_opaque_sp->GetNumItems ();
+    return m_opaque_sp->GetNumPendingItems ();
 }
 
 SBQueueItem
-SBQueue::GetItemAtIndex (uint32_t idx)
+SBQueue::GetPendingItemAtIndex (uint32_t idx)
 {
-    return m_opaque_sp->GetItemAtIndex (idx);
+    return m_opaque_sp->GetPendingItemAtIndex (idx);
 }
 
 SBProcess

Modified: lldb/trunk/source/API/SBQueueItem.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBQueueItem.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/API/SBQueueItem.cpp (original)
+++ lldb/trunk/source/API/SBQueueItem.cpp Tue Feb  4 23:44:54 2014
@@ -15,6 +15,7 @@
 #include "lldb/API/SBThread.h"
 #include "lldb/Core/Address.h"
 #include "lldb/Target/QueueItem.h"
+#include "lldb/Target/Thread.h"
 
 using namespace lldb;
 using namespace lldb_private;

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Tue Feb  4 23:44:54 2014
@@ -38,9 +38,7 @@ using namespace lldb_private;
 //------------------------------------------------------------------
 PlatformDarwin::PlatformDarwin (bool is_host) :
     PlatformPOSIX(is_host),  // This is the local host platform
-    m_developer_directory (),
-    m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
-    m_libdispatch_offsets()
+    m_developer_directory ()
 {
 }
 
@@ -872,114 +870,6 @@ PlatformDarwin::ModuleIsExcludedForNonMo
         return false;
 }
 
-std::string
-PlatformDarwin::GetQueueNameForThreadQAddress (Process *process, addr_t thread_dispatch_qaddr)
-{
-    std::string dispatch_queue_name;
-    if (thread_dispatch_qaddr == LLDB_INVALID_ADDRESS || thread_dispatch_qaddr == 0 || process == NULL)
-        return "";
-
-    ReadLibdispatchOffsets (process);
-    if (m_libdispatch_offsets.IsValid ())
-    {
-        Error error;
-        addr_t queue_addr = process->ReadPointerFromMemory (thread_dispatch_qaddr, error);
-        if (error.Success())
-        {
-            if (m_libdispatch_offsets.dqo_version >= 4)
-            {
-                // libdispatch versions 4+, pointer to dispatch name is in the
-                // queue structure.
-                addr_t pointer_to_label_address = queue_addr + m_libdispatch_offsets.dqo_label;
-                addr_t label_addr = process->ReadPointerFromMemory (pointer_to_label_address, error);
-                if (error.Success())
-                {
-                    process->ReadCStringFromMemory (label_addr, dispatch_queue_name, error);
-                }
-            }
-            else
-            {
-                // libdispatch versions 1-3, dispatch name is a fixed width char array
-                // in the queue structure.
-                addr_t label_addr = queue_addr + m_libdispatch_offsets.dqo_label;
-                dispatch_queue_name.resize (m_libdispatch_offsets.dqo_label_size, '\0');
-                size_t bytes_read = process->ReadMemory (label_addr, &dispatch_queue_name[0], m_libdispatch_offsets.dqo_label_size, error);
-                if (bytes_read < m_libdispatch_offsets.dqo_label_size)
-                    dispatch_queue_name.erase (bytes_read);
-            }
-        }
-    }
-    return dispatch_queue_name;
-}
-
-void
-PlatformDarwin::ReadLibdispatchOffsetsAddress (Process *process)
-{
-    if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
-        return;
-
-    static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
-    const Symbol *dispatch_queue_offsets_symbol = NULL;
-
-    // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6 ("Snow Leopard")
-    ModuleSpec libSystem_module_spec (FileSpec("libSystem.B.dylib", false));
-    ModuleSP module_sp(process->GetTarget().GetImages().FindFirstModule (libSystem_module_spec));
-    if (module_sp)
-        dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
-    
-    // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and later
-    if (dispatch_queue_offsets_symbol == NULL)
-    {
-        ModuleSpec libdispatch_module_spec (FileSpec("libdispatch.dylib", false));
-        module_sp = process->GetTarget().GetImages().FindFirstModule (libdispatch_module_spec);
-        if (module_sp)
-            dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
-    }
-    if (dispatch_queue_offsets_symbol)
-        m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetAddress().GetLoadAddress(&process->GetTarget());
-}
-
-void
-PlatformDarwin::ReadLibdispatchOffsets (Process *process)
-{
-    if (m_libdispatch_offsets.IsValid())
-        return;
-
-    ReadLibdispatchOffsetsAddress (process);
-
-    uint8_t memory_buffer[sizeof (struct LibdispatchOffsets)];
-    DataExtractor data (memory_buffer, 
-                        sizeof(memory_buffer), 
-                        process->GetTarget().GetArchitecture().GetByteOrder(), 
-                        process->GetTarget().GetArchitecture().GetAddressByteSize());
-
-    Error error;
-    if (process->ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer))
-    {
-        lldb::offset_t data_offset = 0;
-
-        // The struct LibdispatchOffsets is a series of uint16_t's - extract them all
-        // in one big go.
-        data.GetU16 (&data_offset, &m_libdispatch_offsets.dqo_version, sizeof (struct LibdispatchOffsets) / sizeof (uint16_t));
-    }
-}
-
-lldb::queue_id_t
-PlatformDarwin::GetQueueIDForThreadQAddress (Process *process, lldb::addr_t dispatch_qaddr)
-{
-    if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0 || process == NULL)
-        return LLDB_INVALID_QUEUE_ID;
-
-    Error error;
-    uint32_t ptr_size = process->GetTarget().GetArchitecture().GetAddressByteSize();
-    uint64_t this_thread_queue_id = process->ReadUnsignedIntegerFromMemory (dispatch_qaddr, ptr_size, LLDB_INVALID_QUEUE_ID, error);
-    if (!error.Success())
-        return LLDB_INVALID_QUEUE_ID;
-
-    return this_thread_queue_id;
-}
-
-
 bool
 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
 {

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h Tue Feb  4 23:44:54 2014
@@ -118,12 +118,6 @@ public:
     virtual size_t
     GetEnvironment (lldb_private::StringList &environment);
 
-    std::string
-    GetQueueNameForThreadQAddress (lldb_private::Process *process, lldb::addr_t dispatch_qaddr);
-
-    lldb::queue_id_t
-    GetQueueIDForThreadQAddress (lldb_private::Process *process, lldb::addr_t dispatch_qaddr);
-
     bool
     ARMGetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch);
     
@@ -148,49 +142,7 @@ protected:
                                    lldb::ModuleSP *old_module_sp_ptr,
                                    bool *did_create_ptr);
 
-    // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s
-    // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot be cached.
-    // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value that can be cached.
-    struct LibdispatchOffsets
-    {
-        uint16_t dqo_version;
-        uint16_t dqo_label;
-        uint16_t dqo_label_size;
-        uint16_t dqo_flags;
-        uint16_t dqo_flags_size;
-        uint16_t dqo_serialnum;
-        uint16_t dqo_serialnum_size;
-        uint16_t dqo_width;
-        uint16_t dqo_width_size;
-        uint16_t dqo_running;
-        uint16_t dqo_running_size;
-
-        LibdispatchOffsets ()
-        {
-            dqo_version = UINT16_MAX;
-            dqo_flags  = UINT16_MAX;
-            dqo_serialnum = UINT16_MAX;
-            dqo_label = UINT16_MAX;
-            dqo_width = UINT16_MAX;
-            dqo_running = UINT16_MAX;
-        };
-
-        bool
-        IsValid ()
-        {
-            return dqo_version != UINT16_MAX;
-        }
-
-        bool
-        LabelIsValid ()
-        {
-            return dqo_label != UINT16_MAX;
-        }
-    };
-
     std::string                 m_developer_directory;
-    lldb::addr_t                m_dispatch_queue_offsets_addr;
-    struct LibdispatchOffsets   m_libdispatch_offsets;
 
     const char *
     GetDeveloperDirectory();

Modified: lldb/trunk/source/Plugins/Process/Utility/HistoryThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/HistoryThread.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/HistoryThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/HistoryThread.cpp Tue Feb  4 23:44:54 2014
@@ -25,7 +25,7 @@ HistoryThread::HistoryThread (lldb_priva
                               std::vector<lldb::addr_t> pcs, 
                               uint32_t stop_id, 
                               bool stop_id_is_valid) : 
-        Thread (process, LLDB_INVALID_THREAD_ID),
+        Thread (process, tid),
         m_framelist_mutex(),
         m_framelist(),
         m_pcs (pcs),

Modified: lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/HistoryThread.h Tue Feb  4 23:44:54 2014
@@ -22,6 +22,16 @@
 
 namespace lldb_private {
 
+//----------------------------------------------------------------------
+/// @class HistoryThread HistoryThread.h "HistoryThread.h"
+/// @brief A thread object representing a backtrace from a previous point in the process execution
+///
+/// This subclass of Thread is used to provide a backtrace from earlier in
+/// process execution.  It is given a backtrace list of pc addresses and 
+/// optionally a stop_id of when those pc addresses were collected, and it will
+/// create stack frames for them.
+//----------------------------------------------------------------------
+
 class HistoryThread : public lldb_private::Thread
 {
 public:

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Tue Feb  4 23:44:54 2014
@@ -19,6 +19,7 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
+#include "lldb/Target/SystemRuntime.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Unwind.h"
 
@@ -74,10 +75,10 @@ ThreadGDBRemote::GetQueueName ()
         ProcessSP process_sp (GetProcess());
         if (process_sp)
         {
-            PlatformSP platform_sp (process_sp->GetTarget().GetPlatform());
-            if (platform_sp)
+            SystemRuntime *runtime = process_sp->GetSystemRuntime ();
+            if (runtime)
             {
-                m_dispatch_queue_name = platform_sp->GetQueueNameForThreadQAddress (process_sp.get(), m_thread_dispatch_qaddr);
+                m_dispatch_queue_name = runtime->GetQueueNameFromThreadQAddress (m_thread_dispatch_qaddr);
             }
             if (m_dispatch_queue_name.length() > 0)
             {
@@ -96,10 +97,10 @@ ThreadGDBRemote::GetQueueID ()
         ProcessSP process_sp (GetProcess());
         if (process_sp)
         {
-            PlatformSP platform_sp (process_sp->GetTarget().GetPlatform());
-            if (platform_sp)
+            SystemRuntime *runtime = process_sp->GetSystemRuntime ();
+            if (runtime)
             {
-                return platform_sp->GetQueueIDForThreadQAddress (process_sp.get(), m_thread_dispatch_qaddr);
+                return runtime->GetQueueIDFromThreadQAddress (m_thread_dispatch_qaddr);
             }
         }
     }

Added: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp?rev=200822&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp (added)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp Tue Feb  4 23:44:54 2014
@@ -0,0 +1,390 @@
+//===-- AppleGetItemInfoHandler.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AppleGetItemInfoHandler.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char *AppleGetItemInfoHandler::g_get_item_info_function_name = "__lldb_backtrace_recording_get_item_info";
+const char *AppleGetItemInfoHandler::g_get_item_info_function_code = "                                  \n\
+extern \"C\"                                                                                                    \n\
+{                                                                                                               \n\
+    /*                                                                                                          \n\
+     * mach defines                                                                                             \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    typedef unsigned int uint32_t;                                                                              \n\
+    typedef unsigned long long uint64_t;                                                                        \n\
+    typedef uint32_t mach_port_t;                                                                               \n\
+    typedef mach_port_t vm_map_t;                                                                               \n\
+    typedef int kern_return_t;                                                                                  \n\
+    typedef uint64_t mach_vm_address_t;                                                                         \n\
+    typedef uint64_t mach_vm_size_t;                                                                            \n\
+                                                                                                                \n\
+    mach_port_t mach_task_self ();                                                                              \n\
+    kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size);         \n\
+                                                                                                                \n\
+    /*                                                                                                          \n\
+     * libBacktraceRecording defines                                                                            \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    typedef uint32_t queue_list_scope_t;                                                                        \n\
+    typedef void *dispatch_queue_t;                                                                             \n\
+    typedef void *introspection_dispatch_queue_info_t;                                                          \n\
+    typedef void *introspection_dispatch_item_info_ref;                                                         \n\
+                                                                                                                \n\
+    extern uint64_t __introspection_dispatch_queue_item_get_info (introspection_dispatch_item_info_ref item_info_ref, \n\
+                                                 introspection_dispatch_item_info_ref *returned_queues_buffer,  \n\
+                                                 uint64_t *returned_queues_buffer_size);                        \n\
+    extern int printf(const char *format, ...);                                                                 \n\
+                                                                                                                \n\
+    /*                                                                                                          \n\
+     * return type define                                                                                       \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    struct get_item_info_return_values                                                                      \n\
+    {                                                                                                           \n\
+        uint64_t item_info_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */  \n\
+        uint64_t item_info_buffer_size;   /* the size of the items buffer from libBacktraceRecording */     \n\
+    };                                                                                                          \n\
+                                                                                                                \n\
+    void  __lldb_backtrace_recording_get_item_info                                                          \n\
+                                               (struct get_item_info_return_values *return_buffer,          \n\
+                                                int debug,                                                      \n\
+                                                uint64_t /* introspection_dispatch_item_info_ref item_info_ref */ item, \n\
+                                                void *page_to_free,                                             \n\
+                                                uint64_t page_to_free_size)                                     \n\
+{                                                                                                               \n\
+    if (debug)                                                                                                  \n\
+      printf (\"entering get_item_info with args return_buffer == %p, debug == %d, item == 0x%llx, page_to_free == %p, page_to_free_size == 0x%llx\\n\", return_buffer, debug, item, page_to_free, page_to_free_size); \n\
+    if (page_to_free != 0)                                                                                      \n\
+    {                                                                                                           \n\
+        mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
+    }                                                                                                           \n\
+                                                                                                                \n\
+    __introspection_dispatch_queue_item_get_info ((void*) item,                                                 \n\
+                                                  (void**)&return_buffer->item_info_buffer_ptr,                 \n\
+                                                  &return_buffer->item_info_buffer_size);                       \n\
+}                                                                                                               \n\
+}                                                                                                               \n\
+";
+
+AppleGetItemInfoHandler::AppleGetItemInfoHandler (Process *process) :
+    m_process (process),
+    m_get_item_info_function (),
+    m_get_item_info_impl_code (),
+    m_get_item_info_function_mutex(),
+    m_get_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
+    m_get_item_info_retbuffer_mutex()
+{
+}
+
+AppleGetItemInfoHandler::~AppleGetItemInfoHandler ()
+{
+}
+
+void
+AppleGetItemInfoHandler::Detach ()
+{
+
+    if (m_process && m_process->IsAlive() && m_get_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
+    {
+        Mutex::Locker locker;
+        locker.TryLock (m_get_item_info_retbuffer_mutex);  // Even if we don't get the lock, deallocate the buffer
+        m_process->DeallocateMemory (m_get_item_info_return_buffer_addr);
+    }
+}
+
+// Compile our __lldb_backtrace_recording_get_item_info() function (from the
+// source above in g_get_item_info_function_code) if we don't find that function in the inferior
+// already with USE_BUILTIN_FUNCTION defined.  (e.g. this would be the case for testing.)
+//
+// Insert the __lldb_backtrace_recording_get_item_info into the inferior process if needed.
+//
+// Write the get_item_info_arglist into the inferior's memory space to prepare for the call.
+// 
+// Returns the address of the arguments written down in the inferior process, which can be used to
+// make the function call.
+
+lldb::addr_t
+AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &get_item_info_arglist)
+{
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    Address impl_code_address;
+    StreamString errors;
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+    lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+
+    // Scope for mutex locker:
+    {
+        Mutex::Locker locker(m_get_item_info_function_mutex);
+        
+        // First stage is to make the ClangUtility to hold our injected function:
+
+#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
+                                // This is useful for debugging additions to the get_impl function 'cause you don't have
+                                // to bother with string-ifying the code into g_get_item_info_function_code.
+        
+        if (USE_BUILTIN_FUNCTION)
+        {
+            ConstString our_utility_function_name("__lldb_backtrace_recording_get_item_info");
+            SymbolContextList sc_list;
+            
+            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
+            if (sc_list.GetSize() == 1)
+            {
+                SymbolContext sc;
+                sc_list.GetContextAtIndex(0, sc);
+                if (sc.symbol != NULL)
+                    impl_code_address = sc.symbol->GetAddress();
+                    
+                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
+                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
+            }
+            else
+            {
+                //printf ("Could not find queues introspection function address.\n");
+                return args_addr;
+            }
+        }
+        else if (!m_get_item_info_impl_code.get())
+        {
+            if (g_get_item_info_function_code != NULL)
+            {
+                m_get_item_info_impl_code.reset (new ClangUtilityFunction (g_get_item_info_function_code,
+                                                             g_get_item_info_function_name));
+                if (!m_get_item_info_impl_code->Install(errors, exe_ctx))
+                {
+                    if (log)
+                        log->Printf ("Failed to install get-item-info introspection: %s.", errors.GetData());
+                    m_get_item_info_impl_code.reset();
+                    return args_addr;
+                }
+            }
+            else
+            {
+                if (log)
+                    log->Printf("No get-item-info introspection code found.");
+                errors.Printf ("No get-item-info introspection code found.");
+                return LLDB_INVALID_ADDRESS;
+            }
+            
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_get_item_info_impl_code->StartAddress());
+        }
+        else
+        {
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_get_item_info_impl_code->StartAddress());
+        }
+
+        // Next make the runner function for our implementation utility function.
+        if (!m_get_item_info_function.get())
+        {
+            ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+            ClangASTType get_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+            m_get_item_info_function.reset(new ClangFunction (thread,
+                                                     get_item_info_return_type,
+                                                     impl_code_address,
+                                                     get_item_info_arglist));
+            
+            errors.Clear();        
+            unsigned num_errors = m_get_item_info_function->CompileFunction(errors);
+            if (num_errors)
+            {
+                if (log)
+                    log->Printf ("Error compiling get-item-info function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+            
+            errors.Clear();
+            if (!m_get_item_info_function->WriteFunctionWrapper(exe_ctx, errors))
+            {
+                if (log)
+                    log->Printf ("Error Inserting get-item-info function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+        }
+    }
+    
+    errors.Clear();
+    
+    // Now write down the argument values for this particular call.  This looks like it might be a race condition
+    // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
+    // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+    if (!m_get_item_info_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_item_info_arglist, errors))
+    {
+        if (log)
+            log->Printf ("Error writing get-item-info function arguments: \"%s\".", errors.GetData());
+        return args_addr;
+    }
+        
+    return args_addr;
+}
+
+AppleGetItemInfoHandler::GetItemInfoReturnInfo
+AppleGetItemInfoHandler::GetItemInfo (Thread &thread, uint64_t item, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
+{
+    lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+    ProcessSP process_sp (thread.CalculateProcess());
+    TargetSP target_sp (thread.CalculateTarget());
+    ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+    GetItemInfoReturnInfo return_value;
+    return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+    return_value.item_buffer_size = 0;
+
+    error.Clear();
+
+    // Set up the arguments for a call to
+
+    // struct get_item_info_return_values
+    // {
+    //     uint64_t item_info_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */
+    //     uint64_t item_info_buffer_size;   /* the size of the items buffer from libBacktraceRecording */
+    // };
+    //
+    // void  __lldb_backtrace_recording_get_item_info
+    //                                            (struct get_item_info_return_values *return_buffer,
+    //                                             int debug,
+    //                                             uint64_t item,
+    //                                             void *page_to_free,
+    //                                             uint64_t page_to_free_size)
+
+    // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
+    // the inferior process.
+
+    ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+    Value return_buffer_ptr_value;
+    return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
+    return_buffer_ptr_value.SetClangType (clang_void_ptr_type);
+
+    ClangASTType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+    Value debug_value;
+    debug_value.SetValueType (Value::eValueTypeScalar);
+    debug_value.SetClangType (clang_int_type);
+
+    ClangASTType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+    Value item_value;
+    item_value.SetValueType (Value::eValueTypeScalar);
+    item_value.SetClangType (clang_uint64_type);
+
+    Value page_to_free_value;
+    page_to_free_value.SetValueType (Value::eValueTypeScalar);
+    page_to_free_value.SetClangType (clang_void_ptr_type);
+
+    Value page_to_free_size_value;
+    page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
+    page_to_free_size_value.SetClangType (clang_uint64_type);
+
+
+    Mutex::Locker locker(m_get_item_info_retbuffer_mutex);
+    if (m_get_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
+    {
+        addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
+        if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
+        {
+            if (log)
+                log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
+            return return_value;
+        }
+        m_get_item_info_return_buffer_addr = bufaddr;
+    }
+
+    ValueList argument_values;
+
+    return_buffer_ptr_value.GetScalar() = m_get_item_info_return_buffer_addr;
+    argument_values.PushValue (return_buffer_ptr_value);
+
+    debug_value.GetScalar() = 0;
+    argument_values.PushValue (debug_value);
+
+    item_value.GetScalar() = item;
+    argument_values.PushValue (item_value);
+
+    if (page_to_free != LLDB_INVALID_ADDRESS)
+        page_to_free_value.GetScalar() = page_to_free;
+    else
+        page_to_free_value.GetScalar() = 0;
+    argument_values.PushValue (page_to_free_value);
+
+    page_to_free_size_value.GetScalar() = page_to_free_size;
+    argument_values.PushValue (page_to_free_size_value);
+
+    addr_t args_addr = SetupGetItemInfoFunction (thread, argument_values);
+
+    StreamString errors;
+    ExecutionContext exe_ctx;
+    EvaluateExpressionOptions options;
+    options.SetUnwindOnError (true);
+    options.SetIgnoreBreakpoints (true);
+    options.SetStopOthers (true);
+    thread.CalculateExecutionContext (exe_ctx);
+
+    if (m_get_item_info_function == NULL)
+    {
+        error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_item_get_info");
+        return return_value;
+    }
+
+
+    ExecutionResults func_call_ret;
+    Value results;
+    func_call_ret =  m_get_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+    if (func_call_ret != eExecutionCompleted || !error.Success())
+    {
+        if (log)
+            log->Printf ("Unable to call __introspection_dispatch_queue_item_get_info(), got ExecutionResults %d, error contains %s", func_call_ret, error.AsCString(""));
+        error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_item_info() for list of queues");
+        return return_value;
+    }
+
+    return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+    if (!error.Success() || return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS)
+    {
+        return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_item_info_return_buffer_addr + 8, 8, 0, error);
+
+    if (!error.Success())
+    {
+        return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return return_value;
+}

Added: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h?rev=200822&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h (added)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h Tue Feb  4 23:44:54 2014
@@ -0,0 +1,118 @@
+//===-- AppleGetItemInfoHandler.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_AppleGetItemInfoHandler_h_
+#define lldb_AppleGetItemInfoHandler_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+// This class will insert a ClangUtilityFunction into the inferior process for
+// calling libBacktraceRecording's __introspection_dispatch_queue_item_get_info()
+// function.  The function in the inferior will return a struct by value
+// with these members:
+//
+//     struct get_item_info_return_values
+//     {
+//         introspection_dispatch_item_info_ref *item_buffer;
+//         uint64_t item_buffer_size;
+//     };
+//
+// The item_buffer pointer is an address in the inferior program's address
+// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
+// lldb.  
+//
+// The AppleGetItemInfoHandler object should persist so that the ClangUtilityFunction
+// can be reused multiple times.
+
+namespace lldb_private
+{
+
+class AppleGetItemInfoHandler {
+public:
+
+    AppleGetItemInfoHandler (lldb_private::Process *process);
+
+    ~AppleGetItemInfoHandler();
+
+    struct GetItemInfoReturnInfo
+    {
+        lldb::addr_t    item_buffer_ptr;  /* the address of the item buffer from libBacktraceRecording */
+        lldb::addr_t    item_buffer_size; /* the size of the item buffer from libBacktraceRecording */
+
+        GetItemInfoReturnInfo() :
+            item_buffer_ptr(LLDB_INVALID_ADDRESS),
+            item_buffer_size(0)
+        {}
+    };
+
+    //----------------------------------------------------------
+    /// Get the information about a work item by calling
+    /// __introspection_dispatch_queue_item_get_info.  If there's a page of
+    /// memory that needs to be freed, pass in the address and size and it will
+    /// be freed before getting the list of queues.
+    ///
+    /// @param [in] thread
+    ///     The thread to run this plan on.
+    ///
+    /// @param [in] item
+    ///     The introspection_dispatch_item_info_ref value for the item of interest.
+    ///
+    /// @param [in] page_to_free
+    ///     An address of an inferior process vm page that needs to be deallocated,
+    ///     LLDB_INVALID_ADDRESS if this is not needed.
+    ///
+    /// @param [in] page_to_free_size
+    ///     The size of the vm page that needs to be deallocated if an address was
+    ///     passed in to page_to_free.
+    ///
+    /// @param [out] error
+    ///     This object will be updated with the error status / error string from any failures encountered.
+    ///
+    /// @returns
+    ///     The result of the inferior function call execution.  If there was a failure of any kind while getting
+    ///     the information, the item_buffer_ptr value will be LLDB_INVALID_ADDRESS.
+    //----------------------------------------------------------
+    GetItemInfoReturnInfo
+    GetItemInfo (Thread &thread, lldb::addr_t item, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
+
+
+    void
+    Detach ();
+
+private:
+
+    lldb::addr_t
+    SetupGetItemInfoFunction (Thread &thread, ValueList &get_item_info_arglist);
+
+    static const char *g_get_item_info_function_name;
+    static const char *g_get_item_info_function_code;
+
+    lldb_private::Process *m_process;
+    std::unique_ptr<ClangFunction> m_get_item_info_function;
+    std::unique_ptr<ClangUtilityFunction> m_get_item_info_impl_code;
+    Mutex m_get_item_info_function_mutex;
+
+    lldb::addr_t m_get_item_info_return_buffer_addr;
+    Mutex m_get_item_info_retbuffer_mutex;
+
+};
+
+}  // using namespace lldb_private
+
+#endif	// lldb_AppleGetItemInfoHandler_h_

Added: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp?rev=200822&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp (added)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp Tue Feb  4 23:44:54 2014
@@ -0,0 +1,402 @@
+//===-- AppleGetPendingItemsHandler.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AppleGetPendingItemsHandler.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char *AppleGetPendingItemsHandler::g_get_pending_items_function_name = "__lldb_backtrace_recording_get_pending_items";
+const char *AppleGetPendingItemsHandler::g_get_pending_items_function_code = "                                  \n\
+extern \"C\"                                                                                                    \n\
+{                                                                                                               \n\
+    /*                                                                                                          \n\
+     * mach defines                                                                                             \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    typedef unsigned int uint32_t;                                                                              \n\
+    typedef unsigned long long uint64_t;                                                                        \n\
+    typedef uint32_t mach_port_t;                                                                               \n\
+    typedef mach_port_t vm_map_t;                                                                               \n\
+    typedef int kern_return_t;                                                                                  \n\
+    typedef uint64_t mach_vm_address_t;                                                                         \n\
+    typedef uint64_t mach_vm_size_t;                                                                            \n\
+                                                                                                                \n\
+    mach_port_t mach_task_self ();                                                                              \n\
+    kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size);         \n\
+                                                                                                                \n\
+    /*                                                                                                          \n\
+     * libBacktraceRecording defines                                                                            \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    typedef uint32_t queue_list_scope_t;                                                                        \n\
+    typedef void *dispatch_queue_t;                                                                             \n\
+    typedef void *introspection_dispatch_queue_info_t;                                                          \n\
+    typedef void *introspection_dispatch_item_info_ref;                                                         \n\
+                                                                                                                \n\
+    extern uint64_t __introspection_dispatch_queue_get_pending_items (dispatch_queue_t queue,                   \n\
+                                                 introspection_dispatch_item_info_ref *returned_queues_buffer,  \n\
+                                                 uint64_t *returned_queues_buffer_size);                        \n\
+    extern int printf(const char *format, ...);                                                                 \n\
+                                                                                                                \n\
+    /*                                                                                                          \n\
+     * return type define                                                                                       \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    struct get_pending_items_return_values                                                                      \n\
+    {                                                                                                           \n\
+        uint64_t pending_items_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */  \n\
+        uint64_t pending_items_buffer_size;   /* the size of the items buffer from libBacktraceRecording */     \n\
+        uint64_t count;                /* the number of items included in the queues buffer */                  \n\
+    };                                                                                                          \n\
+                                                                                                                \n\
+    void  __lldb_backtrace_recording_get_pending_items                                                          \n\
+                                               (struct get_pending_items_return_values *return_buffer,          \n\
+                                                int debug,                                                      \n\
+                                                uint64_t /* dispatch_queue_t */ queue,                          \n\
+                                                void *page_to_free,                                             \n\
+                                                uint64_t page_to_free_size)                                     \n\
+{                                                                                                               \n\
+    if (debug)                                                                                                  \n\
+      printf (\"entering get_pending_items with args return_buffer == %p, debug == %d, queue == 0x%llx, page_to_free == %p, page_to_free_size == 0x%llx\\n\", return_buffer, debug, queue, page_to_free, page_to_free_size); \n\
+    if (page_to_free != 0)                                                                                      \n\
+    {                                                                                                           \n\
+        mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
+    }                                                                                                           \n\
+                                                                                                                \n\
+    return_buffer->count = __introspection_dispatch_queue_get_pending_items (                                   \n\
+                                                      (void*) queue,                                            \n\
+                                                      (void**)&return_buffer->pending_items_buffer_ptr,         \n\
+                                                      &return_buffer->pending_items_buffer_size);               \n\
+    if (debug)                                                                                                  \n\
+        printf(\"result was count %lld\\n\", return_buffer->count);                                             \n\
+}                                                                                                               \n\
+}                                                                                                               \n\
+";
+
+AppleGetPendingItemsHandler::AppleGetPendingItemsHandler (Process *process) :
+    m_process (process),
+    m_get_pending_items_function (),
+    m_get_pending_items_impl_code (),
+    m_get_pending_items_function_mutex(),
+    m_get_pending_items_return_buffer_addr (LLDB_INVALID_ADDRESS),
+    m_get_pending_items_retbuffer_mutex()
+{
+}
+
+AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler ()
+{
+}
+
+void
+AppleGetPendingItemsHandler::Detach ()
+{
+
+    if (m_process && m_process->IsAlive() && m_get_pending_items_return_buffer_addr != LLDB_INVALID_ADDRESS)
+    {
+        Mutex::Locker locker;
+        locker.TryLock (m_get_pending_items_retbuffer_mutex);  // Even if we don't get the lock, deallocate the buffer
+        m_process->DeallocateMemory (m_get_pending_items_return_buffer_addr);
+    }
+}
+
+// Compile our __lldb_backtrace_recording_get_pending_items() function (from the
+// source above in g_get_pending_items_function_code) if we don't find that function in the inferior
+// already with USE_BUILTIN_FUNCTION defined.  (e.g. this would be the case for testing.)
+//
+// Insert the __lldb_backtrace_recording_get_pending_items into the inferior process if needed.
+//
+// Write the get_pending_items_arglist into the inferior's memory space to prepare for the call.
+// 
+// Returns the address of the arguments written down in the inferior process, which can be used to
+// make the function call.
+
+lldb::addr_t
+AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, ValueList &get_pending_items_arglist)
+{
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    Address impl_code_address;
+    StreamString errors;
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+    lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+
+    // Scope for mutex locker:
+    {
+        Mutex::Locker locker(m_get_pending_items_function_mutex);
+        
+        // First stage is to make the ClangUtility to hold our injected function:
+
+#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
+                                // This is useful for debugging additions to the get_impl function 'cause you don't have
+                                // to bother with string-ifying the code into g_get_pending_items_function_code.
+        
+        if (USE_BUILTIN_FUNCTION)
+        {
+            ConstString our_utility_function_name("__lldb_backtrace_recording_get_pending_items");
+            SymbolContextList sc_list;
+            
+            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
+            if (sc_list.GetSize() == 1)
+            {
+                SymbolContext sc;
+                sc_list.GetContextAtIndex(0, sc);
+                if (sc.symbol != NULL)
+                    impl_code_address = sc.symbol->GetAddress();
+                    
+                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
+                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
+            }
+            else
+            {
+                //printf ("Could not find queues introspection function address.\n");
+                return args_addr;
+            }
+        }
+        else if (!m_get_pending_items_impl_code.get())
+        {
+            if (g_get_pending_items_function_code != NULL)
+            {
+                m_get_pending_items_impl_code.reset (new ClangUtilityFunction (g_get_pending_items_function_code,
+                                                             g_get_pending_items_function_name));
+                if (!m_get_pending_items_impl_code->Install(errors, exe_ctx))
+                {
+                    if (log)
+                        log->Printf ("Failed to install pending-items introspection: %s.", errors.GetData());
+                    m_get_pending_items_impl_code.reset();
+                    return args_addr;
+                }
+            }
+            else
+            {
+                if (log)
+                    log->Printf("No pending-items introspection code found.");
+                errors.Printf ("No pending-items introspection code found.");
+                return LLDB_INVALID_ADDRESS;
+            }
+            
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_get_pending_items_impl_code->StartAddress());
+        }
+        else
+        {
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_get_pending_items_impl_code->StartAddress());
+        }
+
+        // Next make the runner function for our implementation utility function.
+        if (!m_get_pending_items_function.get())
+        {
+            ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+            ClangASTType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+            m_get_pending_items_function.reset(new ClangFunction (thread,
+                                                     get_pending_items_return_type,
+                                                     impl_code_address,
+                                                     get_pending_items_arglist));
+            
+            errors.Clear();        
+            unsigned num_errors = m_get_pending_items_function->CompileFunction(errors);
+            if (num_errors)
+            {
+                if (log)
+                    log->Printf ("Error compiling pending-items function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+            
+            errors.Clear();
+            if (!m_get_pending_items_function->WriteFunctionWrapper(exe_ctx, errors))
+            {
+                if (log)
+                    log->Printf ("Error Inserting pending-items function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+        }
+    }
+    
+    errors.Clear();
+    
+    // Now write down the argument values for this particular call.  This looks like it might be a race condition
+    // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
+    // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+    if (!m_get_pending_items_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_pending_items_arglist, errors))
+    {
+        if (log)
+            log->Printf ("Error writing pending-items function arguments: \"%s\".", errors.GetData());
+        return args_addr;
+    }
+        
+    return args_addr;
+}
+
+AppleGetPendingItemsHandler::GetPendingItemsReturnInfo
+AppleGetPendingItemsHandler::GetPendingItems (Thread &thread, addr_t queue, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
+{
+    lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+    ProcessSP process_sp (thread.CalculateProcess());
+    TargetSP target_sp (thread.CalculateTarget());
+    ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+    GetPendingItemsReturnInfo return_value;
+    return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+    return_value.items_buffer_size = 0;
+    return_value.count = 0;
+
+    error.Clear();
+
+    // Set up the arguments for a call to
+
+    // struct get_pending_items_return_values
+    // {
+    //     uint64_t pending_items_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */
+    //     uint64_t pending_items_buffer_size;   /* the size of the items buffer from libBacktraceRecording */
+    //     uint64_t count;                /* the number of items included in the queues buffer */
+    // };
+    //
+    // void  __lldb_backtrace_recording_get_pending_items
+    //                                            (struct get_pending_items_return_values *return_buffer,
+    //                                             int debug,
+    //                                             uint64_t /* dispatch_queue_t */ queue
+    //                                             void *page_to_free,
+    //                                             uint64_t page_to_free_size)
+
+    // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
+    // the inferior process.
+
+    ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+    Value return_buffer_ptr_value;
+    return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
+    return_buffer_ptr_value.SetClangType (clang_void_ptr_type);
+
+    ClangASTType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+    Value debug_value;
+    debug_value.SetValueType (Value::eValueTypeScalar);
+    debug_value.SetClangType (clang_int_type);
+
+    ClangASTType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+    Value queue_value;
+    queue_value.SetValueType (Value::eValueTypeScalar);
+    queue_value.SetClangType (clang_uint64_type);
+
+    Value page_to_free_value;
+    page_to_free_value.SetValueType (Value::eValueTypeScalar);
+    page_to_free_value.SetClangType (clang_void_ptr_type);
+
+    Value page_to_free_size_value;
+    page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
+    page_to_free_size_value.SetClangType (clang_uint64_type);
+
+
+    Mutex::Locker locker(m_get_pending_items_retbuffer_mutex);
+    if (m_get_pending_items_return_buffer_addr == LLDB_INVALID_ADDRESS)
+    {
+        addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
+        if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
+        {
+            if (log)
+                log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
+            return return_value;
+        }
+        m_get_pending_items_return_buffer_addr = bufaddr;
+    }
+
+    ValueList argument_values;
+
+    return_buffer_ptr_value.GetScalar() = m_get_pending_items_return_buffer_addr;
+    argument_values.PushValue (return_buffer_ptr_value);
+
+    debug_value.GetScalar() = 0;
+    argument_values.PushValue (debug_value);
+
+    queue_value.GetScalar() = queue;
+    argument_values.PushValue (queue_value);
+
+    if (page_to_free != LLDB_INVALID_ADDRESS)
+        page_to_free_value.GetScalar() = page_to_free;
+    else
+        page_to_free_value.GetScalar() = 0;
+    argument_values.PushValue (page_to_free_value);
+
+    page_to_free_size_value.GetScalar() = page_to_free_size;
+    argument_values.PushValue (page_to_free_size_value);
+
+    addr_t args_addr = SetupGetPendingItemsFunction (thread, argument_values);
+
+    StreamString errors;
+    ExecutionContext exe_ctx;
+    EvaluateExpressionOptions options;
+    options.SetUnwindOnError (true);
+    options.SetIgnoreBreakpoints (true);
+    options.SetStopOthers (true);
+    thread.CalculateExecutionContext (exe_ctx);
+
+    if (m_get_pending_items_function == NULL)
+    {
+        error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_get_pending_items");
+    }
+
+
+    ExecutionResults func_call_ret;
+    Value results;
+    func_call_ret =  m_get_pending_items_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+    if (func_call_ret != eExecutionCompleted || !error.Success())
+    {
+        if (log)
+            log->Printf ("Unable to call __introspection_dispatch_queue_get_pending_items(), got ExecutionResults %d, error contains %s", func_call_ret, error.AsCString(""));
+        error.SetErrorString ("Unable to call __introspection_dispatch_queue_get_pending_items() for list of queues");
+        return return_value;
+    }
+
+    return_value.items_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+    if (!error.Success() || return_value.items_buffer_ptr == LLDB_INVALID_ADDRESS)
+    {
+        return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return_value.items_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr + 8, 8, 0, error);
+
+    if (!error.Success())
+    {
+        return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return_value.count = m_process->ReadUnsignedIntegerFromMemory (m_get_pending_items_return_buffer_addr + 16, 8, 0, error);
+    if (!error.Success())
+    {
+        return_value.items_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return return_value;
+}

Added: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h?rev=200822&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h (added)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h Tue Feb  4 23:44:54 2014
@@ -0,0 +1,121 @@
+//===-- AppleGetPendingItemsHandler.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_AppleGetPendingItemsHandler_h_
+#define lldb_AppleGetPendingItemsHandler_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+// This class will insert a ClangUtilityFunction into the inferior process for
+// calling libBacktraceRecording's __introspection_dispatch_queue_get_pending_items()
+// function.  The function in the inferior will return a struct by value
+// with these members:
+//
+//     struct get_pending_items_return_values
+//     {
+//         introspection_dispatch_item_info_ref *items_buffer;
+//         uint64_t items_buffer_size;
+//         uint64_t count;
+//     };
+//
+// The items_buffer pointer is an address in the inferior program's address
+// space (items_buffer_size in size) which must be mach_vm_deallocate'd by
+// lldb.  count is the number of items that were stored in the buffer.
+//
+// The AppleGetPendingItemsHandler object should persist so that the ClangUtilityFunction
+// can be reused multiple times.
+
+namespace lldb_private
+{
+
+class AppleGetPendingItemsHandler {
+public:
+
+    AppleGetPendingItemsHandler (lldb_private::Process *process);
+
+    ~AppleGetPendingItemsHandler();
+
+    struct GetPendingItemsReturnInfo
+    {
+        lldb::addr_t    items_buffer_ptr;  /* the address of the pending items buffer from libBacktraceRecording */
+        lldb::addr_t    items_buffer_size; /* the size of the pending items buffer from libBacktraceRecording */
+        uint64_t        count;              /* the number of pending items included in the buffer */
+
+        GetPendingItemsReturnInfo () :
+            items_buffer_ptr(LLDB_INVALID_ADDRESS),
+            items_buffer_size(0),
+            count(0)
+        {}
+    };
+
+    //----------------------------------------------------------
+    /// Get the list of pending items for a given queue via a call to
+    /// __introspection_dispatch_queue_get_pending_items.  If there's a page of
+    /// memory that needs to be freed, pass in the address and size and it will
+    /// be freed before getting the list of queues.
+    ///
+    /// @param [in] thread
+    ///     The thread to run this plan on.
+    ///
+    /// @param [in] queue
+    ///     The dispatch_queue_t value for the queue of interest.
+    ///
+    /// @param [in] page_to_free
+    ///     An address of an inferior process vm page that needs to be deallocated,
+    ///     LLDB_INVALID_ADDRESS if this is not needed.
+    ///
+    /// @param [in] page_to_free_size
+    ///     The size of the vm page that needs to be deallocated if an address was
+    ///     passed in to page_to_free.
+    ///
+    /// @param [out] error
+    ///     This object will be updated with the error status / error string from any failures encountered.
+    ///
+    /// @returns
+    ///     The result of the inferior function call execution.  If there was a failure of any kind while getting
+    ///     the information, the items_buffer_ptr value will be LLDB_INVALID_ADDRESS.
+    //----------------------------------------------------------
+    GetPendingItemsReturnInfo
+    GetPendingItems (Thread &thread, lldb::addr_t queue, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
+
+
+    void
+    Detach ();
+
+private:
+
+    lldb::addr_t
+    SetupGetPendingItemsFunction (Thread &thread, ValueList &get_pending_items_arglist);
+
+    static const char *g_get_pending_items_function_name;
+    static const char *g_get_pending_items_function_code;
+
+    lldb_private::Process *m_process;
+    std::unique_ptr<ClangFunction> m_get_pending_items_function;
+    std::unique_ptr<ClangUtilityFunction> m_get_pending_items_impl_code;
+    Mutex m_get_pending_items_function_mutex;
+
+    lldb::addr_t m_get_pending_items_return_buffer_addr;
+    Mutex m_get_pending_items_retbuffer_mutex;
+
+};
+
+}  // using namespace lldb_private
+
+#endif	// lldb_AppleGetPendingItemsHandler_h_

Added: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp?rev=200822&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp (added)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp Tue Feb  4 23:44:54 2014
@@ -0,0 +1,401 @@
+//===-- AppleGetQueuesHandler.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AppleGetQueuesHandler.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "AppleThreadPlanStepThroughObjCTrampoline.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char *AppleGetQueuesHandler::g_get_current_queues_function_name = "__lldb_backtrace_recording_get_current_queues";
+const char *AppleGetQueuesHandler::g_get_current_queues_function_code = "                             \n\
+extern \"C\"                                                                                                    \n\
+{                                                                                                               \n\
+    /*                                                                                                          \n\
+     * mach defines                                                                                             \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    typedef unsigned int uint32_t;                                                                              \n\
+    typedef unsigned long long uint64_t;                                                                        \n\
+    typedef uint32_t mach_port_t;                                                                               \n\
+    typedef mach_port_t vm_map_t;                                                                               \n\
+    typedef int kern_return_t;                                                                                  \n\
+    typedef uint64_t mach_vm_address_t;                                                                         \n\
+    typedef uint64_t mach_vm_size_t;                                                                            \n\
+                                                                                                                \n\
+    mach_port_t mach_task_self ();                                                                              \n\
+    kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size);         \n\
+                                                                                                                \n\
+    /*                                                                                                          \n\
+     * libBacktraceRecording defines                                                                            \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    typedef uint32_t queue_list_scope_t;                                                                        \n\
+    typedef void *introspection_dispatch_queue_info_t;                                                          \n\
+                                                                                                                \n\
+    extern uint64_t __introspection_dispatch_get_queues (queue_list_scope_t scope,                              \n\
+                                                 introspection_dispatch_queue_info_t *returned_queues_buffer,   \n\
+                                                 uint64_t *returned_queues_buffer_size);                        \n\
+    extern int printf(const char *format, ...);                                                                 \n\
+                                                                                                                \n\
+    /*                                                                                                          \n\
+     * return type define                                                                                       \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    struct get_current_queues_return_values                                                                     \n\
+    {                                                                                                           \n\
+        uint64_t queues_buffer_ptr;    /* the address of the queues buffer from libBacktraceRecording */        \n\
+        uint64_t queues_buffer_size;   /* the size of the queues buffer from libBacktraceRecording */           \n\
+        uint64_t count;                /* the number of queues included in the queues buffer */                 \n\
+    };                                                                                                          \n\
+                                                                                                                \n\
+    void  __lldb_backtrace_recording_get_current_queues                                                         \n\
+                                               (struct get_current_queues_return_values *return_buffer,         \n\
+                                                int debug,                                                      \n\
+                                                void *page_to_free,                                             \n\
+                                                uint64_t page_to_free_size)                                     \n\
+{                                                                                                               \n\
+    if (debug)                                                                                                  \n\
+      printf (\"entering get_current_queues with args %p, %d, 0x%p, 0x%llx\\n\", return_buffer, debug, page_to_free, page_to_free_size); \n\
+    if (page_to_free != 0)                                                                                      \n\
+    {                                                                                                           \n\
+        mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
+    }                                                                                                           \n\
+                                                                                                                \n\
+    return_buffer->count = __introspection_dispatch_get_queues (                                                \n\
+                                                      /* QUEUES_WITH_ANY_ITEMS */ 2,                            \n\
+                                                      (void**)&return_buffer->queues_buffer_ptr,                \n\
+                                                      &return_buffer->queues_buffer_size);                      \n\
+    if (debug)                                                                                                  \n\
+        printf(\"result was count %lld\\n\", return_buffer->count);                                             \n\
+}                                                                                                               \n\
+}                                                                                                               \n\
+";
+
+AppleGetQueuesHandler::AppleGetQueuesHandler (Process *process) :
+    m_process (process),
+    m_get_queues_function (),
+    m_get_queues_impl_code (),
+    m_get_queues_function_mutex(),
+    m_get_queues_return_buffer_addr (LLDB_INVALID_ADDRESS),
+    m_get_queues_retbuffer_mutex()
+{
+}
+
+AppleGetQueuesHandler::~AppleGetQueuesHandler ()
+{
+}
+
+void
+AppleGetQueuesHandler::Detach ()
+{
+
+    if (m_process && m_process->IsAlive() && m_get_queues_return_buffer_addr != LLDB_INVALID_ADDRESS)
+    {
+        Mutex::Locker locker;
+        locker.TryLock (m_get_queues_retbuffer_mutex);  // Even if we don't get the lock, deallocate the buffer
+        m_process->DeallocateMemory (m_get_queues_return_buffer_addr);
+    }
+}
+
+// Construct a ClangASTType for the structure that g_get_current_queues_function_code will return by value
+// so we can extract the fields after performing the function call.
+// i.e. we are getting this struct returned to us:
+//
+//    struct get_current_queues_return_values
+//    {
+//        introspection_dispatch_queue_info_t *queues_buffer;
+//        uint64_t queues_buffer_size;
+//        uint64_t count;
+//    };
+
+
+// Compile our __lldb_backtrace_recording_get_current_queues() function (from the
+// source above in g_get_current_queues_function_code) if we don't find that function in the inferior
+// already with USE_BUILTIN_FUNCTION defined.  (e.g. this would be the case for testing.)
+//
+// Insert the __lldb_backtrace_recording_get_current_queues into the inferior process if needed.
+//
+// Write the get_queues_arglist into the inferior's memory space to prepare for the call.
+// 
+// Returns the address of the arguments written down in the inferior process, which can be used to
+// make the function call.
+
+lldb::addr_t
+AppleGetQueuesHandler::SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist)
+{
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    Address impl_code_address;
+    StreamString errors;
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+    lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+
+    // Scope for mutex locker:
+    {
+        Mutex::Locker locker(m_get_queues_function_mutex);
+        
+        // First stage is to make the ClangUtility to hold our injected function:
+
+#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
+                                // This is useful for debugging additions to the get_impl function 'cause you don't have
+                                // to bother with string-ifying the code into g_get_current_queues_function_code.
+        
+        if (USE_BUILTIN_FUNCTION)
+        {
+            ConstString our_utility_function_name("__lldb_backtrace_recording_get_current_queues");
+            SymbolContextList sc_list;
+            
+            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
+            if (sc_list.GetSize() == 1)
+            {
+                SymbolContext sc;
+                sc_list.GetContextAtIndex(0, sc);
+                if (sc.symbol != NULL)
+                    impl_code_address = sc.symbol->GetAddress();
+                    
+                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
+                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
+            }
+            else
+            {
+                //printf ("Could not find queues introspection function address.\n");
+                return args_addr;
+            }
+        }
+        else if (!m_get_queues_impl_code.get())
+        {
+            if (g_get_current_queues_function_code != NULL)
+            {
+                m_get_queues_impl_code.reset (new ClangUtilityFunction (g_get_current_queues_function_code,
+                                                             g_get_current_queues_function_name));
+                if (!m_get_queues_impl_code->Install(errors, exe_ctx))
+                {
+                    if (log)
+                        log->Printf ("Failed to install queues introspection: %s.", errors.GetData());
+                    m_get_queues_impl_code.reset();
+                    return args_addr;
+                }
+            }
+            else
+            {
+                if (log)
+                    log->Printf("No queues introspection code found.");
+                errors.Printf ("No queues introspection code found.");
+                return LLDB_INVALID_ADDRESS;
+            }
+            
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_get_queues_impl_code->StartAddress());
+        }
+        else
+        {
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_get_queues_impl_code->StartAddress());
+        }
+
+        // Next make the runner function for our implementation utility function.
+        if (!m_get_queues_function.get())
+        {
+            ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+            ClangASTType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+            m_get_queues_function.reset(new ClangFunction (thread,
+                                                     get_queues_return_type,
+                                                     impl_code_address,
+                                                     get_queues_arglist));
+            
+            errors.Clear();        
+            unsigned num_errors = m_get_queues_function->CompileFunction(errors);
+            if (num_errors)
+            {
+                if (log)
+                    log->Printf ("Error compiling get-queues function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+            
+            errors.Clear();
+            if (!m_get_queues_function->WriteFunctionWrapper(exe_ctx, errors))
+            {
+                if (log)
+                    log->Printf ("Error Inserting get-queues function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+        }
+    }
+    
+    errors.Clear();
+    
+    // Now write down the argument values for this particular call.  This looks like it might be a race condition
+    // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
+    // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+    if (!m_get_queues_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_queues_arglist, errors))
+    {
+        if (log)
+            log->Printf ("Error writing get-queues function arguments: \"%s\".", errors.GetData());
+        return args_addr;
+    }
+        
+    return args_addr;
+}
+
+AppleGetQueuesHandler::GetQueuesReturnInfo
+AppleGetQueuesHandler::GetCurrentQueues (Thread &thread, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
+{
+    lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+    ProcessSP process_sp (thread.CalculateProcess());
+    TargetSP target_sp (thread.CalculateTarget());
+    ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+    GetQueuesReturnInfo return_value;
+    return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+    return_value.queues_buffer_size = 0;
+    return_value.count = 0;
+
+    error.Clear();
+
+    // Set up the arguments for a call to
+
+    // struct get_current_queues_return_values
+    // {
+    //    uint64_t queues_buffer_ptr;    /* the address of the queues buffer from libBacktraceRecording */
+    //    uint64_t queues_buffer_size;   /* the size of the queues buffer from libBacktraceRecording */
+    //    uint64_t count;                /* the number of queues included in the queues buffer */
+    // };                                    
+    //
+    //  void
+    //    __lldb_backtrace_recording_get_current_queues
+    //                                         (struct get_current_queues_return_values *return_buffer,
+    //                                          void *page_to_free,
+    //                                          uint64_t page_to_free_size);
+
+    // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
+    // the inferior process.
+
+    ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+    Value return_buffer_ptr_value;
+    return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
+    return_buffer_ptr_value.SetClangType (clang_void_ptr_type);
+
+    ClangASTType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+    Value debug_value;
+    debug_value.SetValueType (Value::eValueTypeScalar);
+    debug_value.SetClangType (clang_int_type);
+
+    Value page_to_free_value;
+    page_to_free_value.SetValueType (Value::eValueTypeScalar);
+    page_to_free_value.SetClangType (clang_void_ptr_type);
+
+    ClangASTType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+    Value page_to_free_size_value;
+    page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
+    page_to_free_size_value.SetClangType (clang_uint64_type);
+
+
+    Mutex::Locker locker(m_get_queues_retbuffer_mutex);
+    if (m_get_queues_return_buffer_addr == LLDB_INVALID_ADDRESS)
+    {
+        addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
+        if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
+        {
+            if (log)
+                log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
+            return return_value;
+        }
+        m_get_queues_return_buffer_addr = bufaddr;
+    }
+
+    ValueList argument_values;
+
+    return_buffer_ptr_value.GetScalar() = m_get_queues_return_buffer_addr;
+    argument_values.PushValue (return_buffer_ptr_value);
+
+    debug_value.GetScalar() = 0;
+    argument_values.PushValue (debug_value);
+
+    if (page_to_free != LLDB_INVALID_ADDRESS)
+        page_to_free_value.GetScalar() = page_to_free;
+    else
+        page_to_free_value.GetScalar() = 0;
+    argument_values.PushValue (page_to_free_value);
+
+    page_to_free_size_value.GetScalar() = page_to_free_size;
+    argument_values.PushValue (page_to_free_size_value);
+
+    addr_t args_addr = SetupGetQueuesFunction (thread, argument_values);
+
+    if (m_get_queues_function == NULL)
+    {
+        error.SetErrorString ("Unable to compile function to call __introspection_dispatch_get_queues");
+    }
+
+    StreamString errors;
+    ExecutionContext exe_ctx;
+    EvaluateExpressionOptions options;
+    options.SetUnwindOnError (true);
+    options.SetIgnoreBreakpoints (true);
+    options.SetStopOthers (true);
+    thread.CalculateExecutionContext (exe_ctx);
+
+    ExecutionResults func_call_ret;
+    Value results;
+    func_call_ret =  m_get_queues_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+    if (func_call_ret != eExecutionCompleted || !error.Success())
+    {
+        if (log)
+            log->Printf ("Unable to call introspection_get_dispatch_queues(), got ExecutionResults %d, error contains %s", func_call_ret, error.AsCString(""));
+        error.SetErrorString ("Unable to call introspection_get_dispatch_queues() for list of queues");
+        return return_value;
+    }
+
+    return_value.queues_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+    if (!error.Success() || return_value.queues_buffer_ptr == LLDB_INVALID_ADDRESS)
+    {
+        return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return_value.queues_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr + 8, 8, 0, error);
+
+    if (!error.Success())
+    {
+        return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return_value.count = m_process->ReadUnsignedIntegerFromMemory (m_get_queues_return_buffer_addr + 16, 8, 0, error);
+    if (!error.Success())
+    {
+        return_value.queues_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return return_value;
+}

Added: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h?rev=200822&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h (added)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h Tue Feb  4 23:44:54 2014
@@ -0,0 +1,118 @@
+//===-- AppleGetQueuesHandler.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_AppleGetQueuesHandler_h_
+#define lldb_AppleGetQueuesHandler_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+// This class will insert a ClangUtilityFunction into the inferior process for
+// calling libBacktraceRecording's introspection_get_dispatch_queues()
+// function.  The function in the inferior will return a struct by value
+// with these members:
+//
+//     struct get_current_queues_return_values
+//     {
+//         introspection_dispatch_queue_info_t *queues_buffer;
+//         uint64_t queues_buffer_size;
+//         uint64_t count;
+//     };
+//
+// The queues_buffer pointer is an address in the inferior program's address
+// space (queues_buffer_size in size) which must be mach_vm_deallocate'd by
+// lldb.  count is the number of queues that were stored in the buffer.
+//
+// The AppleGetQueuesHandler object should persist so that the ClangUtilityFunction
+// can be reused multiple times.
+
+namespace lldb_private
+{
+
+class AppleGetQueuesHandler {
+public:
+
+    AppleGetQueuesHandler (lldb_private::Process *process);
+
+    ~AppleGetQueuesHandler();
+
+    struct GetQueuesReturnInfo
+    {
+        lldb::addr_t    queues_buffer_ptr;  /* the address of the queues buffer from libBacktraceRecording */
+        lldb::addr_t    queues_buffer_size; /* the size of the queues buffer from libBacktraceRecording */
+        uint64_t        count;              /* the number of queues included in the queues buffer */
+
+        GetQueuesReturnInfo() :
+            queues_buffer_ptr(LLDB_INVALID_ADDRESS),
+            queues_buffer_size(0),
+            count(0)
+        {}
+    };
+
+    //----------------------------------------------------------
+    /// Get the list of queues that exist (with any active or pending items) via
+    /// a call to introspection_get_dispatch_queues().  If there's a page of
+    /// memory that needs to be freed, pass in the address and size and it will
+    /// be freed before getting the list of queues.
+    ///
+    /// @param [in] thread
+    ///     The thread to run this plan on.
+    ///
+    /// @param [in] page_to_free
+    ///     An address of an inferior process vm page that needs to be deallocated,
+    ///     LLDB_INVALID_ADDRESS if this is not needed.
+    ///
+    /// @param [in] page_to_free_size
+    ///     The size of the vm page that needs to be deallocated if an address was
+    ///     passed in to page_to_free.
+    ///
+    /// @param [out] error
+    ///     This object will be updated with the error status / error string from any failures encountered.
+    ///
+    /// @returns
+    ///     The result of the inferior function call execution.  If there was a failure of any kind while getting
+    ///     the information, the queues_buffer_ptr value will be LLDB_INVALID_ADDRESS.
+    //----------------------------------------------------------
+    GetQueuesReturnInfo
+    GetCurrentQueues (Thread &thread, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
+
+
+    void
+    Detach ();
+
+private:
+
+    lldb::addr_t
+    SetupGetQueuesFunction (Thread &thread, ValueList &get_queues_arglist);
+
+    static const char *g_get_current_queues_function_name;
+    static const char *g_get_current_queues_function_code;
+
+    lldb_private::Process *m_process;
+    std::unique_ptr<ClangFunction> m_get_queues_function;
+    std::unique_ptr<ClangUtilityFunction> m_get_queues_impl_code;
+    Mutex m_get_queues_function_mutex;
+
+    lldb::addr_t m_get_queues_return_buffer_addr;
+    Mutex m_get_queues_retbuffer_mutex;
+
+};
+
+}  // using namespace lldb_private
+
+#endif	// lldb_AppleGetQueuesHandler_h_

Added: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp?rev=200822&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp (added)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp Tue Feb  4 23:44:54 2014
@@ -0,0 +1,385 @@
+//===-- AppleGetThreadItemInfoHandler.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AppleGetThreadItemInfoHandler.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_name = "__lldb_backtrace_recording_get_thread_item_info";
+const char *AppleGetThreadItemInfoHandler::g_get_thread_item_info_function_code = "                                  \n\
+extern \"C\"                                                                                                    \n\
+{                                                                                                               \n\
+    /*                                                                                                          \n\
+     * mach defines                                                                                             \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    typedef unsigned int uint32_t;                                                                              \n\
+    typedef unsigned long long uint64_t;                                                                        \n\
+    typedef uint32_t mach_port_t;                                                                               \n\
+    typedef mach_port_t vm_map_t;                                                                               \n\
+    typedef int kern_return_t;                                                                                  \n\
+    typedef uint64_t mach_vm_address_t;                                                                         \n\
+    typedef uint64_t mach_vm_size_t;                                                                            \n\
+                                                                                                                \n\
+    mach_port_t mach_task_self ();                                                                              \n\
+    kern_return_t mach_vm_deallocate (vm_map_t target, mach_vm_address_t address, mach_vm_size_t size);         \n\
+                                                                                                                \n\
+    typedef void *pthread_t;                                                                                    \n\
+    extern int printf(const char *format, ...);                                                                 \n\
+    extern pthread_t pthread_self(void);                                                                        \n\
+                                                                                                                \n\
+    /*                                                                                                          \n\
+     * libBacktraceRecording defines                                                                            \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    typedef uint32_t queue_list_scope_t;                                                                        \n\
+    typedef void *dispatch_queue_t;                                                                             \n\
+    typedef void *introspection_dispatch_queue_info_t;                                                          \n\
+    typedef void *introspection_dispatch_item_info_ref;                                                         \n\
+                                                                                                                \n\
+    extern void __introspection_dispatch_thread_get_item_info (pthread_t thread,                                \n\
+                                                 introspection_dispatch_item_info_ref *returned_queues_buffer,  \n\
+                                                 uint64_t *returned_queues_buffer_size);                        \n\
+                                                                                                                \n\
+    /*                                                                                                          \n\
+     * return type define                                                                                       \n\
+     */                                                                                                         \n\
+                                                                                                                \n\
+    struct get_thread_item_info_return_values                                                                      \n\
+    {                                                                                                           \n\
+        uint64_t item_info_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */  \n\
+        uint64_t item_info_buffer_size;   /* the size of the items buffer from libBacktraceRecording */     \n\
+    };                                                                                                          \n\
+                                                                                                                \n\
+    void  __lldb_backtrace_recording_get_thread_item_info                                                          \n\
+                                               (struct get_thread_item_info_return_values *return_buffer,          \n\
+                                                int debug,                                                      \n\
+                                                void *page_to_free,                                             \n\
+                                                uint64_t page_to_free_size)                                     \n\
+{                                                                                                               \n\
+    void *pthread_id = pthread_self ();                                                                         \n\
+    if (debug)                                                                                                  \n\
+      printf (\"entering get_thread_item_info with args return_buffer == %p, debug == %d, pthread id == 0x%llx, page_to_free == %p, page_to_free_size == 0x%llx\\n\", return_buffer, debug, (uint64_t) pthread_id, page_to_free, page_to_free_size); \n\
+    if (page_to_free != 0)                                                                                      \n\
+    {                                                                                                           \n\
+        mach_vm_deallocate (mach_task_self(), (mach_vm_address_t) page_to_free, (mach_vm_size_t) page_to_free_size); \n\
+    }                                                                                                           \n\
+                                                                                                                \n\
+    __introspection_dispatch_thread_get_item_info (pthread_id,                                                  \n\
+                                                  (void**)&return_buffer->item_info_buffer_ptr,                 \n\
+                                                  &return_buffer->item_info_buffer_size);                       \n\
+}                                                                                                               \n\
+}                                                                                                               \n\
+";
+
+AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler (Process *process) :
+    m_process (process),
+    m_get_thread_item_info_function (),
+    m_get_thread_item_info_impl_code (),
+    m_get_thread_item_info_function_mutex(),
+    m_get_thread_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
+    m_get_thread_item_info_retbuffer_mutex()
+{
+}
+
+AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler ()
+{
+}
+
+void
+AppleGetThreadItemInfoHandler::Detach ()
+{
+
+    if (m_process && m_process->IsAlive() && m_get_thread_item_info_return_buffer_addr != LLDB_INVALID_ADDRESS)
+    {
+        Mutex::Locker locker;
+        locker.TryLock (m_get_thread_item_info_retbuffer_mutex);  // Even if we don't get the lock, deallocate the buffer
+        m_process->DeallocateMemory (m_get_thread_item_info_return_buffer_addr);
+    }
+}
+
+// Compile our __lldb_backtrace_recording_get_thread_item_info() function (from the
+// source above in g_get_thread_item_info_function_code) if we don't find that function in the inferior
+// already with USE_BUILTIN_FUNCTION defined.  (e.g. this would be the case for testing.)
+//
+// Insert the __lldb_backtrace_recording_get_thread_item_info into the inferior process if needed.
+//
+// Write the get_thread_item_info_arglist into the inferior's memory space to prepare for the call.
+// 
+// Returns the address of the arguments written down in the inferior process, which can be used to
+// make the function call.
+
+lldb::addr_t
+AppleGetThreadItemInfoHandler::SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist)
+{
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    Address impl_code_address;
+    StreamString errors;
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+    lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+
+    // Scope for mutex locker:
+    {
+        Mutex::Locker locker(m_get_thread_item_info_function_mutex);
+        
+        // First stage is to make the ClangUtility to hold our injected function:
+
+#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
+                                // This is useful for debugging additions to the get_impl function 'cause you don't have
+                                // to bother with string-ifying the code into g_get_thread_item_info_function_code.
+        
+        if (USE_BUILTIN_FUNCTION)
+        {
+            ConstString our_utility_function_name("__lldb_backtrace_recording_get_thread_item_info");
+            SymbolContextList sc_list;
+            
+            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
+            if (sc_list.GetSize() == 1)
+            {
+                SymbolContext sc;
+                sc_list.GetContextAtIndex(0, sc);
+                if (sc.symbol != NULL)
+                    impl_code_address = sc.symbol->GetAddress();
+                    
+                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
+                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
+            }
+            else
+            {
+                //printf ("Could not find queues introspection function address.\n");
+                return args_addr;
+            }
+        }
+        else if (!m_get_thread_item_info_impl_code.get())
+        {
+            if (g_get_thread_item_info_function_code != NULL)
+            {
+                m_get_thread_item_info_impl_code.reset (new ClangUtilityFunction (g_get_thread_item_info_function_code,
+                                                             g_get_thread_item_info_function_name));
+                if (!m_get_thread_item_info_impl_code->Install(errors, exe_ctx))
+                {
+                    if (log)
+                        log->Printf ("Failed to install get-thread-item-info introspection: %s.", errors.GetData());
+                    m_get_thread_item_info_impl_code.reset();
+                    return args_addr;
+                }
+            }
+            else
+            {
+                if (log)
+                    log->Printf("No get-thread-item-info introspection code found.");
+                errors.Printf ("No get-thread-item-info introspection code found.");
+                return LLDB_INVALID_ADDRESS;
+            }
+            
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_get_thread_item_info_impl_code->StartAddress());
+        }
+        else
+        {
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_get_thread_item_info_impl_code->StartAddress());
+        }
+
+        // Next make the runner function for our implementation utility function.
+        if (!m_get_thread_item_info_function.get())
+        {
+            ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+            ClangASTType get_thread_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+            m_get_thread_item_info_function.reset(new ClangFunction (thread,
+                                                     get_thread_item_info_return_type,
+                                                     impl_code_address,
+                                                     get_thread_item_info_arglist));
+            
+            errors.Clear();        
+            unsigned num_errors = m_get_thread_item_info_function->CompileFunction(errors);
+            if (num_errors)
+            {
+                if (log)
+                    log->Printf ("Error compiling get-thread-item-info function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+            
+            errors.Clear();
+            if (!m_get_thread_item_info_function->WriteFunctionWrapper(exe_ctx, errors))
+            {
+                if (log)
+                    log->Printf ("Error Inserting get-thread-item-info function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+        }
+    }
+    
+    errors.Clear();
+    
+    // Now write down the argument values for this particular call.  This looks like it might be a race condition
+    // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
+    // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+    if (!m_get_thread_item_info_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_thread_item_info_arglist, errors))
+    {
+        if (log)
+            log->Printf ("Error writing get-thread-item-info function arguments: \"%s\".", errors.GetData());
+        return args_addr;
+    }
+        
+    return args_addr;
+}
+
+AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo
+AppleGetThreadItemInfoHandler::GetThreadItemInfo (Thread &thread, addr_t page_to_free, uint64_t page_to_free_size, Error &error)
+{
+    lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0);
+    ProcessSP process_sp (thread.CalculateProcess());
+    TargetSP target_sp (thread.CalculateTarget());
+    ClangASTContext *clang_ast_context = target_sp->GetScratchClangASTContext();
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
+
+    GetThreadItemInfoReturnInfo return_value;
+    return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+    return_value.item_buffer_size = 0;
+
+    error.Clear();
+
+    // Set up the arguments for a call to
+
+    // struct get_thread_item_info_return_values
+    // {
+    //     uint64_t item_info_buffer_ptr;    /* the address of the items buffer from libBacktraceRecording */
+    //     uint64_t item_info_buffer_size;   /* the size of the items buffer from libBacktraceRecording */
+    // };
+    //
+    // void  __lldb_backtrace_recording_get_thread_item_info
+    //                                            (struct get_thread_item_info_return_values *return_buffer,
+    //                                             int debug,
+    //                                             void *page_to_free,
+    //                                             uint64_t page_to_free_size)
+
+    // Where the return_buffer argument points to a 24 byte region of memory already allocated by lldb in
+    // the inferior process.
+
+    ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+    Value return_buffer_ptr_value;
+    return_buffer_ptr_value.SetValueType (Value::eValueTypeScalar);
+    return_buffer_ptr_value.SetClangType (clang_void_ptr_type);
+
+    ClangASTType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
+    Value debug_value;
+    debug_value.SetValueType (Value::eValueTypeScalar);
+    debug_value.SetClangType (clang_int_type);
+
+    Value page_to_free_value;
+    page_to_free_value.SetValueType (Value::eValueTypeScalar);
+    page_to_free_value.SetClangType (clang_void_ptr_type);
+
+    ClangASTType clang_uint64_type = clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
+    Value page_to_free_size_value;
+    page_to_free_size_value.SetValueType (Value::eValueTypeScalar);
+    page_to_free_size_value.SetClangType (clang_uint64_type);
+
+
+    Mutex::Locker locker(m_get_thread_item_info_retbuffer_mutex);
+    if (m_get_thread_item_info_return_buffer_addr == LLDB_INVALID_ADDRESS)
+    {
+        addr_t bufaddr = process_sp->AllocateMemory (32, ePermissionsReadable | ePermissionsWritable, error);
+        if (!error.Success() || bufaddr == LLDB_INVALID_ADDRESS)
+        {
+            if (log)
+                log->Printf ("Failed to allocate memory for return buffer for get current queues func call");
+            return return_value;
+        }
+        m_get_thread_item_info_return_buffer_addr = bufaddr;
+    }
+
+    ValueList argument_values;
+
+    return_buffer_ptr_value.GetScalar() = m_get_thread_item_info_return_buffer_addr;
+    argument_values.PushValue (return_buffer_ptr_value);
+
+    debug_value.GetScalar() = 0;
+    argument_values.PushValue (debug_value);
+
+    if (page_to_free != LLDB_INVALID_ADDRESS)
+        page_to_free_value.GetScalar() = page_to_free;
+    else
+        page_to_free_value.GetScalar() = 0;
+    argument_values.PushValue (page_to_free_value);
+
+    page_to_free_size_value.GetScalar() = page_to_free_size;
+    argument_values.PushValue (page_to_free_size_value);
+
+    addr_t args_addr = SetupGetThreadItemInfoFunction (thread, argument_values);
+
+    StreamString errors;
+    ExecutionContext exe_ctx;
+    EvaluateExpressionOptions options;
+    options.SetUnwindOnError (true);
+    options.SetIgnoreBreakpoints (true);
+    options.SetStopOthers (true);
+    thread.CalculateExecutionContext (exe_ctx);
+
+    if (m_get_thread_item_info_function == NULL)
+    {
+        error.SetErrorString ("Unable to compile function to call __introspection_dispatch_thread_get_item_info");
+        return return_value;
+    }
+
+
+    ExecutionResults func_call_ret;
+    Value results;
+    func_call_ret =  m_get_thread_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+    if (func_call_ret != eExecutionCompleted || !error.Success())
+    {
+        if (log)
+            log->Printf ("Unable to call __introspection_dispatch_thread_get_item_info(), got ExecutionResults %d, error contains %s", func_call_ret, error.AsCString(""));
+        error.SetErrorString ("Unable to call __introspection_dispatch_thread_get_item_info() for list of queues");
+        return return_value;
+    }
+
+    return_value.item_buffer_ptr = m_process->ReadUnsignedIntegerFromMemory (m_get_thread_item_info_return_buffer_addr, 8, LLDB_INVALID_ADDRESS, error);
+    if (!error.Success() || return_value.item_buffer_ptr == LLDB_INVALID_ADDRESS)
+    {
+        return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return_value.item_buffer_size = m_process->ReadUnsignedIntegerFromMemory (m_get_thread_item_info_return_buffer_addr + 8, 8, 0, error);
+
+    if (!error.Success())
+    {
+        return_value.item_buffer_ptr = LLDB_INVALID_ADDRESS;
+        return return_value;
+    }
+
+    return return_value;
+}

Added: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h?rev=200822&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h (added)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h Tue Feb  4 23:44:54 2014
@@ -0,0 +1,115 @@
+//===-- AppleGetThreadItemInfoHandler.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_AppleGetThreadItemInfoHandler_h_
+#define lldb_AppleGetThreadItemInfoHandler_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Symbol/ClangASTType.h"
+
+// This class will insert a ClangUtilityFunction into the inferior process for
+// calling libBacktraceRecording's __introspection_dispatch_thread_get_item_info()
+// function.  The function in the inferior will return a struct by value
+// with these members:
+//
+//     struct get_thread_item_info_return_values
+//     {
+//         introspection_dispatch_item_info_ref *item_buffer;
+//         uint64_t item_buffer_size;
+//     };
+//
+// The item_buffer pointer is an address in the inferior program's address
+// space (item_buffer_size in size) which must be mach_vm_deallocate'd by
+// lldb.  
+//
+// The AppleGetThreadItemInfoHandler object should persist so that the ClangUtilityFunction
+// can be reused multiple times.
+
+namespace lldb_private
+{
+
+class AppleGetThreadItemInfoHandler {
+public:
+
+    AppleGetThreadItemInfoHandler (lldb_private::Process *process);
+
+    ~AppleGetThreadItemInfoHandler();
+
+    struct GetThreadItemInfoReturnInfo
+    {
+        lldb::addr_t    item_buffer_ptr;  /* the address of the item buffer from libBacktraceRecording */
+        lldb::addr_t    item_buffer_size; /* the size of the item buffer from libBacktraceRecording */
+
+        GetThreadItemInfoReturnInfo() :
+            item_buffer_ptr(LLDB_INVALID_ADDRESS),
+            item_buffer_size(0)
+        {}
+    };
+
+    //----------------------------------------------------------
+    /// Get the information about a work item by calling
+    /// __introspection_dispatch_thread_get_item_info.  If there's a page of
+    /// memory that needs to be freed, pass in the address and size and it will
+    /// be freed before getting the list of queues.
+    ///
+    /// @param [in] thread
+    ///     The thread to run this plan on.
+    ///
+    /// @param [in] page_to_free
+    ///     An address of an inferior process vm page that needs to be deallocated,
+    ///     LLDB_INVALID_ADDRESS if this is not needed.
+    ///
+    /// @param [in] page_to_free_size
+    ///     The size of the vm page that needs to be deallocated if an address was
+    ///     passed in to page_to_free.
+    ///
+    /// @param [out] error
+    ///     This object will be updated with the error status / error string from any failures encountered.
+    ///
+    /// @returns
+    ///     The result of the inferior function call execution.  If there was a failure of any kind while getting
+    ///     the information, the item_buffer_ptr value will be LLDB_INVALID_ADDRESS.
+    //----------------------------------------------------------
+    GetThreadItemInfoReturnInfo
+    GetThreadItemInfo (Thread &thread, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Error &error);
+
+
+    void
+    Detach ();
+
+private:
+
+    lldb::addr_t
+    SetupGetThreadItemInfoFunction (Thread &thread, ValueList &get_thread_item_info_arglist);
+
+    static const char *g_get_thread_item_info_function_name;
+    static const char *g_get_thread_item_info_function_code;
+
+    lldb_private::Process *m_process;
+    std::unique_ptr<ClangFunction> m_get_thread_item_info_function;
+    std::unique_ptr<ClangUtilityFunction> m_get_thread_item_info_impl_code;
+    Mutex m_get_thread_item_info_function_mutex;
+
+    lldb::addr_t m_get_thread_item_info_return_buffer_addr;
+    Mutex m_get_thread_item_info_retbuffer_mutex;
+
+};
+
+}  // using namespace lldb_private
+
+#endif	// lldb_AppleGetThreadItemInfoHandler_h_

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt Tue Feb  4 23:44:54 2014
@@ -1,5 +1,9 @@
 set(LLVM_NO_RTTI 1)
 
 add_lldb_library(lldbPluginSystemRuntimeMacOSX
+  AppleGetItemInfoHandler.cpp
+  AppleGetPendingItemsHandler.cpp
+  AppleGetQueuesHandler.cpp
+  AppleGetThreadItemInfoHandler.cpp
   SystemRuntimeMacOSX.cpp
   )

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp Tue Feb  4 23:44:54 2014
@@ -26,6 +26,8 @@
 #include "lldb/Target/QueueList.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Target/Process.h"
+
 
 #include "SystemRuntimeMacOSX.h"
 
@@ -82,9 +84,17 @@ SystemRuntimeMacOSX::CreateInstance (Pro
 SystemRuntimeMacOSX::SystemRuntimeMacOSX (Process* process) :
     SystemRuntime(process),
     m_break_id(LLDB_INVALID_BREAK_ID),
-    m_mutex(Mutex::eMutexTypeRecursive)
+    m_mutex(Mutex::eMutexTypeRecursive),
+    m_get_queues_handler(process),
+    m_get_pending_items_handler(process),
+    m_get_item_info_handler(process),
+    m_get_thread_item_info_handler(process),
+    m_page_to_free(LLDB_INVALID_ADDRESS),
+    m_page_to_free_size(0),
+    m_lib_backtrace_recording_info(),
+    m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
+    m_libdispatch_offsets()
 {
-    m_ldi_header.initialized = 0;
 }
 
 //----------------------------------------------------------------------
@@ -95,6 +105,15 @@ SystemRuntimeMacOSX::~SystemRuntimeMacOS
     Clear (true);
 }
 
+void
+SystemRuntimeMacOSX::Detach ()
+{
+        m_get_queues_handler.Detach();
+        m_get_pending_items_handler.Detach();
+        m_get_item_info_handler.Detach();
+        m_get_thread_item_info_handler.Detach();
+}
+
 //----------------------------------------------------------------------
 // Clear out the state of this class.
 //----------------------------------------------------------------------
@@ -109,213 +128,336 @@ SystemRuntimeMacOSX::Clear (bool clear_p
     if (clear_process)
         m_process = NULL;
     m_break_id = LLDB_INVALID_BREAK_ID;
-    m_ldi_header.initialized = 0;
 }
 
 
-void 
-SystemRuntimeMacOSX::DidAttach ()
-{
-}
-
-void 
-SystemRuntimeMacOSX::DidLaunch ()
+std::string
+SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress (addr_t dispatch_qaddr)
 {
+    std::string dispatch_queue_name;
+    if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
+        return "";
+
+    ReadLibdispatchOffsets ();
+    if (m_libdispatch_offsets.IsValid ())
+    {
+        // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a thread -
+        // deref it to get the address of the dispatch_queue_t structure for this thread's 
+        // queue.
+        Error error;
+        addr_t dispatch_queue_addr = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
+        if (error.Success())
+        {
+            if (m_libdispatch_offsets.dqo_version >= 4)
+            {
+                // libdispatch versions 4+, pointer to dispatch name is in the
+                // queue structure.
+                addr_t pointer_to_label_address = dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
+                addr_t label_addr = m_process->ReadPointerFromMemory (pointer_to_label_address, error);
+                if (error.Success())
+                {
+                    m_process->ReadCStringFromMemory (label_addr, dispatch_queue_name, error);
+                }
+            }
+            else
+            {
+                // libdispatch versions 1-3, dispatch name is a fixed width char array
+                // in the queue structure.
+                addr_t label_addr = dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
+                dispatch_queue_name.resize (m_libdispatch_offsets.dqo_label_size, '\0');
+                size_t bytes_read = m_process->ReadMemory (label_addr, &dispatch_queue_name[0], m_libdispatch_offsets.dqo_label_size, error);
+                if (bytes_read < m_libdispatch_offsets.dqo_label_size)
+                    dispatch_queue_name.erase (bytes_read);
+            }
+        }
+    }
+    return dispatch_queue_name;
 }
 
-void
-SystemRuntimeMacOSX::ModulesDidLoad (ModuleList &module_list)
+lldb::queue_id_t
+SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr)
 {
-}
+    queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
 
-bool
-SystemRuntimeMacOSX::LdiHeadersInitialized ()
-{
-    ParseLdiHeaders();
-    return m_ldi_header.initialized;
-}
+    if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
+        return queue_id;
 
-void
-SystemRuntimeMacOSX::ParseLdiHeaders ()
-{
-    if (m_ldi_header.initialized)
-        return;
-    static ConstString ldi_header_symbol ("ldi_infos");
-    SymbolContextList sc_list;
-    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (ldi_header_symbol, eSymbolTypeData, sc_list) > 0)
+    ReadLibdispatchOffsets ();
+    if (m_libdispatch_offsets.IsValid ())
     {
-        SymbolContext sc;
-        sc_list.GetContextAtIndex (0, sc);
-        AddressRange addr_range;
-        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
-
+        // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a thread -
+        // deref it to get the address of the dispatch_queue_t structure for this thread's 
+        // queue.
         Error error;
-        Address ldi_header_addr = addr_range.GetBaseAddress();
-        uint8_t version_buf[6];   // version, ldi_header_size, initialized fields
-        DataExtractor data (version_buf, sizeof(version_buf), m_process->GetByteOrder(), m_process->GetAddressByteSize());
-        const size_t count = sizeof (version_buf);
-        const bool prefer_file_cache = false;
-        if (m_process->GetTarget().ReadMemory (ldi_header_addr, prefer_file_cache, version_buf, count, error) == sizeof (version_buf))
-        {
-            int version, initialized, ldi_header_size;
-            offset_t offset = 0;
-            version = data.GetU16(&offset);
-            ldi_header_size = data.GetU16(&offset);
-            initialized = data.GetU16(&offset);
-            if (initialized)
-            {
-                DataBufferHeap ldi_header (ldi_header_size, 0);
-                DataExtractor ldi_extractor (ldi_header.GetBytes(), ldi_header.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
-                if (m_process->GetTarget().ReadMemory (ldi_header_addr, prefer_file_cache, ldi_header.GetBytes(), ldi_header.GetByteSize(), error) == ldi_header.GetByteSize())
-                {
-                    offset = 0;
-                    m_ldi_header.version = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.ldi_header_size = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.initialized = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.queue_size = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_size = ldi_extractor.GetU16(&offset);
-
-                    // 6 bytes of padding here
-                    offset += 6;
-
-                    m_ldi_header.queues_head_ptr_address = ldi_extractor.GetU64(&offset);
-                    m_ldi_header.items_head_ptr_address = ldi_extractor.GetU64(&offset);
-
-                    m_ldi_header.queue_offsets.next = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.queue_offsets.prev = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.queue_offsets.queue_id = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.queue_offsets.current_item_ptr = ldi_extractor.GetU16(&offset);
-
-                    m_ldi_header.item_offsets.next = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.prev = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.type = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.identifier = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.stop_id = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.backtrace_length = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.backtrace_ptr = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.thread_name_ptr = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.queue_name_ptr = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.unique_thread_id = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.pthread_id = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.enqueueing_thread_dispatch_queue_t = ldi_extractor.GetU16(&offset);
-                    m_ldi_header.item_offsets.enqueueing_thread_dispatch_block_ptr = ldi_extractor.GetU16(&offset);
-
-                    if (ldi_header.GetByteSize () > offset)
-                    {
-                        m_ldi_header.item_offsets.queue_id_from_thread_info = ldi_extractor.GetU16(&offset);
-                    }
-                    else
-                    {
-                        m_ldi_header.item_offsets.queue_id_from_thread_info = 0xffff;
-                    }
-                }
+        uint64_t dispatch_queue_addr = m_process->ReadPointerFromMemory (dispatch_qaddr, error);
+        if (error.Success())
+        {
+            addr_t serialnum_address = dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
+            queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory (serialnum_address, m_libdispatch_offsets.dqo_serialnum_size, LLDB_INVALID_QUEUE_ID, error);
+            if (error.Success())
+            {
+                queue_id = serialnum;
             }
         }
     }
+
+    return queue_id;
 }
 
-lldb::addr_t
-SystemRuntimeMacOSX::GetQueuesHead ()
+
+void
+SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress ()
 {
-    if (!LdiHeadersInitialized())
-        return LLDB_INVALID_ADDRESS;
+    if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
+        return;
 
-    Error error;
-    addr_t queues_head = m_process->ReadPointerFromMemory (m_ldi_header.queues_head_ptr_address, error);
-    if (error.Success() == false || queues_head == LLDB_INVALID_ADDRESS || queues_head == 0)
-        return LLDB_INVALID_ADDRESS;
+    static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
+    const Symbol *dispatch_queue_offsets_symbol = NULL;
 
-    return queues_head;
+    // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6 ("Snow Leopard")
+    ModuleSpec libSystem_module_spec (FileSpec("libSystem.B.dylib", false));
+    ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule (libSystem_module_spec));
+    if (module_sp)
+        dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
+    
+    // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and later
+    if (dispatch_queue_offsets_symbol == NULL)
+    {
+        ModuleSpec libdispatch_module_spec (FileSpec("libdispatch.dylib", false));
+        module_sp = m_process->GetTarget().GetImages().FindFirstModule (libdispatch_module_spec);
+        if (module_sp)
+            dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
+    }
+    if (dispatch_queue_offsets_symbol)
+        m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget());
 }
 
-lldb::addr_t
-SystemRuntimeMacOSX::GetItemsHead ()
+void
+SystemRuntimeMacOSX::ReadLibdispatchOffsets ()
 {
-    if (!LdiHeadersInitialized())
-        return LLDB_INVALID_ADDRESS;
+    if (m_libdispatch_offsets.IsValid())
+        return;
+
+    ReadLibdispatchOffsetsAddress ();
+
+    uint8_t memory_buffer[sizeof (struct LibdispatchOffsets)];
+    DataExtractor data (memory_buffer, 
+                        sizeof(memory_buffer), 
+                        m_process->GetByteOrder(), 
+                        m_process->GetAddressByteSize());
 
     Error error;
-    addr_t items_head = m_process->ReadPointerFromMemory (m_ldi_header.items_head_ptr_address, error);
-    if (error.Success() == false || items_head == LLDB_INVALID_ADDRESS || items_head == 0)
-        return LLDB_INVALID_ADDRESS;
+    if (m_process->ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer))
+    {
+        lldb::offset_t data_offset = 0;
 
-    return items_head;
+        // The struct LibdispatchOffsets is a series of uint16_t's - extract them all
+        // in one big go.
+        data.GetU16 (&data_offset, &m_libdispatch_offsets.dqo_version, sizeof (struct LibdispatchOffsets) / sizeof (uint16_t));
+    }
 }
 
-addr_t
-SystemRuntimeMacOSX::GetThreadCreatorItem (ThreadSP thread_sp)
+
+ThreadSP
+SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP real_thread, ConstString type)
 {
-    addr_t enqueued_item_ptr = thread_sp->GetExtendedBacktraceToken();
-    if (enqueued_item_ptr == LLDB_INVALID_ADDRESS)
+    ThreadSP originating_thread_sp;
+    if (BacktraceRecordingHeadersInitialized() && type == ConstString ("libdispatch"))
     {
-        if (thread_sp->GetQueueID() == LLDB_INVALID_QUEUE_ID || thread_sp->GetQueueID() == 0)
-            return LLDB_INVALID_ADDRESS;
-    
         Error error;
-        uint64_t this_thread_queue_id = thread_sp->GetQueueID();
-    
-        addr_t queues_head = GetQueuesHead();
-        if (queues_head == LLDB_INVALID_ADDRESS)
-            return LLDB_INVALID_ADDRESS;
-    
-        // Step through the queues_head linked list looking for a queue matching this thread, if any
-        uint64_t queue_obj_ptr = queues_head;
-        enqueued_item_ptr = LLDB_INVALID_ADDRESS;
-    
-        while (queue_obj_ptr != 0)
+
+        // real_thread is either an actual, live thread (in which case we need to call into
+        // libBacktraceRecording to find its originator) or it is an extended backtrace itself,
+        // in which case we get the token from it and call into libBacktraceRecording to find
+        // the originator of that token.
+
+        if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS)
+        {
+            originating_thread_sp = GetExtendedBacktraceFromItemRef (real_thread->GetExtendedBacktraceToken());
+        }
+        else
         {
-            uint64_t queue_id = m_process->ReadUnsignedIntegerFromMemory (queue_obj_ptr + m_ldi_header.queue_offsets.queue_id, 8, LLDB_INVALID_ADDRESS, error);
-            if (error.Success() && queue_id != LLDB_INVALID_ADDRESS)
+            AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret = m_get_thread_item_info_handler.GetThreadItemInfo (*real_thread.get(), m_page_to_free, m_page_to_free_size, error);
+            if (ret.item_buffer_ptr != 0 &&  ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
             {
-                if (queue_id == this_thread_queue_id)
+                DataBufferHeap data (ret.item_buffer_size, 0);
+                if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
                 {
-                    enqueued_item_ptr = m_process->ReadPointerFromMemory (queue_obj_ptr + m_ldi_header.queue_offsets.current_item_ptr, error);
-                    break;
+                    DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
+                    ItemInfo item = ExtractItemInfoFromBuffer (extractor);
+                    bool stop_id_is_valid = true;
+                    if (item.stop_id == 0)
+                        stop_id_is_valid = false;
+                    originating_thread_sp.reset (new HistoryThread (*m_process,
+                                                                    item.enqueuing_thread_id,
+                                                                    item.enqueuing_callstack,
+                                                                    item.stop_id,
+                                                                    stop_id_is_valid));
+                    originating_thread_sp->SetExtendedBacktraceToken (item.item_that_enqueued_this);
+                    originating_thread_sp->SetQueueName (item.enqueuing_queue_label.c_str());
+                    originating_thread_sp->SetQueueID (item.enqueuing_queue_serialnum);
+//                    originating_thread_sp->SetThreadName (item.enqueuing_thread_label.c_str());
                 }
             }
-            queue_obj_ptr = m_process->ReadPointerFromMemory (queue_obj_ptr + m_ldi_header.queue_offsets.next, error);
-            if (error.Success() == false || queue_obj_ptr == LLDB_INVALID_ADDRESS)
-            {
-                break;
-            }
         }
     }
-    
-    return enqueued_item_ptr;
+    return originating_thread_sp;
 }
 
-SystemRuntimeMacOSX::ArchivedBacktrace
-SystemRuntimeMacOSX::GetLibdispatchExtendedBacktrace (ThreadSP thread_sp)
+ThreadSP
+SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref)
 {
-    ArchivedBacktrace bt;
-    bt.stop_id = 0;
-    bt.stop_id_is_valid = false;
-    bt.libdispatch_queue_id = LLDB_INVALID_QUEUE_ID;
-
-    addr_t enqueued_item_ptr = GetThreadCreatorItem (thread_sp);
-    
-    if (enqueued_item_ptr == LLDB_INVALID_ADDRESS)
-        return bt;
+    ThreadSP return_thread_sp;
 
+    AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
+    ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
     Error error;
-    uint32_t ptr_size = m_process->GetTarget().GetArchitecture().GetAddressByteSize();
+    ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), item_ref, m_page_to_free, m_page_to_free_size, error);
+    if (ret.item_buffer_ptr != 0 &&  ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
+    {
+        DataBufferHeap data (ret.item_buffer_size, 0);
+        if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
+        {
+            DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
+            ItemInfo item = ExtractItemInfoFromBuffer (extractor);
+            bool stop_id_is_valid = true;
+            if (item.stop_id == 0)
+                stop_id_is_valid = false;
+            return_thread_sp.reset (new HistoryThread (*m_process,
+                                                            item.enqueuing_thread_id,
+                                                            item.enqueuing_callstack,
+                                                            item.stop_id,
+                                                            stop_id_is_valid));
+            return_thread_sp->SetExtendedBacktraceToken (item.item_that_enqueued_this);
+            return_thread_sp->SetQueueName (item.enqueuing_queue_label.c_str());
+            return_thread_sp->SetQueueID (item.enqueuing_queue_serialnum);
+//            return_thread_sp->SetThreadName (item.enqueuing_thread_label.c_str());
+
+        }
+    }
+    return return_thread_sp;
+}
+
+ThreadSP
+SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem (QueueItemSP queue_item_sp, ConstString type)
+{
+    ThreadSP extended_thread_sp;
+    if (type != ConstString("libdispatch"))
+        return extended_thread_sp;
+
+    bool stop_id_is_valid = true;
+    if (queue_item_sp->GetStopID() == 0)
+        stop_id_is_valid = false;
+
+    extended_thread_sp.reset (new HistoryThread (*m_process, 
+                                                 queue_item_sp->GetEnqueueingThreadID(),
+                                                 queue_item_sp->GetEnqueueingBacktrace(),
+                                                 queue_item_sp->GetStopID(),
+                                                 stop_id_is_valid));
+    extended_thread_sp->SetExtendedBacktraceToken (queue_item_sp->GetItemThatEnqueuedThis());
+    extended_thread_sp->SetQueueName (queue_item_sp->GetQueueLabel().c_str());
+    extended_thread_sp->SetQueueID (queue_item_sp->GetEnqueueingQueueID());
+//    extended_thread_sp->SetThreadName (queue_item_sp->GetThreadLabel().c_str());
+
+    return extended_thread_sp;
+}
+
+/* Returns true if we were able to get the version / offset information
+ * out of libBacktraceRecording.  false means we were unable to retrieve
+ * this; the queue_info_version field will be 0.
+ */
 
-    uint32_t backtrace_length = m_process->ReadUnsignedIntegerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.backtrace_length, 4, 0, error);
-    addr_t pc_array_address = m_process->ReadPointerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.backtrace_ptr, error);
+bool
+SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized ()
+{
+    if (m_lib_backtrace_recording_info.queue_info_version != 0)
+        return true;
+
+    addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
+    addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
+    addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
+    addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
+    Target &target = m_process->GetTarget();
 
-    if (backtrace_length == 0 || pc_array_address == LLDB_INVALID_ADDRESS)
-        return bt;
 
-    for (uint32_t idx = 0; idx < backtrace_length; idx++)
+    static ConstString introspection_dispatch_queue_info_version ("__introspection_dispatch_queue_info_version");
+    SymbolContextList sc_list;
+    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) > 0)
+    {
+        SymbolContext sc;
+        sc_list.GetContextAtIndex (0, sc);
+        AddressRange addr_range;
+        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
+        queue_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
+    }
+    sc_list.Clear();
+
+    static ConstString introspection_dispatch_queue_info_data_offset ("__introspection_dispatch_queue_info_data_offset");
+    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_data_offset, eSymbolTypeData, sc_list) > 0)
     {
-        addr_t pc_val = m_process->ReadPointerFromMemory (pc_array_address + (ptr_size * idx), error);
-        if (error.Success() && pc_val != LLDB_INVALID_ADDRESS)
+        SymbolContext sc;
+        sc_list.GetContextAtIndex (0, sc);
+        AddressRange addr_range;
+        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
+        queue_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
+    }
+    sc_list.Clear();
+
+    static ConstString introspection_dispatch_item_info_version ("__introspection_dispatch_item_info_version");
+    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) > 0)
+    {
+        SymbolContext sc;
+        sc_list.GetContextAtIndex (0, sc);
+        AddressRange addr_range;
+        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
+        item_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
+    }
+    sc_list.Clear();
+
+    static ConstString introspection_dispatch_item_info_data_offset ("__introspection_dispatch_item_info_data_offset");
+    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_data_offset, eSymbolTypeData, sc_list) > 0)
+    {
+        SymbolContext sc;
+        sc_list.GetContextAtIndex (0, sc);
+        AddressRange addr_range;
+        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
+        item_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
+    }
+
+    if (queue_info_version_address != LLDB_INVALID_ADDRESS
+        && queue_info_data_offset_address != LLDB_INVALID_ADDRESS
+        && item_info_version_address != LLDB_INVALID_ADDRESS
+        && item_info_data_offset_address != LLDB_INVALID_ADDRESS)
+    {
+        Error error;
+        m_lib_backtrace_recording_info.queue_info_version = m_process->ReadUnsignedIntegerFromMemory (queue_info_version_address, 2, 0, error);
+        if (error.Success())
         {
-            bt.pcs.push_back (pc_val);
+            m_lib_backtrace_recording_info.queue_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (queue_info_data_offset_address, 2, 0, error);
+            if (error.Success())
+            {
+                m_lib_backtrace_recording_info.item_info_version = m_process->ReadUnsignedIntegerFromMemory (item_info_version_address, 2, 0, error);
+                if (error.Success())
+                {
+                    m_lib_backtrace_recording_info.item_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (item_info_data_offset_address, 2, 0, error);
+                    if (!error.Success())
+                    {
+                        m_lib_backtrace_recording_info.queue_info_version = 0;
+                    }
+                }
+                else
+                {
+                    m_lib_backtrace_recording_info.queue_info_version = 0;
+                }
+            }
+            else
+            {
+                m_lib_backtrace_recording_info.queue_info_version = 0;
+            }
         }
     }
 
-    return bt;
+    return m_lib_backtrace_recording_info.queue_info_version != 0;
 }
 
 const std::vector<ConstString> &
@@ -324,146 +466,233 @@ SystemRuntimeMacOSX::GetExtendedBacktrac
     if (m_types.size () == 0)
     {
         m_types.push_back(ConstString("libdispatch"));
-        m_types.push_back(ConstString("pthread"));
+        // We could have pthread as another type in the future if we have a way of
+        // gathering that information & it's useful to distinguish between them.
     }
     return m_types;
 }
 
 void
-SystemRuntimeMacOSX::SetNewThreadQueueName (ThreadSP original_thread_sp, ThreadSP new_extended_thread_sp)
+SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list)
 {
-    addr_t enqueued_item_ptr = GetThreadCreatorItem (original_thread_sp);
-
-    if (enqueued_item_ptr != LLDB_INVALID_ADDRESS)
+    if (!BacktraceRecordingHeadersInitialized())
     {
-        Error error;
-        addr_t queue_name_ptr = m_process->ReadPointerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.queue_name_ptr, error);
-        if (queue_name_ptr != LLDB_INVALID_ADDRESS && error.Success())
+        // We don't have libBacktraceRecording -- build the list of queues by looking at
+        // all extant threads, and the queues that they currently belong to.
+
+        for (ThreadSP thread_sp : m_process->Threads())
         {
-            char namebuf[512];
-            if (m_process->ReadCStringFromMemory (queue_name_ptr, namebuf, sizeof (namebuf), error) > 0 && error.Success())
+            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);
+                }
+            }
+        }
+    }
+    else
+    {
+        AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
+        ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+        if (cur_thread_sp)
+        { 
+            Error error;
+            queue_info_pointer = m_get_queues_handler.GetCurrentQueues (*cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
+            if (error.Success())
             {
-                new_extended_thread_sp->SetQueueName (namebuf);
+                m_page_to_free = LLDB_INVALID_ADDRESS;
+                m_page_to_free_size = 0;
+
+                if (queue_info_pointer.count > 0 
+                    && queue_info_pointer.queues_buffer_size > 0
+                    && queue_info_pointer.queues_buffer_ptr != 0 
+                    && queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS)
+                {
+                    PopulateQueuesUsingLibBTR (queue_info_pointer.queues_buffer_ptr, queue_info_pointer.queues_buffer_size, queue_info_pointer.count, queue_list);
+                }
             }
         }
     }
 }
 
 void
-SystemRuntimeMacOSX::SetNewThreadThreadName (ThreadSP original_thread_sp, ThreadSP new_extended_thread_sp)
+SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
 {
-    addr_t enqueued_item_ptr = GetThreadCreatorItem (original_thread_sp);
-
-    if (enqueued_item_ptr != LLDB_INVALID_ADDRESS)
+    if (BacktraceRecordingHeadersInitialized())
     {
-        Error error;
-        addr_t thread_name_ptr = m_process->ReadPointerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.thread_name_ptr, error);
-        if (thread_name_ptr != LLDB_INVALID_ADDRESS && error.Success())
+        std::vector<addr_t> pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress());
+        for (addr_t pending_item : pending_item_refs)
         {
-            char namebuf[512];
-            if (m_process->ReadCStringFromMemory (thread_name_ptr, namebuf, sizeof (namebuf), error) > 0 && error.Success())
+            AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
+            ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+            Error error;
+            ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), pending_item, m_page_to_free, m_page_to_free_size, error);
+            if (ret.item_buffer_ptr != 0 &&  ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
             {
-                new_extended_thread_sp->SetName (namebuf);
+                DataBufferHeap data (ret.item_buffer_size, 0);
+                if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
+                {
+                    DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
+                    ItemInfo item = ExtractItemInfoFromBuffer (extractor);
+                    QueueItemSP queue_item_sp (new QueueItem (queue->shared_from_this()));
+                    queue_item_sp->SetItemThatEnqueuedThis (item.item_that_enqueued_this);
+
+                    Address addr;
+                    if (!m_process->GetTarget().ResolveLoadAddress (item.function_or_block, addr, item.stop_id))
+                    {
+                        m_process->GetTarget().ResolveLoadAddress (item.function_or_block, addr);
+                    }
+                    queue_item_sp->SetAddress (addr);
+                    queue_item_sp->SetEnqueueingThreadID (item.enqueuing_thread_id);
+                    queue_item_sp->SetTargetQueueID (item.enqueuing_thread_id);
+                    queue_item_sp->SetStopID (item.stop_id);
+                    queue_item_sp->SetEnqueueingBacktrace (item.enqueuing_callstack);
+                    queue_item_sp->SetThreadLabel (item.enqueuing_thread_label);
+                    queue_item_sp->SetQueueLabel (item.enqueuing_queue_label);
+                    queue_item_sp->SetTargetQueueLabel (item.target_queue_label);
+
+                    queue->PushPendingQueueItem (queue_item_sp);
+                }
             }
         }
     }
 }
 
-
-void
-SystemRuntimeMacOSX::SetNewThreadExtendedBacktraceToken (ThreadSP original_thread_sp, ThreadSP new_extended_thread_sp)
-{
-    addr_t enqueued_item_ptr = GetThreadCreatorItem (original_thread_sp);
-    if (enqueued_item_ptr != LLDB_INVALID_ADDRESS)
-    {
+// Returns an array of introspection_dispatch_item_info_ref's for the pending items on
+// a queue.  The information about each of these pending items then needs to be fetched
+// individually by passing the ref to libBacktraceRecording.
+
+std::vector<lldb::addr_t>
+SystemRuntimeMacOSX::GetPendingItemRefsForQueue (lldb::addr_t queue)
+{
+    std::vector<addr_t> pending_item_refs;
+    AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
+    ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+    if (cur_thread_sp)
+    { 
         Error error;
-        uint64_t further_extended_backtrace = m_process->ReadPointerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.enqueueing_thread_dispatch_block_ptr, error);
-        if (error.Success() && further_extended_backtrace != 0 && further_extended_backtrace != LLDB_INVALID_ADDRESS)
+        pending_items_pointer = m_get_pending_items_handler.GetPendingItems (*cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size, error);
+        if (error.Success())
         {
-            new_extended_thread_sp->SetExtendedBacktraceToken (further_extended_backtrace);
+            m_page_to_free = LLDB_INVALID_ADDRESS;
+            m_page_to_free_size = 0;
+            if (pending_items_pointer.count > 0
+                && pending_items_pointer.items_buffer_size > 0
+                && pending_items_pointer.items_buffer_ptr != 0
+                && pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS)
+            {
+                DataBufferHeap data (pending_items_pointer.items_buffer_size, 0);
+                if (m_process->ReadMemory (pending_items_pointer.items_buffer_ptr, data.GetBytes(), pending_items_pointer.items_buffer_size, error))
+                {
+                    offset_t offset = 0;
+                    DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
+                    int i = 0;
+                    while (offset < pending_items_pointer.items_buffer_size && i < pending_items_pointer.count)
+                    {
+                        pending_item_refs.push_back (extractor.GetPointer (&offset));
+                        i++;
+                    }
+                }
+                m_page_to_free = pending_items_pointer.items_buffer_ptr;
+                m_page_to_free_size = pending_items_pointer.items_buffer_size;
+            }
         }
     }
+    return pending_item_refs;
 }
 
+
 void
-SystemRuntimeMacOSX::SetNewThreadQueueID (ThreadSP original_thread_sp, ThreadSP new_extended_thread_sp)
+SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, 
+                                                uint64_t count, lldb_private::QueueList &queue_list)
 {
-    queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
-    addr_t enqueued_item_ptr = GetThreadCreatorItem (original_thread_sp);
-    if (enqueued_item_ptr != LLDB_INVALID_ADDRESS && m_ldi_header.item_offsets.queue_id_from_thread_info != 0xffff)
-    {
-        Error error;
-        queue_id = m_process->ReadUnsignedIntegerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.queue_id_from_thread_info, 8, LLDB_INVALID_QUEUE_ID, error);
-        if (!error.Success())
-            queue_id = LLDB_INVALID_QUEUE_ID;
-    }
-
-    if (queue_id != LLDB_INVALID_QUEUE_ID)
+    Error error;
+    DataBufferHeap data (queues_buffer_size, 0);
+    if (m_process->ReadMemory (queues_buffer, data.GetBytes(), queues_buffer_size, error) == queues_buffer_size && error.Success())
     {
-        new_extended_thread_sp->SetQueueID (queue_id);
-    }
-}
+        // We've read the information out of inferior memory; free it on the next call we make
+        m_page_to_free = queues_buffer;
+        m_page_to_free_size = queues_buffer_size;
+
+        DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
+        offset_t offset = 0;
+        uint64_t queues_read = 0;
+
+        // The information about the queues is stored in this format (v1):
+        // typedef struct introspection_dispatch_queue_info_s {
+        //     uint32_t offset_to_next;
+        //     dispatch_queue_t queue;
+        //     uint64_t serialnum;     // queue's serialnum in the process, as provided by libdispatch
+        //     uint32_t running_work_items_count;
+        //     uint32_t pending_work_items_count;
+        // 
+        //     char data[];     // Starting here, we have variable-length data:
+        //     // char queue_label[];
+        // } introspection_dispatch_queue_info_s;
 
+        while (queues_read < count && offset < queues_buffer_size)
+        {
+            offset_t    start_of_this_item = offset;
 
-lldb::tid_t
-SystemRuntimeMacOSX::GetNewThreadUniqueThreadID (ThreadSP original_thread_sp)
-{
-    tid_t ret = LLDB_INVALID_THREAD_ID;
-    addr_t enqueued_item_ptr = GetThreadCreatorItem (original_thread_sp);
-    if (enqueued_item_ptr != LLDB_INVALID_ADDRESS)
-    {
-        Error error;
-        ret = m_process->ReadUnsignedIntegerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.unique_thread_id, 8, LLDB_INVALID_THREAD_ID, error);
-        if (!error.Success())
-            ret = LLDB_INVALID_THREAD_ID;
+            uint32_t    offset_to_next = extractor.GetU32 (&offset);
+            /* on 64-bit architectures, the pointer will be 8-byte aligned so there's 4 bytes of
+             * padding between these fields. 
+             */
+            if (m_process->GetAddressByteSize() == 8)
+                offset += 4;
+            addr_t      queue = extractor.GetPointer (&offset);
+            uint64_t    serialnum = extractor.GetU64 (&offset);
+            uint32_t    running_work_items_count = extractor.GetU32 (&offset);
+            uint32_t    pending_work_items_count = extractor.GetU32 (&offset);
+
+            // Read the first field of the variable length data
+            offset = start_of_this_item + m_lib_backtrace_recording_info.queue_info_data_offset;
+            const char *queue_label = extractor.GetCStr (&offset);
+            if (queue_label == NULL)
+                queue_label = "";
+
+            offset_t    start_of_next_item = start_of_this_item + offset_to_next;
+            offset = start_of_next_item;
+
+            QueueSP queue_sp (new Queue (m_process->shared_from_this(), serialnum, queue_label));
+            queue_sp->SetNumRunningWorkItems (running_work_items_count);
+            queue_sp->SetNumPendingWorkItems (pending_work_items_count);
+            queue_sp->SetLibdispatchQueueAddress (queue);
+            queue_list.AddQueue (queue_sp);
+            queues_read++;
+        }
     }
-    return ret;
 }
 
-ThreadSP
-SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP original_thread_sp, ConstString type)
+SystemRuntimeMacOSX::ItemInfo
+SystemRuntimeMacOSX::ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor)
 {
-    ThreadSP new_extended_thread_sp;
-
-    if (type != ConstString("libdispatch"))
-        return new_extended_thread_sp;
-
-    ArchivedBacktrace bt = GetLibdispatchExtendedBacktrace (original_thread_sp);
-
-    if (bt.pcs.size() == 0)
-        return new_extended_thread_sp;
-
-    tid_t unique_thread_id = GetNewThreadUniqueThreadID (original_thread_sp);
-
-    new_extended_thread_sp.reset (new HistoryThread (*m_process, unique_thread_id, bt.pcs, bt.stop_id, bt.stop_id_is_valid));
+    ItemInfo item;
 
-    SetNewThreadThreadName (original_thread_sp, new_extended_thread_sp);
-    SetNewThreadQueueName (original_thread_sp, new_extended_thread_sp);
-    SetNewThreadQueueID (original_thread_sp, new_extended_thread_sp);
-    SetNewThreadExtendedBacktraceToken (original_thread_sp, new_extended_thread_sp);
-    return new_extended_thread_sp;
-}
+    offset_t offset = 0;
+    
+    item.item_that_enqueued_this = extractor.GetPointer (&offset);
+    item.function_or_block = extractor.GetPointer (&offset);
+    item.enqueuing_thread_id = extractor.GetU64 (&offset);
+    item.enqueuing_queue_serialnum = extractor.GetU64 (&offset);
+    item.target_queue_serialnum = extractor.GetU64 (&offset);
+    item.enqueuing_callstack_frame_count = extractor.GetU32 (&offset);
+    item.stop_id = extractor.GetU32 (&offset);
 
-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.)
+    offset = m_lib_backtrace_recording_info.item_info_data_offset;
 
-    for (ThreadSP thread_sp : m_process->Threads())
+    for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++)
     {
-        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);
-            }
-        }
+        item.enqueuing_callstack.push_back (extractor.GetPointer (&offset));
     }
-}
+    item.enqueuing_thread_label = extractor.GetCStr (&offset);
+    item.enqueuing_queue_label = extractor.GetCStr (&offset);
+    item.target_queue_label = extractor.GetCStr (&offset);
 
+    return item;
+}
 
 void
 SystemRuntimeMacOSX::Initialize()

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h Tue Feb  4 23:44:54 2014
@@ -26,6 +26,12 @@
 #include "lldb/Core/UUID.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/QueueItem.h"
+
+#include "AppleGetItemInfoHandler.h"
+#include "AppleGetQueuesHandler.h"
+#include "AppleGetPendingItemsHandler.h"
+#include "AppleGetThreadItemInfoHandler.h"
 
 class SystemRuntimeMacOSX : public lldb_private::SystemRuntime
 {
@@ -48,6 +54,11 @@ public:
     static lldb_private::SystemRuntime *
     CreateInstance (lldb_private::Process *process);
 
+
+    //------------------------------------------------------------------
+    // instance methods
+    //------------------------------------------------------------------
+
     SystemRuntimeMacOSX (lldb_private::Process *process);
 
     virtual
@@ -57,13 +68,7 @@ public:
     Clear (bool clear_process);
 
     void
-    DidAttach ();
-
-    void
-    DidLaunch();
-
-    void
-    ModulesDidLoad (lldb_private::ModuleList &module_list);
+    Detach ();
 
     const std::vector<lldb_private::ConstString> &
     GetExtendedBacktraceTypes ();
@@ -71,18 +76,29 @@ public:
     lldb::ThreadSP
     GetExtendedBacktraceThread (lldb::ThreadSP thread, lldb_private::ConstString type);
 
-    // REMOVE THE FOLLOWING 4
-    bool 
-    SetItemEnqueuedBreakpoint ();
+    lldb::ThreadSP
+    GetExtendedBacktraceForQueueItem (lldb::QueueItemSP queue_item_sp, lldb_private::ConstString type);
 
-    bool
-    DidSetItemEnqueuedBreakpoint () const;
+    lldb::ThreadSP
+    GetExtendedBacktraceFromItemRef (lldb::addr_t item_ref);
 
-    static bool
-    ItemEnqueuedCallback (void *baton, lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+    void
+    PopulateQueueList (lldb_private::QueueList &queue_list);
 
-    bool
-    ItemEnqueuedBreakpointHit (lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+    void
+    PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count, lldb_private::QueueList &queue_list);
+
+    void
+    PopulatePendingQueuesUsingLibBTR (lldb::addr_t items_buffer, uint64_t items_buffer_size, uint64_t count, lldb_private::Queue *queue);
+
+    std::string
+    GetQueueNameFromThreadQAddress (lldb::addr_t dispatch_qaddr);
+
+    lldb::queue_id_t
+    GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr);
+
+    void
+    PopulatePendingItemsForQueue (lldb_private::Queue *queue);
 
     //------------------------------------------------------------------
     // PluginInterface protocol
@@ -93,19 +109,6 @@ public:
     virtual uint32_t
     GetPluginVersion();
 
-private:
-    struct ArchivedBacktrace {
-        uint32_t stop_id;
-        bool stop_id_is_valid;
-        lldb::queue_id_t libdispatch_queue_id;   // LLDB_INVALID_QUEUE_ID if unavailable
-        std::vector<lldb::addr_t> pcs;
-    };
-
-    SystemRuntimeMacOSX::ArchivedBacktrace
-    GetLibdispatchExtendedBacktrace (lldb::ThreadSP thread);
-
-    void
-    PopulateQueueList (lldb_private::QueueList &queue_list);
 
 protected:
     lldb::user_id_t m_break_id;
@@ -113,73 +116,103 @@ protected:
 
 private:
 
-    void
-    ParseLdiHeaders ();
-
-    bool
-    LdiHeadersInitialized ();
-
-    lldb::addr_t
-    GetQueuesHead ();
-
-    lldb::addr_t
-    GetItemsHead ();
+    struct libBacktraceRecording_info {
+        uint16_t    queue_info_version;
+        uint16_t    queue_info_data_offset;
+        uint16_t    item_info_version;
+        uint16_t    item_info_data_offset;
+
+        libBacktraceRecording_info () :
+            queue_info_version(0),
+            queue_info_data_offset(0),
+            item_info_version(0),
+            item_info_data_offset(0) {}
+    };
 
-    lldb::addr_t
-    GetThreadCreatorItem (lldb::ThreadSP thread);
 
-    lldb::tid_t
-    GetNewThreadUniqueThreadID (lldb::ThreadSP original_thread_sp);
+    // A structure which reflects the data recorded in the
+    // libBacktraceRecording introspection_dispatch_item_info_s.
+    struct ItemInfo {
+        lldb::addr_t    item_that_enqueued_this;
+        lldb::addr_t    function_or_block;
+        uint64_t        enqueuing_thread_id;
+        uint64_t        enqueuing_queue_serialnum;
+        uint64_t        target_queue_serialnum;
+        uint32_t        enqueuing_callstack_frame_count;
+        uint32_t        stop_id;
+        std::vector<lldb::addr_t>   enqueuing_callstack;
+        std::string                 enqueuing_thread_label;
+        std::string                 enqueuing_queue_label;
+        std::string                 target_queue_label;
+    };
 
-    void
-    SetNewThreadThreadName (lldb::ThreadSP original_thread_sp, lldb::ThreadSP new_extended_thread_sp);
+    // The offsets of different fields of the dispatch_queue_t structure in
+    // a thread/queue process.
+    // Based on libdispatch src/queue_private.h, struct dispatch_queue_offsets_s
+    // With dqo_version 1-3, the dqo_label field is a per-queue value and cannot be cached.
+    // With dqo_version 4 (Mac OS X 10.9 / iOS 7), dqo_label is a constant value that can be cached.
+    struct LibdispatchOffsets
+    {
+        uint16_t dqo_version;
+        uint16_t dqo_label;
+        uint16_t dqo_label_size;
+        uint16_t dqo_flags;
+        uint16_t dqo_flags_size;
+        uint16_t dqo_serialnum;
+        uint16_t dqo_serialnum_size;
+        uint16_t dqo_width;
+        uint16_t dqo_width_size;
+        uint16_t dqo_running;
+        uint16_t dqo_running_size;
+
+        LibdispatchOffsets ()
+        {
+            dqo_version = UINT16_MAX;
+            dqo_flags  = UINT16_MAX;
+            dqo_serialnum = UINT16_MAX;
+            dqo_label = UINT16_MAX;
+            dqo_width = UINT16_MAX;
+            dqo_running = UINT16_MAX;
+        };
+
+        bool
+        IsValid ()
+        {
+            return dqo_version != UINT16_MAX;
+        }
+
+        bool
+        LabelIsValid ()
+        {
+            return dqo_label != UINT16_MAX;
+        }
+    };
 
-    void
-    SetNewThreadQueueName (lldb::ThreadSP original_thread_sp, lldb::ThreadSP new_extended_thread_sp);
+    bool
+    BacktraceRecordingHeadersInitialized ();
 
     void
-    SetNewThreadExtendedBacktraceToken (lldb::ThreadSP original_thread_sp, lldb::ThreadSP new_extended_thread_sp);
+    ReadLibdispatchOffsetsAddress();
 
     void
-    SetNewThreadQueueID (lldb::ThreadSP original_thread_sp, lldb::ThreadSP new_extended_thread_sp);
+    ReadLibdispatchOffsets ();
 
-    struct ldi_queue_offsets {
-        uint16_t next;
-        uint16_t prev;
-        uint16_t queue_id;
-        uint16_t current_item_ptr;
-    };
+    std::vector<lldb::addr_t>
+    GetPendingItemRefsForQueue (lldb::addr_t queue);
 
-    struct ldi_item_offsets {
-        uint16_t next;
-        uint16_t prev;
-        uint16_t type;
-        uint16_t identifier;
-        uint16_t stop_id;
-        uint16_t backtrace_length;
-        uint16_t backtrace_ptr;
-        uint16_t thread_name_ptr;
-        uint16_t queue_name_ptr;
-        uint16_t unique_thread_id;
-        uint16_t pthread_id;
-        uint16_t enqueueing_thread_dispatch_queue_t;
-        uint16_t enqueueing_thread_dispatch_block_ptr;
-        uint16_t queue_id_from_thread_info;
-    };
+    ItemInfo
+    ExtractItemInfoFromBuffer (lldb_private::DataExtractor &extractor);
 
-    struct ldi_header {
-        uint16_t                    version;
-        uint16_t                    ldi_header_size;
-        uint16_t                    initialized;        // 0 means uninitialized
-        uint16_t                    queue_size;
-        uint16_t                    item_size;
-        uint64_t                    queues_head_ptr_address;  // Address of queues head structure
-        uint64_t                    items_head_ptr_address;   // Address of items_head
-        struct ldi_queue_offsets    queue_offsets;
-        struct ldi_item_offsets     item_offsets;
-    };
+    lldb_private::AppleGetQueuesHandler m_get_queues_handler;
+    lldb_private::AppleGetPendingItemsHandler m_get_pending_items_handler;
+    lldb_private::AppleGetItemInfoHandler m_get_item_info_handler;
+    lldb_private::AppleGetThreadItemInfoHandler m_get_thread_item_info_handler;
 
-    struct ldi_header   m_ldi_header;
+    lldb::addr_t                        m_page_to_free;
+    uint64_t                            m_page_to_free_size;
+    libBacktraceRecording_info          m_lib_backtrace_recording_info;
+    lldb::addr_t                        m_dispatch_queue_offsets_addr;
+    struct LibdispatchOffsets           m_libdispatch_offsets;
 
     DISALLOW_COPY_AND_ASSIGN (SystemRuntimeMacOSX);
 };

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Feb  4 23:44:54 2014
@@ -1020,9 +1020,7 @@ Process::Process(Target &target, Listene
     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),
@@ -1699,39 +1697,6 @@ Process::AssignIndexIDToThread(uint64_t
     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()
 {

Modified: lldb/trunk/source/Target/Queue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Queue.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Target/Queue.cpp (original)
+++ lldb/trunk/source/Target/Queue.cpp Tue Feb  4 23:44:54 2014
@@ -11,6 +11,7 @@
 #include "lldb/Target/Queue.h"
 #include "lldb/Target/QueueList.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Target/SystemRuntime.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -19,13 +20,15 @@ Queue::Queue (ProcessSP process_sp, lldb
     m_process_wp (),
     m_queue_id (queue_id),
     m_queue_name (),
-    m_enqueued_items()
+    m_running_work_items_count(0),
+    m_pending_work_items_count(0),
+    m_pending_items(),
+    m_dispatch_queue_t_addr(LLDB_INVALID_ADDRESS)
 {
     if (queue_name)
         m_queue_name = queue_name;
 
     m_process_wp = process_sp;
-    m_index_id = process_sp->AssignIndexIDToQueue (queue_id);
 }
 
 Queue::~Queue ()
@@ -50,7 +53,7 @@ Queue::GetName ()
 uint32_t
 Queue::GetIndexID ()
 {
-    return m_index_id;
+    return m_queue_id;
 }
 
 std::vector<lldb::ThreadSP>
@@ -70,3 +73,55 @@ Queue::GetThreads ()
     }
     return result;
 }
+
+void
+Queue::SetNumRunningWorkItems (uint32_t count)
+{
+    m_running_work_items_count = count;
+}
+
+uint32_t
+Queue::GetNumRunningWorkItems () const
+{
+    return m_running_work_items_count;
+}
+
+
+void
+Queue::SetNumPendingWorkItems (uint32_t count)
+{
+    m_pending_work_items_count = count;
+}
+
+uint32_t
+Queue::GetNumPendingWorkItems () const
+{
+    return m_pending_work_items_count;
+}
+
+void
+Queue::SetLibdispatchQueueAddress (addr_t dispatch_queue_t_addr)
+{
+    m_dispatch_queue_t_addr = dispatch_queue_t_addr;
+}
+
+addr_t
+Queue::GetLibdispatchQueueAddress () const
+{
+    return m_dispatch_queue_t_addr;
+}
+
+
+const std::vector<lldb::QueueItemSP> &
+Queue::GetPendingItems ()
+{
+    if (m_pending_items.size() == 0)
+    {
+        ProcessSP process_sp = m_process_wp.lock();
+        if (process_sp && process_sp->GetSystemRuntime())
+        {
+            process_sp->GetSystemRuntime()->PopulatePendingItemsForQueue (this);
+        }
+    }
+    return m_pending_items;
+}

Modified: lldb/trunk/source/Target/QueueItem.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/QueueItem.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Target/QueueItem.cpp (original)
+++ lldb/trunk/source/Target/QueueItem.cpp Tue Feb  4 23:44:54 2014
@@ -8,7 +8,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Target/Queue.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/QueueItem.h"
+#include "lldb/Target/SystemRuntime.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -16,7 +18,16 @@ using namespace lldb_private;
 QueueItem::QueueItem (QueueSP queue_sp) :
     m_queue_wp (),
     m_kind (eQueueItemKindUnknown),
-    m_address ()
+    m_address (),
+    m_item_that_enqueued_this_ref (LLDB_INVALID_ADDRESS),
+    m_enqueueing_thread_id (LLDB_INVALID_THREAD_ID),
+    m_enqueueing_queue_id (LLDB_INVALID_QUEUE_ID),
+    m_target_queue_id (LLDB_INVALID_QUEUE_ID),
+    m_stop_id (0),
+    m_backtrace(),
+    m_thread_label(),
+    m_queue_label(),
+    m_target_queue_label()
 {
     m_queue_wp = queue_sp;
 }
@@ -52,5 +63,15 @@ QueueItem::SetAddress (Address addr)
 ThreadSP
 QueueItem::GetExtendedBacktraceThread (ConstString type)
 {
-    return ThreadSP();
+    ThreadSP return_thread;
+    QueueSP queue_sp = m_queue_wp.lock();
+    if (queue_sp)
+    {
+        ProcessSP process_sp = queue_sp->GetProcess();
+        if (process_sp && process_sp->GetSystemRuntime())
+        {
+            return_thread = process_sp->GetSystemRuntime()->GetExtendedBacktraceForQueueItem (this->shared_from_this(), type);
+        }
+    }
+    return return_thread;
 }

Modified: lldb/trunk/source/Target/SystemRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/SystemRuntime.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/Target/SystemRuntime.cpp (original)
+++ lldb/trunk/source/Target/SystemRuntime.cpp Tue Feb  4 23:44:54 2014
@@ -56,6 +56,11 @@ SystemRuntime::DidLaunch()
 }
 
 void
+SystemRuntime::Detach()
+{
+}
+
+void
 SystemRuntime::ModulesDidLoad (ModuleList &module_list)
 {
 }

Modified: lldb/trunk/source/lldb-log.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb-log.cpp?rev=200822&r1=200821&r2=200822&view=diff
==============================================================================
--- lldb/trunk/source/lldb-log.cpp (original)
+++ lldb/trunk/source/lldb-log.cpp Tue Feb  4 23:44:54 2014
@@ -141,6 +141,7 @@ lldb_private::DisableLog (const char **c
                 else if (0 == ::strncasecmp(arg, "unwind", 6))  flag_bits &= ~LIBLLDB_LOG_UNWIND;
                 else if (0 == ::strncasecmp(arg, "types", 5))   flag_bits &= ~LIBLLDB_LOG_TYPES;
                 else if (0 == ::strncasecmp(arg, "symbol", 6))  flag_bits &= ~LIBLLDB_LOG_SYMBOLS;
+                else if (0 == ::strcasecmp(arg, "system-runtime"))  flag_bits &= ~LIBLLDB_LOG_SYSTEM_RUNTIME;
                 else if (0 == ::strncasecmp(arg, "module", 6))  flag_bits &= ~LIBLLDB_LOG_MODULES;
                 else if (0 == ::strncasecmp(arg, "mmap", 4))    flag_bits &= ~LIBLLDB_LOG_MMAP;
                 else if (0 == ::strcasecmp(arg, "os"))          flag_bits &= ~LIBLLDB_LOG_OS;
@@ -208,6 +209,7 @@ lldb_private::EnableLog (StreamSP &log_s
             else if (0 == ::strcasecmp(arg, "state"))       flag_bits |= LIBLLDB_LOG_STATE;
             else if (0 == ::strcasecmp(arg, "step"))        flag_bits |= LIBLLDB_LOG_STEP;
             else if (0 == ::strncasecmp(arg, "symbol", 6))  flag_bits |= LIBLLDB_LOG_SYMBOLS;
+            else if (0 == ::strcasecmp(arg, "system-runtime"))  flag_bits |= LIBLLDB_LOG_SYSTEM_RUNTIME;
             else if (0 == ::strcasecmp(arg, "target"))      flag_bits |= LIBLLDB_LOG_TARGET;
             else if (0 == ::strncasecmp(arg, "temp", 4))    flag_bits |= LIBLLDB_LOG_TEMPORARY;
             else if (0 == ::strcasecmp(arg, "thread"))      flag_bits |= LIBLLDB_LOG_THREAD;
@@ -256,6 +258,7 @@ lldb_private::ListLogCategories (Stream
                  "  state - log private and public process state changes\n"
                  "  step - log step related activities\n"
                  "  symbol - log symbol related issues and warnings\n"
+                 "  system-runtime - log system runtime events\n"
                  "  target - log target events and activities\n"
                  "  thread - log thread events and activities\n"
                  "  types - log type system related activities\n"





More information about the lldb-commits mailing list