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