1 //===-- CommandObjectTraceStartIntelPT.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 "CommandObjectTraceStartIntelPT.h" 10 11 #include "TraceIntelPT.h" 12 #include "TraceIntelPTConstants.h" 13 #include "lldb/Host/OptionParser.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::trace_intel_pt; 20 using namespace llvm; 21 22 // CommandObjectThreadTraceStartIntelPT 23 24 #define LLDB_OPTIONS_thread_trace_start_intel_pt 25 #include "TraceIntelPTCommandOptions.inc" 26 27 Status CommandObjectThreadTraceStartIntelPT::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 's': { 35 int64_t ipt_trace_size; 36 if (option_arg.empty() || option_arg.getAsInteger(0, ipt_trace_size) || 37 ipt_trace_size < 0) 38 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 39 option_arg.str().c_str()); 40 else 41 m_ipt_trace_size = ipt_trace_size; 42 break; 43 } 44 case 't': { 45 m_enable_tsc = true; 46 break; 47 } 48 case 'p': { 49 int64_t psb_period; 50 if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) || 51 psb_period < 0) 52 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 53 option_arg.str().c_str()); 54 else 55 m_psb_period = psb_period; 56 break; 57 } 58 default: 59 llvm_unreachable("Unimplemented option"); 60 } 61 return error; 62 } 63 64 void CommandObjectThreadTraceStartIntelPT::CommandOptions:: 65 OptionParsingStarting(ExecutionContext *execution_context) { 66 m_ipt_trace_size = kDefaultIptTraceSize; 67 m_enable_tsc = kDefaultEnableTscValue; 68 m_psb_period = kDefaultPsbPeriod; 69 } 70 71 llvm::ArrayRef<OptionDefinition> 72 CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() { 73 return llvm::makeArrayRef(g_thread_trace_start_intel_pt_options); 74 } 75 76 bool CommandObjectThreadTraceStartIntelPT::DoExecuteOnThreads( 77 Args &command, CommandReturnObject &result, 78 llvm::ArrayRef<lldb::tid_t> tids) { 79 if (Error err = m_trace.Start(tids, m_options.m_ipt_trace_size, 80 m_options.m_enable_tsc, m_options.m_psb_period)) 81 result.SetError(Status(std::move(err))); 82 else 83 result.SetStatus(eReturnStatusSuccessFinishResult); 84 85 return result.Succeeded(); 86 } 87 88 /// CommandObjectProcessTraceStartIntelPT 89 90 #define LLDB_OPTIONS_process_trace_start_intel_pt 91 #include "TraceIntelPTCommandOptions.inc" 92 93 Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue( 94 uint32_t option_idx, llvm::StringRef option_arg, 95 ExecutionContext *execution_context) { 96 Status error; 97 const int short_option = m_getopt_table[option_idx].val; 98 99 switch (short_option) { 100 case 's': { 101 int64_t ipt_trace_size; 102 if (option_arg.empty() || option_arg.getAsInteger(0, ipt_trace_size) || 103 ipt_trace_size < 0) 104 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 105 option_arg.str().c_str()); 106 else 107 m_ipt_trace_size = ipt_trace_size; 108 break; 109 } 110 case 'l': { 111 int64_t process_buffer_size_limit; 112 if (option_arg.empty() || 113 option_arg.getAsInteger(0, process_buffer_size_limit) || 114 process_buffer_size_limit < 0) 115 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 116 option_arg.str().c_str()); 117 else 118 m_process_buffer_size_limit = process_buffer_size_limit; 119 break; 120 } 121 case 't': { 122 m_enable_tsc = true; 123 break; 124 } 125 case 'c': { 126 m_per_cpu_tracing = true; 127 break; 128 } 129 case 'p': { 130 int64_t psb_period; 131 if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) || 132 psb_period < 0) 133 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 134 option_arg.str().c_str()); 135 else 136 m_psb_period = psb_period; 137 break; 138 } 139 default: 140 llvm_unreachable("Unimplemented option"); 141 } 142 return error; 143 } 144 145 void CommandObjectProcessTraceStartIntelPT::CommandOptions:: 146 OptionParsingStarting(ExecutionContext *execution_context) { 147 m_ipt_trace_size = kDefaultIptTraceSize; 148 m_process_buffer_size_limit = kDefaultProcessBufferSizeLimit; 149 m_enable_tsc = kDefaultEnableTscValue; 150 m_psb_period = kDefaultPsbPeriod; 151 m_per_cpu_tracing = kDefaultPerCpuTracing; 152 } 153 154 llvm::ArrayRef<OptionDefinition> 155 CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() { 156 return llvm::makeArrayRef(g_process_trace_start_intel_pt_options); 157 } 158 159 bool CommandObjectProcessTraceStartIntelPT::DoExecute( 160 Args &command, CommandReturnObject &result) { 161 if (Error err = m_trace.Start(m_options.m_ipt_trace_size, 162 m_options.m_process_buffer_size_limit, 163 m_options.m_enable_tsc, m_options.m_psb_period, 164 m_options.m_per_cpu_tracing)) 165 result.SetError(Status(std::move(err))); 166 else 167 result.SetStatus(eReturnStatusSuccessFinishResult); 168 169 return result.Succeeded(); 170 } 171