1 //===-- CommandObjectThreadTraceExportCTF.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 "CommandObjectThreadTraceExportCTF.h" 10 11 #include "../common/TraceHTR.h" 12 #include "lldb/Host/OptionParser.h" 13 #include "lldb/Target/Process.h" 14 #include "lldb/Target/Trace.h" 15 16 using namespace lldb; 17 using namespace lldb_private; 18 using namespace lldb_private::ctf; 19 using namespace llvm; 20 21 // CommandObjectThreadTraceExportCTF 22 23 #define LLDB_OPTIONS_thread_trace_export_ctf 24 #include "TraceExporterCTFCommandOptions.inc" 25 26 Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue( 27 uint32_t option_idx, llvm::StringRef option_arg, 28 ExecutionContext *execution_context) { 29 Status error; 30 const int short_option = m_getopt_table[option_idx].val; 31 32 switch (short_option) { 33 case 'f': { 34 m_file.assign(std::string(option_arg)); 35 break; 36 } 37 case 't': { 38 int64_t thread_index; 39 if (option_arg.empty() || option_arg.getAsInteger(0, thread_index) || 40 thread_index < 0) 41 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 42 option_arg.str().c_str()); 43 else 44 m_thread_index = thread_index; 45 break; 46 } 47 default: 48 llvm_unreachable("Unimplemented option"); 49 } 50 return error; 51 } 52 53 void CommandObjectThreadTraceExportCTF::CommandOptions::OptionParsingStarting( 54 ExecutionContext *execution_context) { 55 m_file.clear(); 56 m_thread_index = None; 57 } 58 59 llvm::ArrayRef<OptionDefinition> 60 CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() { 61 return llvm::makeArrayRef(g_thread_trace_export_ctf_options); 62 } 63 64 bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command, 65 CommandReturnObject &result) { 66 const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace(); 67 Process *process = m_exe_ctx.GetProcessPtr(); 68 Thread *thread = m_options.m_thread_index 69 ? process->GetThreadList() 70 .FindThreadByIndexID(*m_options.m_thread_index) 71 .get() 72 : GetDefaultThread(); 73 74 if (thread == nullptr) { 75 const uint32_t num_threads = process->GetThreadList().GetSize(); 76 size_t tid = m_options.m_thread_index ? *m_options.m_thread_index 77 : LLDB_INVALID_THREAD_ID; 78 result.AppendErrorWithFormatv( 79 "Thread index {0} is out of range (valid values are 1 - {1}).\n", tid, 80 num_threads); 81 return false; 82 } else { 83 TraceHTR htr(*thread, *trace_sp->GetCursor(*thread)); 84 htr.ExecutePasses(); 85 if (llvm::Error err = htr.Export(m_options.m_file)) { 86 result.AppendErrorWithFormat("%s\n", toString(std::move(err)).c_str()); 87 return false; 88 } else { 89 return true; 90 } 91 } 92 } 93