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.SetErrorString(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.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 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 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.m_impl_up->GetObjectSP())) 100 error.SetErrorString(llvm::toString(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(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 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 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 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