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 "lldb/Host/OptionParser.h"
13 #include "lldb/Target/Process.h"
14 #include "lldb/Target/Trace.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 using namespace lldb_private::trace_intel_pt;
19 using namespace llvm;
20 
21 // CommandObjectThreadTraceStartIntelPT
22 
23 #define LLDB_OPTIONS_thread_trace_start_intel_pt
24 #include "TraceIntelPTCommandOptions.inc"
25 
26 Status CommandObjectThreadTraceStartIntelPT::CommandOptions::SetOptionValue(
27     uint32_t option_idx, llvm::StringRef option_arg,
28     ExecutionContext *execution_context) {
29   Status error;
30   const int short_option = m_getopt_table[option_idx].val;
31 
32   switch (short_option) {
33   case 's': {
34     int64_t thread_buffer_size;
35     if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) ||
36         thread_buffer_size < 0)
37       error.SetErrorStringWithFormat("invalid integer value for option '%s'",
38                                      option_arg.str().c_str());
39     else
40       m_thread_buffer_size = thread_buffer_size;
41     break;
42   }
43   default:
44     llvm_unreachable("Unimplemented option");
45   }
46   return error;
47 }
48 
49 void CommandObjectThreadTraceStartIntelPT::CommandOptions::
50     OptionParsingStarting(ExecutionContext *execution_context) {
51   m_thread_buffer_size = 4 * 1024; // 4KB
52 }
53 
54 llvm::ArrayRef<OptionDefinition>
55 CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() {
56   return llvm::makeArrayRef(g_thread_trace_start_intel_pt_options);
57 }
58 
59 bool CommandObjectThreadTraceStartIntelPT::DoExecuteOnThreads(
60     Args &command, CommandReturnObject &result,
61     const std::vector<lldb::tid_t> &tids) {
62   if (Error err = m_trace.Start(tids, m_options.m_thread_buffer_size))
63     result.SetError(toString(std::move(err)));
64   else
65     result.SetStatus(eReturnStatusSuccessFinishResult);
66 
67   return result.Succeeded();
68 }
69 
70 /// CommandObjectProcessTraceStartIntelPT
71 
72 #define LLDB_OPTIONS_process_trace_start_intel_pt
73 #include "TraceIntelPTCommandOptions.inc"
74 
75 Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue(
76     uint32_t option_idx, llvm::StringRef option_arg,
77     ExecutionContext *execution_context) {
78   Status error;
79   const int short_option = m_getopt_table[option_idx].val;
80 
81   switch (short_option) {
82   case 's': {
83     int64_t thread_buffer_size;
84     if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) ||
85         thread_buffer_size < 0)
86       error.SetErrorStringWithFormat("invalid integer value for option '%s'",
87                                      option_arg.str().c_str());
88     else
89       m_thread_buffer_size = thread_buffer_size;
90     break;
91   }
92   case 'l': {
93     int64_t process_buffer_size_limit;
94     if (option_arg.empty() ||
95         option_arg.getAsInteger(0, process_buffer_size_limit) ||
96         process_buffer_size_limit < 0)
97       error.SetErrorStringWithFormat("invalid integer value for option '%s'",
98                                      option_arg.str().c_str());
99     else
100       m_process_buffer_size_limit = process_buffer_size_limit;
101     break;
102   }
103   default:
104     llvm_unreachable("Unimplemented option");
105   }
106   return error;
107 }
108 
109 void CommandObjectProcessTraceStartIntelPT::CommandOptions::
110     OptionParsingStarting(ExecutionContext *execution_context) {
111   m_thread_buffer_size = 4 * 1024;               // 4KB
112   m_process_buffer_size_limit = 5 * 1024 * 1024; // 500MB
113 }
114 
115 llvm::ArrayRef<OptionDefinition>
116 CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() {
117   return llvm::makeArrayRef(g_process_trace_start_intel_pt_options);
118 }
119 
120 bool CommandObjectProcessTraceStartIntelPT::DoExecute(
121     Args &command, CommandReturnObject &result) {
122   if (Error err = m_trace.Start(m_options.m_thread_buffer_size,
123                                 m_options.m_process_buffer_size_limit))
124     result.SetError(toString(std::move(err)));
125   else
126     result.SetStatus(eReturnStatusSuccessFinishResult);
127 
128   return result.Succeeded();
129 }
130