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
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)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::
OptionParsingStarting(ExecutionContext * execution_context)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>
GetDefinitions()72 CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() {
73 return llvm::makeArrayRef(g_thread_trace_start_intel_pt_options);
74 }
75
DoExecuteOnThreads(Args & command,CommandReturnObject & result,llvm::ArrayRef<lldb::tid_t> tids)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
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)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::
OptionParsingStarting(ExecutionContext * execution_context)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>
GetDefinitions()150 CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() {
151 return llvm::makeArrayRef(g_process_trace_start_intel_pt_options);
152 }
153
DoExecute(Args & command,CommandReturnObject & result)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