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 thread_buffer_size; 36 if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) || 37 thread_buffer_size < 0) 38 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 39 option_arg.str().c_str()); 40 else 41 m_thread_buffer_size = thread_buffer_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_thread_buffer_size = kDefaultThreadBufferSize; 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_thread_buffer_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 thread_buffer_size; 102 if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) || 103 thread_buffer_size < 0) 104 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 105 option_arg.str().c_str()); 106 else 107 m_thread_buffer_size = thread_buffer_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 'p': { 126 int64_t psb_period; 127 if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) || 128 psb_period < 0) 129 error.SetErrorStringWithFormat("invalid integer value for option '%s'", 130 option_arg.str().c_str()); 131 else 132 m_psb_period = psb_period; 133 break; 134 } 135 default: 136 llvm_unreachable("Unimplemented option"); 137 } 138 return error; 139 } 140 141 void CommandObjectProcessTraceStartIntelPT::CommandOptions:: 142 OptionParsingStarting(ExecutionContext *execution_context) { 143 m_thread_buffer_size = kDefaultThreadBufferSize; 144 m_process_buffer_size_limit = kDefaultProcessBufferSizeLimit; 145 m_enable_tsc = kDefaultEnableTscValue; 146 m_psb_period = kDefaultPsbPeriod; 147 } 148 149 llvm::ArrayRef<OptionDefinition> 150 CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() { 151 return llvm::makeArrayRef(g_process_trace_start_intel_pt_options); 152 } 153 154 bool CommandObjectProcessTraceStartIntelPT::DoExecute( 155 Args &command, CommandReturnObject &result) { 156 if (Error err = m_trace.Start(m_options.m_thread_buffer_size, 157 m_options.m_process_buffer_size_limit, 158 m_options.m_enable_tsc, m_options.m_psb_period)) 159 result.SetError(Status(std::move(err))); 160 else 161 result.SetStatus(eReturnStatusSuccessFinishResult); 162 163 return result.Succeeded(); 164 } 165