Пример #1
0
ThreadSP
SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP real_thread, ConstString type)
{
    ThreadSP originating_thread_sp;
    if (BacktraceRecordingHeadersInitialized() && type == ConstString ("libdispatch"))
    {
        Error error;

        // 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
        {
            ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
            AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret = m_get_thread_item_info_handler.GetThreadItemInfo (*cur_thread_sp.get(), real_thread->GetID(), 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)
            {
                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;
                    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());
                }
                m_page_to_free = ret.item_buffer_ptr;
                m_page_to_free_size = ret.item_buffer_size;
            }
        }
    }
    return originating_thread_sp;
}
Пример #2
0
addr_t
SystemRuntimeMacOSX::GetThreadCreatorItem (ThreadSP thread_sp)
{
    addr_t enqueued_item_ptr = thread_sp->GetExtendedBacktraceToken();
    if (enqueued_item_ptr == LLDB_INVALID_ADDRESS)
    {
        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)
        {
            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)
            {
                if (queue_id == this_thread_queue_id)
                {
                    enqueued_item_ptr = m_process->ReadPointerFromMemory (queue_obj_ptr + m_ldi_header.queue_offsets.current_item_ptr, error);
                    break;
                }
            }
            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;
}