1 | //===-- HistoryThread.cpp -------------------------------------------------===// |
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/LLDBLog.h" |
19 | #include "lldb/Utility/Log.h" |
20 | |
21 | #include <memory> |
22 | |
23 | using namespace lldb; |
24 | using namespace lldb_private; |
25 | |
26 | // Constructor |
27 | |
28 | HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid, |
29 | std::vector<lldb::addr_t> pcs, |
30 | bool pcs_are_call_addresses) |
31 | : Thread(process, tid, true), m_framelist_mutex(), m_framelist(), |
32 | m_pcs(pcs), 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 = |
36 | std::make_unique<HistoryUnwind>(args&: *this, args&: pcs, args&: pcs_are_call_addresses); |
37 | Log *log = GetLog(mask: LLDBLog::Object); |
38 | LLDB_LOGF(log, "%p HistoryThread::HistoryThread" , static_cast<void *>(this)); |
39 | } |
40 | |
41 | // Destructor |
42 | |
43 | HistoryThread::~HistoryThread() { |
44 | Log *log = GetLog(mask: LLDBLog::Object); |
45 | LLDB_LOGF(log, "%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")" , |
46 | static_cast<void *>(this), GetID()); |
47 | DestroyThread(); |
48 | } |
49 | |
50 | lldb::RegisterContextSP HistoryThread::GetRegisterContext() { |
51 | RegisterContextSP rctx; |
52 | if (m_pcs.size() > 0) { |
53 | rctx = std::make_shared<RegisterContextHistory>( |
54 | args&: *this, args: 0, args: GetProcess()->GetAddressByteSize(), args&: m_pcs[0]); |
55 | } |
56 | return rctx; |
57 | } |
58 | |
59 | lldb::RegisterContextSP |
60 | HistoryThread::CreateRegisterContextForFrame(StackFrame *frame) { |
61 | return m_unwinder_up->CreateRegisterContextForFrame(frame); |
62 | } |
63 | |
64 | lldb::StackFrameListSP HistoryThread::GetStackFrameList() { |
65 | // FIXME do not throw away the lock after we acquire it.. |
66 | std::unique_lock<std::mutex> lock(m_framelist_mutex); |
67 | lock.unlock(); |
68 | if (m_framelist.get() == nullptr) { |
69 | m_framelist = |
70 | std::make_shared<StackFrameList>(args&: *this, args: StackFrameListSP(), args: true); |
71 | } |
72 | |
73 | return m_framelist; |
74 | } |
75 | |
76 | uint32_t HistoryThread::GetExtendedBacktraceOriginatingIndexID() { |
77 | if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID) { |
78 | if (GetProcess()->HasAssignedIndexIDToThread( |
79 | sb_thread_id: m_originating_unique_thread_id)) { |
80 | return GetProcess()->AssignIndexIDToThread( |
81 | thread_id: m_originating_unique_thread_id); |
82 | } |
83 | } |
84 | return LLDB_INVALID_THREAD_ID; |
85 | } |
86 | |