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 21using namespace lldb; 22using namespace lldb_private; 23using namespace llvm; 24 25SBTrace::SBTrace() { LLDB_INSTRUMENT_VA(this); } 26 27SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) { 28 LLDB_INSTRUMENT_VA(this, trace_sp); 29} 30 31SBTrace 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 46SBTraceCursor 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 67SBFileSpec 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 85const 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 93SBError 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 104SBError 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 121SBError 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 131SBError 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 141bool SBTrace::IsValid() { 142 LLDB_INSTRUMENT_VA(this); 143 return this->operator bool(); 144} 145 146SBTrace::operator bool() const { 147 LLDB_INSTRUMENT_VA(this); 148 return (bool)m_opaque_sp; 149} 150