1 //===-- HistoryThread.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/lldb-private.h"
10 
11 #include "Plugins/Process/Utility/HistoryThread.h"
12 
13 #include "Plugins/Process/Utility/HistoryUnwind.h"
14 #include "Plugins/Process/Utility/RegisterContextHistory.h"
15 
16 #include "lldb/Target/Process.h"
17 #include "lldb/Target/StackFrameList.h"
18 #include "lldb/Utility/Log.h"
19 
20 #include <memory>
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 //  Constructor
26 
27 HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
28                              std::vector<lldb::addr_t> pcs, uint32_t stop_id,
29                              bool stop_id_is_valid)
30     : Thread(process, tid, true), m_framelist_mutex(), m_framelist(),
31       m_pcs(pcs), m_stop_id(stop_id), m_stop_id_is_valid(stop_id_is_valid),
32       m_extended_unwind_token(LLDB_INVALID_ADDRESS), m_queue_name(),
33       m_thread_name(), m_originating_unique_thread_id(tid),
34       m_queue_id(LLDB_INVALID_QUEUE_ID) {
35   m_unwinder_up.reset(new HistoryUnwind(*this, pcs, stop_id_is_valid));
36   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
37   if (log)
38     log->Printf("%p HistoryThread::HistoryThread", static_cast<void *>(this));
39 }
40 
41 //  Destructor
42 
43 HistoryThread::~HistoryThread() {
44   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
45   if (log)
46     log->Printf("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")",
47                 static_cast<void *>(this), GetID());
48   DestroyThread();
49 }
50 
51 lldb::RegisterContextSP HistoryThread::GetRegisterContext() {
52   RegisterContextSP rctx;
53   if (m_pcs.size() > 0) {
54     rctx = std::make_shared<RegisterContextHistory>(
55         *this, 0, GetProcess()->GetAddressByteSize(), m_pcs[0]);
56   }
57   return rctx;
58 }
59 
60 lldb::RegisterContextSP
61 HistoryThread::CreateRegisterContextForFrame(StackFrame *frame) {
62   return m_unwinder_up->CreateRegisterContextForFrame(frame);
63 }
64 
65 lldb::StackFrameListSP HistoryThread::GetStackFrameList() {
66   // FIXME do not throw away the lock after we acquire it..
67   std::unique_lock<std::mutex> lock(m_framelist_mutex);
68   lock.unlock();
69   if (m_framelist.get() == NULL) {
70     m_framelist =
71         std::make_shared<StackFrameList>(*this, StackFrameListSP(), true);
72   }
73 
74   return m_framelist;
75 }
76 
77 uint32_t HistoryThread::GetExtendedBacktraceOriginatingIndexID() {
78   if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID) {
79     if (GetProcess()->HasAssignedIndexIDToThread(
80             m_originating_unique_thread_id)) {
81       return GetProcess()->AssignIndexIDToThread(
82           m_originating_unique_thread_id);
83     }
84   }
85   return LLDB_INVALID_THREAD_ID;
86 }
87