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 return m_opaque_sp ? m_opaque_sp->GetStartConfigurationHelp() : nullptr; 88 } 89 90 SBError SBTrace::Start(const SBStructuredData &configuration) { 91 LLDB_INSTRUMENT_VA(this, configuration); 92 SBError error; 93 if (!m_opaque_sp) 94 error.SetErrorString("error: invalid trace"); 95 else if (llvm::Error err = 96 m_opaque_sp->Start(configuration.m_impl_up->GetObjectSP())) 97 error.SetErrorString(llvm::toString(std::move(err)).c_str()); 98 return error; 99 } 100 101 SBError SBTrace::Start(const SBThread &thread, 102 const SBStructuredData &configuration) { 103 LLDB_INSTRUMENT_VA(this, thread, configuration); 104 105 SBError error; 106 if (!m_opaque_sp) 107 error.SetErrorString("error: invalid trace"); 108 else { 109 if (llvm::Error err = 110 m_opaque_sp->Start(std::vector<lldb::tid_t>{thread.GetThreadID()}, 111 configuration.m_impl_up->GetObjectSP())) 112 error.SetErrorString(llvm::toString(std::move(err)).c_str()); 113 } 114 115 return error; 116 } 117 118 SBError SBTrace::Stop() { 119 LLDB_INSTRUMENT_VA(this); 120 SBError error; 121 if (!m_opaque_sp) 122 error.SetErrorString("error: invalid trace"); 123 else if (llvm::Error err = m_opaque_sp->Stop()) 124 error.SetErrorString(llvm::toString(std::move(err)).c_str()); 125 return error; 126 } 127 128 SBError SBTrace::Stop(const SBThread &thread) { 129 LLDB_INSTRUMENT_VA(this, thread); 130 SBError error; 131 if (!m_opaque_sp) 132 error.SetErrorString("error: invalid trace"); 133 else if (llvm::Error err = m_opaque_sp->Stop({thread.GetThreadID()})) 134 error.SetErrorString(llvm::toString(std::move(err)).c_str()); 135 return error; 136 } 137 138 bool SBTrace::IsValid() { 139 LLDB_INSTRUMENT_VA(this); 140 return this->operator bool(); 141 } 142 143 SBTrace::operator bool() const { 144 LLDB_INSTRUMENT_VA(this); 145 return (bool)m_opaque_sp; 146 } 147