| //===-- SBTrace.cpp -------------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "lldb/Target/Process.h" | |
| #include "lldb/Utility/Instrumentation.h" | |
| #include "lldb/API/SBDebugger.h" | |
| #include "lldb/API/SBStructuredData.h" | |
| #include "lldb/API/SBThread.h" | |
| #include "lldb/API/SBTrace.h" | |
| #include "lldb/Core/StructuredDataImpl.h" | |
| #include <memory> | |
| using namespace lldb; | |
| using namespace lldb_private; | |
| using namespace llvm; | |
| SBTrace::SBTrace() { LLDB_INSTRUMENT_VA(this); } | |
| SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) { | |
| LLDB_INSTRUMENT_VA(this, trace_sp); | |
| } | |
| SBTrace SBTrace::LoadTraceFromFile(SBError &error, SBDebugger &debugger, | |
| const SBFileSpec &trace_description_file) { | |
| LLDB_INSTRUMENT_VA(error, debugger, trace_description_file); | |
| Expected<lldb::TraceSP> trace_or_err = Trace::LoadPostMortemTraceFromFile( | |
| debugger.ref(), trace_description_file.ref()); | |
| if (!trace_or_err) { | |
| error = Status::FromErrorString(toString(trace_or_err.takeError()).c_str()); | |
| return SBTrace(); | |
| } | |
| return SBTrace(trace_or_err.get()); | |
| } | |
| SBTraceCursor SBTrace::CreateNewCursor(SBError &error, SBThread &thread) { | |
| LLDB_INSTRUMENT_VA(this, error, thread); | |
| if (!m_opaque_sp) { | |
| error = Status::FromErrorString("error: invalid trace"); | |
| return SBTraceCursor(); | |
| } | |
| if (!thread.get()) { | |
| error = Status::FromErrorString("error: invalid thread"); | |
| return SBTraceCursor(); | |
| } | |
| if (llvm::Expected<lldb::TraceCursorSP> trace_cursor_sp = | |
| m_opaque_sp->CreateNewCursor(*thread.get())) { | |
| return SBTraceCursor(std::move(*trace_cursor_sp)); | |
| } else { | |
| error = Status::FromErrorString( | |
| llvm::toString(trace_cursor_sp.takeError()).c_str()); | |
| return SBTraceCursor(); | |
| } | |
| } | |
| SBFileSpec SBTrace::SaveToDisk(SBError &error, const SBFileSpec &bundle_dir, | |
| bool compact) { | |
| LLDB_INSTRUMENT_VA(this, error, bundle_dir, compact); | |
| error.Clear(); | |
| SBFileSpec file_spec; | |
| if (!m_opaque_sp) | |
| error = Status::FromErrorString("error: invalid trace"); | |
| else if (Expected<FileSpec> desc_file = | |
| m_opaque_sp->SaveToDisk(bundle_dir.ref(), compact)) | |
| file_spec.SetFileSpec(*desc_file); | |
| else | |
| error = | |
| Status::FromErrorString(llvm::toString(desc_file.takeError()).c_str()); | |
| return file_spec; | |
| } | |
| const char *SBTrace::GetStartConfigurationHelp() { | |
| LLDB_INSTRUMENT_VA(this); | |
| if (!m_opaque_sp) | |
| return nullptr; | |
| return ConstString(m_opaque_sp->GetStartConfigurationHelp()).GetCString(); | |
| } | |
| SBError SBTrace::Start(const SBStructuredData &configuration) { | |
| LLDB_INSTRUMENT_VA(this, configuration); | |
| SBError error; | |
| if (!m_opaque_sp) | |
| error = Status::FromErrorString("error: invalid trace"); | |
| else if (llvm::Error err = | |
| m_opaque_sp->Start(configuration.m_impl_up->GetObjectSP())) | |
| error = Status::FromErrorString(llvm::toString(std::move(err)).c_str()); | |
| return error; | |
| } | |
| SBError SBTrace::Start(const SBThread &thread, | |
| const SBStructuredData &configuration) { | |
| LLDB_INSTRUMENT_VA(this, thread, configuration); | |
| SBError error; | |
| if (!m_opaque_sp) | |
| error = Status::FromErrorString("error: invalid trace"); | |
| else { | |
| if (llvm::Error err = | |
| m_opaque_sp->Start(std::vector<lldb::tid_t>{thread.GetThreadID()}, | |
| configuration.m_impl_up->GetObjectSP())) | |
| error = Status::FromErrorString(llvm::toString(std::move(err)).c_str()); | |
| } | |
| return error; | |
| } | |
| SBError SBTrace::Stop() { | |
| LLDB_INSTRUMENT_VA(this); | |
| SBError error; | |
| if (!m_opaque_sp) | |
| error = Status::FromErrorString("error: invalid trace"); | |
| else if (llvm::Error err = m_opaque_sp->Stop()) | |
| error = Status::FromErrorString(llvm::toString(std::move(err)).c_str()); | |
| return error; | |
| } | |
| SBError SBTrace::Stop(const SBThread &thread) { | |
| LLDB_INSTRUMENT_VA(this, thread); | |
| SBError error; | |
| if (!m_opaque_sp) | |
| error = Status::FromErrorString("error: invalid trace"); | |
| else if (llvm::Error err = m_opaque_sp->Stop({thread.GetThreadID()})) | |
| error = Status::FromErrorString(llvm::toString(std::move(err)).c_str()); | |
| return error; | |
| } | |
| bool SBTrace::IsValid() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return this->operator bool(); | |
| } | |
| SBTrace::operator bool() const { | |
| LLDB_INSTRUMENT_VA(this); | |
| return (bool)m_opaque_sp; | |
| } |