libBacktraceRecording __introspection_dispatch_queue_get_pending_items is
authorJason Molenda <jmolenda@apple.com>
Sun, 9 Mar 2014 21:17:08 +0000 (21:17 +0000)
committerJason Molenda <jmolenda@apple.com>
Sun, 9 Mar 2014 21:17:08 +0000 (21:17 +0000)
changing the data it returns; this change accepts either the old format or
the new format.  It doesn't yet benefit from the new format's additions -
but I need to get this checked in so we aren't rev-locked.
Also add a missing .i entry for SBQueue::GetNumRunningItems() missing from
the last checkin.
<rdar://problem/16272115>

llvm-svn: 203421

lldb/include/lldb/Target/QueueItem.h
lldb/scripts/Python/interface/SBQueue.i
lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
lldb/source/Target/QueueItem.cpp

index 1e4dbb7..bdb6d99 100644 (file)
@@ -38,7 +38,7 @@ class QueueItem :
 {
 public:
 
-    QueueItem (lldb::QueueSP queue_sp);
+    QueueItem (lldb::QueueSP queue_sp, lldb::addr_t item_ref);
 
     ~QueueItem ();
 
@@ -222,6 +222,7 @@ protected:
     lldb::QueueItemKind     m_kind;
     lldb_private::Address   m_address;
 
+    lldb::addr_t            m_item_ref;     // the token we can be used to fetch more information about this queue item
     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
index f3a49b1..7f48166 100644 (file)
@@ -48,6 +48,9 @@ public:
     lldb::SBQueueItem
     GetPendingItemAtIndex (uint32_t);
 
+    uint32_t
+    GetNumRunningItems ();
+
 };
 
 } // namespace lldb
index d4d60b3..53b9c83 100644 (file)
@@ -526,18 +526,104 @@ SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list)
     }
 }
 
+// Returns either an array of introspection_dispatch_item_info_ref's for the pending items on
+// a queue or an array introspection_dispatch_item_info_ref's and code addresses 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.
+
+SystemRuntimeMacOSX::PendingItemsForQueue
+SystemRuntimeMacOSX::GetPendingItemRefsForQueue (lldb::addr_t queue)
+{
+    PendingItemsForQueue pending_item_refs;
+    AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
+    ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
+    if (cur_thread_sp)
+    { 
+        Error error;
+        pending_items_pointer = m_get_pending_items_handler.GetPendingItems (*cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size, error);
+        m_page_to_free = LLDB_INVALID_ADDRESS;
+        m_page_to_free_size = 0;
+        if (error.Success())
+        {
+            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))
+                {
+                    DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
+
+                    // We either have an array of
+                    //    void* item_ref
+                    // (old style) or we have a structure returned which looks like
+                    //
+                    // struct introspection_dispatch_pending_item_info_s {
+                    //   void *item_ref;
+                    //   void *function_or_block;
+                    // };
+                    //
+                    // struct introspection_dispatch_pending_items_array_s {
+                    //   uint32_t version;
+                    //   uint32_t size_of_item_info;
+                    //   introspection_dispatch_pending_item_info_s items[];
+                    //   }
+
+                    offset_t offset = 0;
+                    int i = 0;
+                    uint32_t version = extractor.GetU32(&offset);
+                    if (version == 1)
+                    {
+                        pending_item_refs.new_style = true;
+                        uint32_t item_size = extractor.GetU32(&offset);
+                        uint32_t start_of_array_offset = offset;
+                        while (offset < pending_items_pointer.items_buffer_size && i < pending_items_pointer.count)
+                        {
+                            offset = start_of_array_offset + (i * item_size);
+                            ItemRefAndCodeAddress item;
+                            item.item_ref = extractor.GetPointer (&offset);
+                            item.code_address = extractor.GetPointer (&offset);
+                            pending_item_refs.item_refs_and_code_addresses.push_back (item);
+                            i++;
+                        }
+                    }
+                    else
+                    {
+                        offset = 0;
+                        pending_item_refs.new_style = false;
+                        while (offset < pending_items_pointer.items_buffer_size && i < pending_items_pointer.count)
+                        {
+                            ItemRefAndCodeAddress item;
+                            item.item_ref = extractor.GetPointer (&offset);
+                            item.code_address = LLDB_INVALID_ADDRESS;
+                            pending_item_refs.item_refs_and_code_addresses.push_back (item);
+                            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::PopulatePendingItemsForQueue (Queue *queue)
 {
     if (BacktraceRecordingHeadersInitialized())
     {
-        std::vector<addr_t> pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress());
-        for (addr_t pending_item : pending_item_refs)
+        PendingItemsForQueue pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress());
+        for (ItemRefAndCodeAddress pending_item : pending_item_refs.item_refs_and_code_addresses)
         {
             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);
+            ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), pending_item.item_ref, m_page_to_free, m_page_to_free_size, error);
             m_page_to_free = LLDB_INVALID_ADDRESS;
             m_page_to_free_size = 0;
             if (ret.item_buffer_ptr != 0 &&  ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0)
@@ -547,7 +633,7 @@ SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
                 {
                     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()));
+                    QueueItemSP queue_item_sp (new QueueItem (queue->shared_from_this(), pending_item.item_ref));
                     queue_item_sp->SetItemThatEnqueuedThis (item.item_that_enqueued_this);
 
                     Address addr;
@@ -573,50 +659,6 @@ SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
     }
 }
 
-// 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;
-        pending_items_pointer = m_get_pending_items_handler.GetPendingItems (*cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size, error);
-        m_page_to_free = LLDB_INVALID_ADDRESS;
-        m_page_to_free_size = 0;
-        if (error.Success())
-        {
-            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::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, 
                                                 uint64_t count, lldb_private::QueueList &queue_list)
index a308844..c20f19c 100644 (file)
@@ -188,6 +188,23 @@ private:
         }
     };
 
+
+    // The libBacktraceRecording function __introspection_dispatch_queue_get_pending_items has
+    // two forms.  It can either return a simple array of item_refs (void *) size or it can return
+    // a header with uint32_t version, a uint32_t size of item, and then an array of item_refs (void*)
+    // and code addresses (void*) for all the pending blocks.
+
+    struct ItemRefAndCodeAddress {
+        lldb::addr_t    item_ref;
+        lldb::addr_t    code_address;
+    };  
+
+    struct PendingItemsForQueue {
+        bool new_style;              // new-style means both item_refs and code_addresses avail
+                                     // old-style means only item_refs is filled in
+        std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses;
+    };  
+
     bool
     BacktraceRecordingHeadersInitialized ();
 
@@ -197,7 +214,7 @@ private:
     void
     ReadLibdispatchOffsets ();
 
-    std::vector<lldb::addr_t>
+    PendingItemsForQueue
     GetPendingItemRefsForQueue (lldb::addr_t queue);
 
     ItemInfo
index afb5cd0..40d824b 100644 (file)
 using namespace lldb;
 using namespace lldb_private;
 
-QueueItem::QueueItem (QueueSP queue_sp) :
+QueueItem::QueueItem (QueueSP queue_sp, lldb::addr_t item_ref) :
     m_queue_wp (),
     m_kind (eQueueItemKindUnknown),
     m_address (),
+    m_item_ref (item_ref),
     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),