xref: /llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp (revision 6a5355e8a159bd9c058d4fbba2a87e0465fe0dc7)
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