1 | //===-- SBTrace.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/Target/Process.h" |
10 | #include "lldb/Utility/Instrumentation.h" |
11 | |
12 | #include "lldb/API/SBDebugger.h" |
13 | #include "lldb/API/SBStructuredData.h" |
14 | #include "lldb/API/SBThread.h" |
15 | #include "lldb/API/SBTrace.h" |
16 | |
17 | #include "lldb/Core/StructuredDataImpl.h" |
18 | |
19 | #include <memory> |
20 | |
21 | using namespace lldb; |
22 | using namespace lldb_private; |
23 | using namespace llvm; |
24 | |
25 | SBTrace::SBTrace() { LLDB_INSTRUMENT_VA(this); } |
26 | |
27 | SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) { |
28 | LLDB_INSTRUMENT_VA(this, trace_sp); |
29 | } |
30 | |
31 | SBTrace SBTrace::LoadTraceFromFile(SBError &error, SBDebugger &debugger, |
32 | const SBFileSpec &trace_description_file) { |
33 | LLDB_INSTRUMENT_VA(error, debugger, trace_description_file); |
34 | |
35 | Expected<lldb::TraceSP> trace_or_err = Trace::LoadPostMortemTraceFromFile( |
36 | debugger&: debugger.ref(), trace_description_file: trace_description_file.ref()); |
37 | |
38 | if (!trace_or_err) { |
39 | error.SetErrorString(toString(E: trace_or_err.takeError()).c_str()); |
40 | return SBTrace(); |
41 | } |
42 | |
43 | return SBTrace(trace_or_err.get()); |
44 | } |
45 | |
46 | SBTraceCursor SBTrace::CreateNewCursor(SBError &error, SBThread &thread) { |
47 | LLDB_INSTRUMENT_VA(this, error, thread); |
48 | |
49 | if (!m_opaque_sp) { |
50 | error.SetErrorString("error: invalid trace" ); |
51 | return SBTraceCursor(); |
52 | } |
53 | if (!thread.get()) { |
54 | error.SetErrorString("error: invalid thread" ); |
55 | return SBTraceCursor(); |
56 | } |
57 | |
58 | if (llvm::Expected<lldb::TraceCursorSP> trace_cursor_sp = |
59 | m_opaque_sp->CreateNewCursor(thread&: *thread.get())) { |
60 | return SBTraceCursor(std::move(*trace_cursor_sp)); |
61 | } else { |
62 | error.SetErrorString(llvm::toString(E: trace_cursor_sp.takeError()).c_str()); |
63 | return SBTraceCursor(); |
64 | } |
65 | } |
66 | |
67 | SBFileSpec SBTrace::SaveToDisk(SBError &error, const SBFileSpec &bundle_dir, |
68 | bool compact) { |
69 | LLDB_INSTRUMENT_VA(this, error, bundle_dir, compact); |
70 | |
71 | error.Clear(); |
72 | SBFileSpec file_spec; |
73 | |
74 | if (!m_opaque_sp) |
75 | error.SetErrorString("error: invalid trace" ); |
76 | else if (Expected<FileSpec> desc_file = |
77 | m_opaque_sp->SaveToDisk(directory: bundle_dir.ref(), compact)) |
78 | file_spec.SetFileSpec(*desc_file); |
79 | else |
80 | error.SetErrorString(llvm::toString(E: desc_file.takeError()).c_str()); |
81 | |
82 | return file_spec; |
83 | } |
84 | |
85 | const char *SBTrace::GetStartConfigurationHelp() { |
86 | LLDB_INSTRUMENT_VA(this); |
87 | if (!m_opaque_sp) |
88 | return nullptr; |
89 | |
90 | return ConstString(m_opaque_sp->GetStartConfigurationHelp()).GetCString(); |
91 | } |
92 | |
93 | SBError SBTrace::Start(const SBStructuredData &configuration) { |
94 | LLDB_INSTRUMENT_VA(this, configuration); |
95 | SBError error; |
96 | if (!m_opaque_sp) |
97 | error.SetErrorString("error: invalid trace" ); |
98 | else if (llvm::Error err = |
99 | m_opaque_sp->Start(configuration: configuration.m_impl_up->GetObjectSP())) |
100 | error.SetErrorString(llvm::toString(E: std::move(err)).c_str()); |
101 | return error; |
102 | } |
103 | |
104 | SBError SBTrace::Start(const SBThread &thread, |
105 | const SBStructuredData &configuration) { |
106 | LLDB_INSTRUMENT_VA(this, thread, configuration); |
107 | |
108 | SBError error; |
109 | if (!m_opaque_sp) |
110 | error.SetErrorString("error: invalid trace" ); |
111 | else { |
112 | if (llvm::Error err = |
113 | m_opaque_sp->Start(tids: std::vector<lldb::tid_t>{thread.GetThreadID()}, |
114 | configuration: configuration.m_impl_up->GetObjectSP())) |
115 | error.SetErrorString(llvm::toString(E: std::move(err)).c_str()); |
116 | } |
117 | |
118 | return error; |
119 | } |
120 | |
121 | SBError SBTrace::Stop() { |
122 | LLDB_INSTRUMENT_VA(this); |
123 | SBError error; |
124 | if (!m_opaque_sp) |
125 | error.SetErrorString("error: invalid trace" ); |
126 | else if (llvm::Error err = m_opaque_sp->Stop()) |
127 | error.SetErrorString(llvm::toString(E: std::move(err)).c_str()); |
128 | return error; |
129 | } |
130 | |
131 | SBError SBTrace::Stop(const SBThread &thread) { |
132 | LLDB_INSTRUMENT_VA(this, thread); |
133 | SBError error; |
134 | if (!m_opaque_sp) |
135 | error.SetErrorString("error: invalid trace" ); |
136 | else if (llvm::Error err = m_opaque_sp->Stop(tids: {thread.GetThreadID()})) |
137 | error.SetErrorString(llvm::toString(E: std::move(err)).c_str()); |
138 | return error; |
139 | } |
140 | |
141 | bool SBTrace::IsValid() { |
142 | LLDB_INSTRUMENT_VA(this); |
143 | return this->operator bool(); |
144 | } |
145 | |
146 | SBTrace::operator bool() const { |
147 | LLDB_INSTRUMENT_VA(this); |
148 | return (bool)m_opaque_sp; |
149 | } |
150 | |