15ffd83dbSDimitry Andric //===-- SBTrace.cpp -------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "lldb/Target/Process.h" 1004eeddc0SDimitry Andric #include "lldb/Utility/Instrumentation.h" 110b57cec5SDimitry Andric 1281ad6265SDimitry Andric #include "lldb/API/SBDebugger.h" 13fe6060f1SDimitry Andric #include "lldb/API/SBStructuredData.h" 14fe6060f1SDimitry Andric #include "lldb/API/SBThread.h" 150b57cec5SDimitry Andric #include "lldb/API/SBTrace.h" 16fe6060f1SDimitry Andric 17fe6060f1SDimitry Andric #include "lldb/Core/StructuredDataImpl.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric #include <memory> 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric using namespace lldb; 220b57cec5SDimitry Andric using namespace lldb_private; 2381ad6265SDimitry Andric using namespace llvm; 240b57cec5SDimitry Andric 2504eeddc0SDimitry Andric SBTrace::SBTrace() { LLDB_INSTRUMENT_VA(this); } 260b57cec5SDimitry Andric 27fe6060f1SDimitry Andric SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) { 2804eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, trace_sp); 290b57cec5SDimitry Andric } 300b57cec5SDimitry Andric 3181ad6265SDimitry Andric SBTrace SBTrace::LoadTraceFromFile(SBError &error, SBDebugger &debugger, 3281ad6265SDimitry Andric const SBFileSpec &trace_description_file) { 3381ad6265SDimitry Andric LLDB_INSTRUMENT_VA(error, debugger, trace_description_file); 3481ad6265SDimitry Andric 3581ad6265SDimitry Andric Expected<lldb::TraceSP> trace_or_err = Trace::LoadPostMortemTraceFromFile( 3681ad6265SDimitry Andric debugger.ref(), trace_description_file.ref()); 3781ad6265SDimitry Andric 3881ad6265SDimitry Andric if (!trace_or_err) { 3981ad6265SDimitry Andric error.SetErrorString(toString(trace_or_err.takeError()).c_str()); 4081ad6265SDimitry Andric return SBTrace(); 4181ad6265SDimitry Andric } 4281ad6265SDimitry Andric 4381ad6265SDimitry Andric return SBTrace(trace_or_err.get()); 4481ad6265SDimitry Andric } 4581ad6265SDimitry Andric 46*bdd1243dSDimitry Andric SBTraceCursor SBTrace::CreateNewCursor(SBError &error, SBThread &thread) { 47*bdd1243dSDimitry Andric LLDB_INSTRUMENT_VA(this, error, thread); 48*bdd1243dSDimitry Andric 49*bdd1243dSDimitry Andric if (!m_opaque_sp) { 50*bdd1243dSDimitry Andric error.SetErrorString("error: invalid trace"); 51*bdd1243dSDimitry Andric return SBTraceCursor(); 52*bdd1243dSDimitry Andric } 53*bdd1243dSDimitry Andric if (!thread.get()) { 54*bdd1243dSDimitry Andric error.SetErrorString("error: invalid thread"); 55*bdd1243dSDimitry Andric return SBTraceCursor(); 56*bdd1243dSDimitry Andric } 57*bdd1243dSDimitry Andric 58*bdd1243dSDimitry Andric if (llvm::Expected<lldb::TraceCursorSP> trace_cursor_sp = 59*bdd1243dSDimitry Andric m_opaque_sp->CreateNewCursor(*thread.get())) { 60*bdd1243dSDimitry Andric return SBTraceCursor(std::move(*trace_cursor_sp)); 61*bdd1243dSDimitry Andric } else { 62*bdd1243dSDimitry Andric error.SetErrorString(llvm::toString(trace_cursor_sp.takeError()).c_str()); 63*bdd1243dSDimitry Andric return SBTraceCursor(); 64*bdd1243dSDimitry Andric } 65*bdd1243dSDimitry Andric } 66*bdd1243dSDimitry Andric 67753f127fSDimitry Andric SBFileSpec SBTrace::SaveToDisk(SBError &error, const SBFileSpec &bundle_dir, 68753f127fSDimitry Andric bool compact) { 69753f127fSDimitry Andric LLDB_INSTRUMENT_VA(this, error, bundle_dir, compact); 70753f127fSDimitry Andric 71753f127fSDimitry Andric error.Clear(); 72753f127fSDimitry Andric SBFileSpec file_spec; 73753f127fSDimitry Andric 74753f127fSDimitry Andric if (!m_opaque_sp) 75753f127fSDimitry Andric error.SetErrorString("error: invalid trace"); 76753f127fSDimitry Andric else if (Expected<FileSpec> desc_file = 77753f127fSDimitry Andric m_opaque_sp->SaveToDisk(bundle_dir.ref(), compact)) 78753f127fSDimitry Andric file_spec.SetFileSpec(*desc_file); 79753f127fSDimitry Andric else 80753f127fSDimitry Andric error.SetErrorString(llvm::toString(desc_file.takeError()).c_str()); 81753f127fSDimitry Andric 82753f127fSDimitry Andric return file_spec; 83753f127fSDimitry Andric } 84753f127fSDimitry Andric 85fe6060f1SDimitry Andric const char *SBTrace::GetStartConfigurationHelp() { 8604eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this); 8704eeddc0SDimitry Andric return m_opaque_sp ? m_opaque_sp->GetStartConfigurationHelp() : nullptr; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 90fe6060f1SDimitry Andric SBError SBTrace::Start(const SBStructuredData &configuration) { 9104eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, configuration); 92fe6060f1SDimitry Andric SBError error; 93fe6060f1SDimitry Andric if (!m_opaque_sp) 94fe6060f1SDimitry Andric error.SetErrorString("error: invalid trace"); 95fe6060f1SDimitry Andric else if (llvm::Error err = 96fe6060f1SDimitry Andric m_opaque_sp->Start(configuration.m_impl_up->GetObjectSP())) 97fe6060f1SDimitry Andric error.SetErrorString(llvm::toString(std::move(err)).c_str()); 9804eeddc0SDimitry Andric return error; 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 101fe6060f1SDimitry Andric SBError SBTrace::Start(const SBThread &thread, 102fe6060f1SDimitry Andric const SBStructuredData &configuration) { 10304eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, thread, configuration); 1040b57cec5SDimitry Andric 105fe6060f1SDimitry Andric SBError error; 106fe6060f1SDimitry Andric if (!m_opaque_sp) 107fe6060f1SDimitry Andric error.SetErrorString("error: invalid trace"); 108fe6060f1SDimitry Andric else { 109fe6060f1SDimitry Andric if (llvm::Error err = 110fe6060f1SDimitry Andric m_opaque_sp->Start(std::vector<lldb::tid_t>{thread.GetThreadID()}, 111fe6060f1SDimitry Andric configuration.m_impl_up->GetObjectSP())) 112fe6060f1SDimitry Andric error.SetErrorString(llvm::toString(std::move(err)).c_str()); 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 11504eeddc0SDimitry Andric return error; 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 118fe6060f1SDimitry Andric SBError SBTrace::Stop() { 11904eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this); 120fe6060f1SDimitry Andric SBError error; 121fe6060f1SDimitry Andric if (!m_opaque_sp) 122fe6060f1SDimitry Andric error.SetErrorString("error: invalid trace"); 123fe6060f1SDimitry Andric else if (llvm::Error err = m_opaque_sp->Stop()) 124fe6060f1SDimitry Andric error.SetErrorString(llvm::toString(std::move(err)).c_str()); 12504eeddc0SDimitry Andric return error; 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 128fe6060f1SDimitry Andric SBError SBTrace::Stop(const SBThread &thread) { 12904eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this, thread); 130fe6060f1SDimitry Andric SBError error; 131fe6060f1SDimitry Andric if (!m_opaque_sp) 132fe6060f1SDimitry Andric error.SetErrorString("error: invalid trace"); 133fe6060f1SDimitry Andric else if (llvm::Error err = m_opaque_sp->Stop({thread.GetThreadID()})) 134fe6060f1SDimitry Andric error.SetErrorString(llvm::toString(std::move(err)).c_str()); 13504eeddc0SDimitry Andric return error; 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric bool SBTrace::IsValid() { 13904eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this); 1400b57cec5SDimitry Andric return this->operator bool(); 1410b57cec5SDimitry Andric } 142fe6060f1SDimitry Andric 1430b57cec5SDimitry Andric SBTrace::operator bool() const { 14404eeddc0SDimitry Andric LLDB_INSTRUMENT_VA(this); 145fe6060f1SDimitry Andric return (bool)m_opaque_sp; 1460b57cec5SDimitry Andric } 147