xref: /llvm-project/lldb/source/API/SBTrace.cpp (revision 0642cd768b80665585c8500bed2933a3b99123dc)
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.ref(), trace_description_file.ref());
37 
38   if (!trace_or_err) {
39     error = Status::FromErrorString(toString(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 = Status::FromErrorString("error: invalid trace");
51     return SBTraceCursor();
52   }
53   if (!thread.get()) {
54     error = Status::FromErrorString("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 = Status::FromErrorString(
63         llvm::toString(trace_cursor_sp.takeError()).c_str());
64     return SBTraceCursor();
65   }
66 }
67 
68 SBFileSpec SBTrace::SaveToDisk(SBError &error, const SBFileSpec &bundle_dir,
69                                bool compact) {
70   LLDB_INSTRUMENT_VA(this, error, bundle_dir, compact);
71 
72   error.Clear();
73   SBFileSpec file_spec;
74 
75   if (!m_opaque_sp)
76     error = Status::FromErrorString("error: invalid trace");
77   else if (Expected<FileSpec> desc_file =
78                m_opaque_sp->SaveToDisk(bundle_dir.ref(), compact))
79     file_spec.SetFileSpec(*desc_file);
80   else
81     error =
82         Status::FromErrorString(llvm::toString(desc_file.takeError()).c_str());
83 
84   return file_spec;
85 }
86 
87 const char *SBTrace::GetStartConfigurationHelp() {
88   LLDB_INSTRUMENT_VA(this);
89   if (!m_opaque_sp)
90     return nullptr;
91 
92   return ConstString(m_opaque_sp->GetStartConfigurationHelp()).GetCString();
93 }
94 
95 SBError SBTrace::Start(const SBStructuredData &configuration) {
96   LLDB_INSTRUMENT_VA(this, configuration);
97   SBError error;
98   if (!m_opaque_sp)
99     error = Status::FromErrorString("error: invalid trace");
100   else if (llvm::Error err =
101                m_opaque_sp->Start(configuration.m_impl_up->GetObjectSP()))
102     error = Status::FromErrorString(llvm::toString(std::move(err)).c_str());
103   return error;
104 }
105 
106 SBError SBTrace::Start(const SBThread &thread,
107                        const SBStructuredData &configuration) {
108   LLDB_INSTRUMENT_VA(this, thread, configuration);
109 
110   SBError error;
111   if (!m_opaque_sp)
112     error = Status::FromErrorString("error: invalid trace");
113   else {
114     if (llvm::Error err =
115             m_opaque_sp->Start(std::vector<lldb::tid_t>{thread.GetThreadID()},
116                                configuration.m_impl_up->GetObjectSP()))
117       error = Status::FromErrorString(llvm::toString(std::move(err)).c_str());
118   }
119 
120   return error;
121 }
122 
123 SBError SBTrace::Stop() {
124   LLDB_INSTRUMENT_VA(this);
125   SBError error;
126   if (!m_opaque_sp)
127     error = Status::FromErrorString("error: invalid trace");
128   else if (llvm::Error err = m_opaque_sp->Stop())
129     error = Status::FromErrorString(llvm::toString(std::move(err)).c_str());
130   return error;
131 }
132 
133 SBError SBTrace::Stop(const SBThread &thread) {
134   LLDB_INSTRUMENT_VA(this, thread);
135   SBError error;
136   if (!m_opaque_sp)
137     error = Status::FromErrorString("error: invalid trace");
138   else if (llvm::Error err = m_opaque_sp->Stop({thread.GetThreadID()}))
139     error = Status::FromErrorString(llvm::toString(std::move(err)).c_str());
140   return error;
141 }
142 
143 bool SBTrace::IsValid() {
144   LLDB_INSTRUMENT_VA(this);
145   return this->operator bool();
146 }
147 
148 SBTrace::operator bool() const {
149   LLDB_INSTRUMENT_VA(this);
150   return (bool)m_opaque_sp;
151 }
152