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
SBTrace()25 SBTrace::SBTrace() { LLDB_INSTRUMENT_VA(this); }
26
SBTrace(const lldb::TraceSP & trace_sp)27 SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) {
28 LLDB_INSTRUMENT_VA(this, trace_sp);
29 }
30
LoadTraceFromFile(SBError & error,SBDebugger & debugger,const SBFileSpec & trace_description_file)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.ref(), trace_description_file.ref());
37
38 if (!trace_or_err) {
39 error.SetErrorString(toString(trace_or_err.takeError()).c_str());
40 return SBTrace();
41 }
42
43 return SBTrace(trace_or_err.get());
44 }
45
CreateNewCursor(SBError & error,SBThread & thread)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.get())) {
60 return SBTraceCursor(std::move(*trace_cursor_sp));
61 } else {
62 error.SetErrorString(llvm::toString(trace_cursor_sp.takeError()).c_str());
63 return SBTraceCursor();
64 }
65 }
66
SaveToDisk(SBError & error,const SBFileSpec & bundle_dir,bool compact)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(bundle_dir.ref(), compact))
78 file_spec.SetFileSpec(*desc_file);
79 else
80 error.SetErrorString(llvm::toString(desc_file.takeError()).c_str());
81
82 return file_spec;
83 }
84
GetStartConfigurationHelp()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
Start(const SBStructuredData & configuration)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.m_impl_up->GetObjectSP()))
100 error.SetErrorString(llvm::toString(std::move(err)).c_str());
101 return error;
102 }
103
Start(const SBThread & thread,const SBStructuredData & configuration)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(std::vector<lldb::tid_t>{thread.GetThreadID()},
114 configuration.m_impl_up->GetObjectSP()))
115 error.SetErrorString(llvm::toString(std::move(err)).c_str());
116 }
117
118 return error;
119 }
120
Stop()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(std::move(err)).c_str());
128 return error;
129 }
130
Stop(const SBThread & thread)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({thread.GetThreadID()}))
137 error.SetErrorString(llvm::toString(std::move(err)).c_str());
138 return error;
139 }
140
IsValid()141 bool SBTrace::IsValid() {
142 LLDB_INSTRUMENT_VA(this);
143 return this->operator bool();
144 }
145
operator bool() const146 SBTrace::operator bool() const {
147 LLDB_INSTRUMENT_VA(this);
148 return (bool)m_opaque_sp;
149 }
150