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