15ffd83dbSDimitry Andric //===-- SBTrace.cpp -------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/Target/Process.h"
1004eeddc0SDimitry Andric #include "lldb/Utility/Instrumentation.h"
110b57cec5SDimitry Andric 
1281ad6265SDimitry Andric #include "lldb/API/SBDebugger.h"
13fe6060f1SDimitry Andric #include "lldb/API/SBStructuredData.h"
14fe6060f1SDimitry Andric #include "lldb/API/SBThread.h"
150b57cec5SDimitry Andric #include "lldb/API/SBTrace.h"
16fe6060f1SDimitry Andric 
17fe6060f1SDimitry Andric #include "lldb/Core/StructuredDataImpl.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include <memory>
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace lldb;
220b57cec5SDimitry Andric using namespace lldb_private;
2381ad6265SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric 
SBTrace()2504eeddc0SDimitry Andric SBTrace::SBTrace() { LLDB_INSTRUMENT_VA(this); }
260b57cec5SDimitry Andric 
SBTrace(const lldb::TraceSP & trace_sp)27fe6060f1SDimitry Andric SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) {
2804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, trace_sp);
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric 
LoadTraceFromFile(SBError & error,SBDebugger & debugger,const SBFileSpec & trace_description_file)3181ad6265SDimitry Andric SBTrace SBTrace::LoadTraceFromFile(SBError &error, SBDebugger &debugger,
3281ad6265SDimitry Andric                                    const SBFileSpec &trace_description_file) {
3381ad6265SDimitry Andric   LLDB_INSTRUMENT_VA(error, debugger, trace_description_file);
3481ad6265SDimitry Andric 
3581ad6265SDimitry Andric   Expected<lldb::TraceSP> trace_or_err = Trace::LoadPostMortemTraceFromFile(
3681ad6265SDimitry Andric       debugger.ref(), trace_description_file.ref());
3781ad6265SDimitry Andric 
3881ad6265SDimitry Andric   if (!trace_or_err) {
3981ad6265SDimitry Andric     error.SetErrorString(toString(trace_or_err.takeError()).c_str());
4081ad6265SDimitry Andric     return SBTrace();
4181ad6265SDimitry Andric   }
4281ad6265SDimitry Andric 
4381ad6265SDimitry Andric   return SBTrace(trace_or_err.get());
4481ad6265SDimitry Andric }
4581ad6265SDimitry Andric 
CreateNewCursor(SBError & error,SBThread & thread)46bdd1243dSDimitry Andric SBTraceCursor SBTrace::CreateNewCursor(SBError &error, SBThread &thread) {
47bdd1243dSDimitry Andric   LLDB_INSTRUMENT_VA(this, error, thread);
48bdd1243dSDimitry Andric 
49bdd1243dSDimitry Andric   if (!m_opaque_sp) {
50bdd1243dSDimitry Andric     error.SetErrorString("error: invalid trace");
51bdd1243dSDimitry Andric     return SBTraceCursor();
52bdd1243dSDimitry Andric   }
53bdd1243dSDimitry Andric   if (!thread.get()) {
54bdd1243dSDimitry Andric     error.SetErrorString("error: invalid thread");
55bdd1243dSDimitry Andric     return SBTraceCursor();
56bdd1243dSDimitry Andric   }
57bdd1243dSDimitry Andric 
58bdd1243dSDimitry Andric   if (llvm::Expected<lldb::TraceCursorSP> trace_cursor_sp =
59bdd1243dSDimitry Andric           m_opaque_sp->CreateNewCursor(*thread.get())) {
60bdd1243dSDimitry Andric     return SBTraceCursor(std::move(*trace_cursor_sp));
61bdd1243dSDimitry Andric   } else {
62bdd1243dSDimitry Andric     error.SetErrorString(llvm::toString(trace_cursor_sp.takeError()).c_str());
63bdd1243dSDimitry Andric     return SBTraceCursor();
64bdd1243dSDimitry Andric   }
65bdd1243dSDimitry Andric }
66bdd1243dSDimitry Andric 
SaveToDisk(SBError & error,const SBFileSpec & bundle_dir,bool compact)67753f127fSDimitry Andric SBFileSpec SBTrace::SaveToDisk(SBError &error, const SBFileSpec &bundle_dir,
68753f127fSDimitry Andric                                bool compact) {
69753f127fSDimitry Andric   LLDB_INSTRUMENT_VA(this, error, bundle_dir, compact);
70753f127fSDimitry Andric 
71753f127fSDimitry Andric   error.Clear();
72753f127fSDimitry Andric   SBFileSpec file_spec;
73753f127fSDimitry Andric 
74753f127fSDimitry Andric   if (!m_opaque_sp)
75753f127fSDimitry Andric     error.SetErrorString("error: invalid trace");
76753f127fSDimitry Andric   else if (Expected<FileSpec> desc_file =
77753f127fSDimitry Andric                m_opaque_sp->SaveToDisk(bundle_dir.ref(), compact))
78753f127fSDimitry Andric     file_spec.SetFileSpec(*desc_file);
79753f127fSDimitry Andric   else
80753f127fSDimitry Andric     error.SetErrorString(llvm::toString(desc_file.takeError()).c_str());
81753f127fSDimitry Andric 
82753f127fSDimitry Andric   return file_spec;
83753f127fSDimitry Andric }
84753f127fSDimitry Andric 
GetStartConfigurationHelp()85fe6060f1SDimitry Andric const char *SBTrace::GetStartConfigurationHelp() {
8604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
8706c3fb27SDimitry Andric   if (!m_opaque_sp)
8806c3fb27SDimitry Andric     return nullptr;
8906c3fb27SDimitry Andric 
9006c3fb27SDimitry Andric   return ConstString(m_opaque_sp->GetStartConfigurationHelp()).GetCString();
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
Start(const SBStructuredData & configuration)93fe6060f1SDimitry Andric SBError SBTrace::Start(const SBStructuredData &configuration) {
9404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, configuration);
95fe6060f1SDimitry Andric   SBError error;
96fe6060f1SDimitry Andric   if (!m_opaque_sp)
97fe6060f1SDimitry Andric     error.SetErrorString("error: invalid trace");
98fe6060f1SDimitry Andric   else if (llvm::Error err =
99fe6060f1SDimitry Andric                m_opaque_sp->Start(configuration.m_impl_up->GetObjectSP()))
100fe6060f1SDimitry Andric     error.SetErrorString(llvm::toString(std::move(err)).c_str());
10104eeddc0SDimitry Andric   return error;
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
Start(const SBThread & thread,const SBStructuredData & configuration)104fe6060f1SDimitry Andric SBError SBTrace::Start(const SBThread &thread,
105fe6060f1SDimitry Andric                        const SBStructuredData &configuration) {
10604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, thread, configuration);
1070b57cec5SDimitry Andric 
108fe6060f1SDimitry Andric   SBError error;
109fe6060f1SDimitry Andric   if (!m_opaque_sp)
110fe6060f1SDimitry Andric     error.SetErrorString("error: invalid trace");
111fe6060f1SDimitry Andric   else {
112fe6060f1SDimitry Andric     if (llvm::Error err =
113fe6060f1SDimitry Andric             m_opaque_sp->Start(std::vector<lldb::tid_t>{thread.GetThreadID()},
114fe6060f1SDimitry Andric                                configuration.m_impl_up->GetObjectSP()))
115fe6060f1SDimitry Andric       error.SetErrorString(llvm::toString(std::move(err)).c_str());
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric 
11804eeddc0SDimitry Andric   return error;
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
Stop()121fe6060f1SDimitry Andric SBError SBTrace::Stop() {
12204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
123fe6060f1SDimitry Andric   SBError error;
124fe6060f1SDimitry Andric   if (!m_opaque_sp)
125fe6060f1SDimitry Andric     error.SetErrorString("error: invalid trace");
126fe6060f1SDimitry Andric   else if (llvm::Error err = m_opaque_sp->Stop())
127fe6060f1SDimitry Andric     error.SetErrorString(llvm::toString(std::move(err)).c_str());
12804eeddc0SDimitry Andric   return error;
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric 
Stop(const SBThread & thread)131fe6060f1SDimitry Andric SBError SBTrace::Stop(const SBThread &thread) {
13204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, thread);
133fe6060f1SDimitry Andric   SBError error;
134fe6060f1SDimitry Andric   if (!m_opaque_sp)
135fe6060f1SDimitry Andric     error.SetErrorString("error: invalid trace");
136fe6060f1SDimitry Andric   else if (llvm::Error err = m_opaque_sp->Stop({thread.GetThreadID()}))
137fe6060f1SDimitry Andric     error.SetErrorString(llvm::toString(std::move(err)).c_str());
13804eeddc0SDimitry Andric   return error;
1390b57cec5SDimitry Andric }
1400b57cec5SDimitry Andric 
IsValid()1410b57cec5SDimitry Andric bool SBTrace::IsValid() {
14204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1430b57cec5SDimitry Andric   return this->operator bool();
1440b57cec5SDimitry Andric }
145fe6060f1SDimitry Andric 
operator bool() const1460b57cec5SDimitry Andric SBTrace::operator bool() const {
14704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
148fe6060f1SDimitry Andric   return (bool)m_opaque_sp;
1490b57cec5SDimitry Andric }
150