]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdGdbShow.cpp
MFV r348534: 9616 Bogus error when attempting to set property on read-only pool
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdCmdGdbShow.cpp
1 //===-- MICmdCmdGdbShow.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // Overview:    CMICmdCmdGdbShow implementation.
11
12 // Third party headers:
13 #include "lldb/API/SBCompileUnit.h"
14 #include "lldb/API/SBFrame.h"
15 #include "lldb/API/SBLanguageRuntime.h"
16 #include "lldb/API/SBStringList.h"
17 #include "lldb/API/SBThread.h"
18
19 // In-house headers:
20 #include "MICmdArgValListOfN.h"
21 #include "MICmdArgValOptionLong.h"
22 #include "MICmdArgValString.h"
23 #include "MICmdCmdGdbShow.h"
24 #include "MICmnLLDBDebugSessionInfo.h"
25 #include "MICmnMIResultRecord.h"
26 #include "MICmnMIValueConst.h"
27
28 // Instantiations:
29 const CMICmdCmdGdbShow::MapGdbOptionNameToFnGdbOptionPtr_t
30     CMICmdCmdGdbShow::ms_mapGdbOptionNameToFnGdbOptionPtr = {
31         {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync},
32         {"print", &CMICmdCmdGdbShow::OptionFnPrint},
33         {"language", &CMICmdCmdGdbShow::OptionFnLanguage},
34         {"disassembly-flavor", &CMICmdCmdGdbShow::OptionFnDisassemblyFlavor},
35         {"fallback", &CMICmdCmdGdbShow::OptionFnFallback},
36         {"breakpoint", &CMICmdCmdGdbShow::OptionFnBreakpoint}};
37
38 //++
39 //------------------------------------------------------------------------------------
40 // Details: CMICmdCmdGdbShow constructor.
41 // Type:    Method.
42 // Args:    None.
43 // Return:  None.
44 // Throws:  None.
45 //--
46 CMICmdCmdGdbShow::CMICmdCmdGdbShow()
47     : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
48       m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
49       m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
50   // Command factory matches this name with that received from the stdin stream
51   m_strMiCmd = "gdb-show";
52
53   // Required by the CMICmdFactory when registering *this command
54   m_pSelfCreatorFn = &CMICmdCmdGdbShow::CreateSelf;
55 }
56
57 //++
58 //------------------------------------------------------------------------------------
59 // Details: CMICmdCmdGdbShow destructor.
60 // Type:    Overrideable.
61 // Args:    None.
62 // Return:  None.
63 // Throws:  None.
64 //--
65 CMICmdCmdGdbShow::~CMICmdCmdGdbShow() {}
66
67 //++
68 //------------------------------------------------------------------------------------
69 // Details: The invoker requires this function. The parses the command line
70 // options
71 //          arguments to extract values for each of those arguments.
72 // Type:    Overridden.
73 // Args:    None.
74 // Return:  MIstatus::success - Function succeeded.
75 //          MIstatus::failure - Function failed.
76 // Throws:  None.
77 //--
78 bool CMICmdCmdGdbShow::ParseArgs() {
79   m_setCmdArgs.Add(new CMICmdArgValListOfN(
80       m_constStrArgNamedGdbOption, true, true,
81       CMICmdArgValListBase::eArgValType_StringAnything));
82   return ParseValidateCmdOptions();
83 }
84
85 //++
86 //------------------------------------------------------------------------------------
87 // Details: The invoker requires this function. The command is executed in this
88 // function.
89 // Type:    Overridden.
90 // Args:    None.
91 // Return:  MIstatus::success - Function succeeded.
92 //          MIstatus::failure - Function failed.
93 // Throws:  None.
94 //--
95 bool CMICmdCmdGdbShow::Execute() {
96   CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
97   const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
98       pArgGdbOption->GetExpectedOptions());
99
100   // Get the gdb-show option to carry out. This option will be used as an action
101   // which should be done. Further arguments will be used as parameters for it.
102   CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
103   const CMICmdArgValString *pOption =
104       static_cast<const CMICmdArgValString *>(*it);
105   const CMIUtilString strOption(pOption->GetValue());
106   ++it;
107
108   // Retrieve the parameter(s) for the option
109   CMIUtilString::VecString_t vecWords;
110   while (it != rVecWords.end()) {
111     const CMICmdArgValString *pWord =
112         static_cast<const CMICmdArgValString *>(*it);
113     vecWords.push_back(pWord->GetValue());
114
115     // Next
116     ++it;
117   }
118
119   FnGdbOptionPtr pPrintRequestFn = nullptr;
120   if (!GetOptionFn(strOption, pPrintRequestFn)) {
121     // For unimplemented option handlers, fallback to a generic handler
122     // ToDo: Remove this when ALL options have been implemented
123     if (!GetOptionFn("fallback", pPrintRequestFn)) {
124       m_bGdbOptionRecognised = false;
125       m_strGdbOptionName = "fallback"; // This would be the strOption name
126       return MIstatus::success;
127     }
128   }
129
130   m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
131   if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
132     return MIstatus::failure;
133
134   return MIstatus::success;
135 }
136
137 //++
138 //------------------------------------------------------------------------------------
139 // Details: The invoker requires this function. The command prepares a MI Record
140 // Result
141 //          for the work carried out in the Execute() method.
142 // Type:    Overridden.
143 // Args:    None.
144 // Return:  MIstatus::success - Function succeeded.
145 //          MIstatus::failure - Function failed.
146 // Throws:  None.
147 //--
148 bool CMICmdCmdGdbShow::Acknowledge() {
149   // Print error if option isn't recognized:
150   // ^error,msg="The request '%s' was not recognized, not implemented"
151   if (!m_bGdbOptionRecognised) {
152     const CMICmnMIValueConst miValueConst(
153         CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
154                               m_strGdbOptionName.c_str()));
155     const CMICmnMIValueResult miValueResult("msg", miValueConst);
156     const CMICmnMIResultRecord miRecordResult(
157         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
158         miValueResult);
159     m_miResultRecord = miRecordResult;
160     return MIstatus::success;
161   }
162
163   // ^done,value="%s"
164   if (m_bGdbOptionFnSuccessful && !m_strValue.empty()) {
165     const CMICmnMIValueConst miValueConst(m_strValue);
166     const CMICmnMIValueResult miValueResult("value", miValueConst);
167     const CMICmnMIResultRecord miRecordResult(
168         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
169         miValueResult);
170     m_miResultRecord = miRecordResult;
171     return MIstatus::success;
172   } else if (m_bGdbOptionFnSuccessful) {
173     // Ignore empty value (for fallback)
174     const CMICmnMIResultRecord miRecordResult(
175         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
176     m_miResultRecord = miRecordResult;
177     return MIstatus::success;
178   }
179
180   // Print error if request failed:
181   // ^error,msg="The request '%s' failed.
182   const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
183       MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
184   const CMICmnMIValueResult miValueResult("msg", miValueConst);
185   const CMICmnMIResultRecord miRecordResult(
186       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
187       miValueResult);
188   m_miResultRecord = miRecordResult;
189
190   return MIstatus::success;
191 }
192
193 //++
194 //------------------------------------------------------------------------------------
195 // Details: Required by the CMICmdFactory when registering *this command. The
196 // factory
197 //          calls this function to create an instance of *this command.
198 // Type:    Static method.
199 // Args:    None.
200 // Return:  CMICmdBase * - Pointer to a new command.
201 // Throws:  None.
202 //--
203 CMICmdBase *CMICmdCmdGdbShow::CreateSelf() { return new CMICmdCmdGdbShow(); }
204
205 //++
206 //------------------------------------------------------------------------------------
207 // Details: Retrieve the print function's pointer for the matching print
208 // request.
209 // Type:    Method.
210 // Args:    vrPrintFnName   - (R) The info requested.
211 //          vrwpFn          - (W) The print function's pointer of the function
212 //          to carry out
213 // Return:  bool    - True = Print request is implemented, false = not found.
214 // Throws:  None.
215 //--
216 bool CMICmdCmdGdbShow::GetOptionFn(const CMIUtilString &vrPrintFnName,
217                                    FnGdbOptionPtr &vrwpFn) const {
218   vrwpFn = nullptr;
219
220   const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
221       ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
222   if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
223     vrwpFn = (*it).second;
224     return true;
225   }
226
227   return false;
228 }
229
230 //++
231 //------------------------------------------------------------------------------------
232 // Details: Carry out work to complete the GDB show option 'target-async' to
233 // prepare
234 //          and send back the requested information.
235 // Type:    Method.
236 // Args:    vrWords - (R) List of additional parameters used by this option.
237 // Return:  MIstatus::success - Function succeeded.
238 //          MIstatus::failure - Function failed.
239 // Throws:  None.
240 //--
241 bool CMICmdCmdGdbShow::OptionFnTargetAsync(
242     const CMIUtilString::VecString_t &vrWords) {
243   MIunused(vrWords);
244
245   // Get async mode
246   CMICmnLLDBDebugSessionInfo &rSessionInfo(
247       CMICmnLLDBDebugSessionInfo::Instance());
248   const bool bAsyncMode = rSessionInfo.GetDebugger().GetAsync();
249
250   m_strValue = bAsyncMode ? "on" : "off";
251   return MIstatus::success;
252 }
253
254 //++
255 //------------------------------------------------------------------------------------
256 // Details: Carry out work to complete the GDB show option 'print' to prepare
257 // and send
258 //          back the requested information.
259 // Type:    Method.
260 // Args:    vrWords - (R) List of additional parameters used by this option.
261 // Return:  MIstatus::success - Function succeeded.
262 //          MIstatus::failure - Function failed.
263 // Throws:  None.
264 //--
265 bool CMICmdCmdGdbShow::OptionFnPrint(
266     const CMIUtilString::VecString_t &vrWords) {
267   const bool bAllArgs(vrWords.size() == 1);
268   if (!bAllArgs) {
269     m_bGbbOptionFnHasError = true;
270     m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS);
271     return MIstatus::failure;
272   }
273
274   const CMIUtilString strOption(vrWords[0]);
275   CMIUtilString strOptionKey;
276   bool bOptionValueDefault = false;
277   if (CMIUtilString::Compare(strOption, "char-array-as-string"))
278     strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
279   else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
280     strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
281   else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) {
282     strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
283     bOptionValueDefault = true;
284   } else {
285     m_bGbbOptionFnHasError = true;
286     m_strGdbOptionFnError = CMIUtilString::Format(
287         MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION),
288         strOption.c_str());
289     return MIstatus::failure;
290   }
291
292   bool bOptionValue = false;
293   bOptionValue = bOptionValueDefault
294                      ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
295                            strOptionKey, bOptionValue) ||
296                            bOptionValue
297                      : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
298                            strOptionKey, bOptionValue) &&
299                            bOptionValue;
300
301   m_strValue = bOptionValue ? "on" : "off";
302   return MIstatus::success;
303 }
304
305 //++
306 //------------------------------------------------------------------------------------
307 // Details: Carry out work to complete the GDB show option 'language' to prepare
308 //          and send back the requested information.
309 // Type:    Method.
310 // Args:    vrWords - (R) List of additional parameters used by this option.
311 // Return:  MIstatus::success - Function succeeded.
312 //          MIstatus::failure - Function failed.
313 // Throws:  None.
314 //--
315 bool CMICmdCmdGdbShow::OptionFnLanguage(
316     const CMIUtilString::VecString_t &vrWords) {
317   MIunused(vrWords);
318
319   // Get current language
320   CMICmnLLDBDebugSessionInfo &rSessionInfo(
321       CMICmnLLDBDebugSessionInfo::Instance());
322   lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
323   const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame();
324   lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit();
325   const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage();
326
327   m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType);
328   return MIstatus::success;
329 }
330
331 //++
332 //------------------------------------------------------------------------------------
333 // Details: Carry out work to complete the GDB show option 'disassembly-flavor' to prepare
334 //          and send back the requested information.
335 // Type:    Method.
336 // Args:    vrWords - (R) List of additional parameters used by this option.
337 // Return:  MIstatus::success - Function succeeded.
338 //          MIstatus::failure - Function failed.
339 // Throws:  None.
340 //--
341 bool CMICmdCmdGdbShow::OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords) {
342   MIunused(vrWords);
343
344   // Get current disassembly flavor
345   lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
346   m_strValue = lldb::SBDebugger::GetInternalVariableValue("target.x86-disassembly-flavor",
347                                                           rDbgr.GetInstanceName()).GetStringAtIndex(0);
348   return MIstatus::success;
349 }
350
351 //++
352 //------------------------------------------------------------------------------------
353 // Details: Carry out work to complete the GDB show option 'breakpoint' to
354 // prepare
355 //          and send back the requested information.
356 // Type:    Method.
357 // Args:    vrWords - (R) List of additional parameters used by this option.
358 // Return:  MIstatus::success - Function succeeded.
359 //          MIstatus::failure - Function failed.
360 // Throws:  None.
361 //--
362 bool CMICmdCmdGdbShow::OptionFnBreakpoint(
363     const CMIUtilString::VecString_t &vrWords) {
364   if (vrWords.size() != 1) {
365     m_bGbbOptionFnHasError = true;
366     m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS);
367     return MIstatus::failure;
368   }
369
370   const CMIUtilString strOption(vrWords[0]);
371   if (!CMIUtilString::Compare(strOption, "pending")) {
372     m_bGbbOptionFnHasError = true;
373     m_strGdbOptionFnError = CMIUtilString::Format(
374         MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION),
375         strOption.c_str());
376     return MIstatus::failure;
377   }
378
379   if (!m_rLLDBDebugSessionInfo.SharedDataRetrieve("breakpoint.pending",
380                                                   m_strValue)) {
381     if (m_strValue.empty())
382       m_strValue = "off";
383   }
384
385   return MIstatus::success;
386 }
387
388 //++
389 //------------------------------------------------------------------------------------
390 // Details: Carry out work to complete the GDB show option to prepare and send
391 // back the
392 //          requested information.
393 // Type:    Method.
394 // Args:    None.
395 // Return:  MIstatus::success - Function succeeded.
396 //          MIstatus::failure - Function failed.
397 // Throws:  None.
398 //--
399 bool CMICmdCmdGdbShow::OptionFnFallback(
400     const CMIUtilString::VecString_t &vrWords) {
401   MIunused(vrWords);
402
403   // Do nothing - intentional. This is a fallback function to do nothing.
404   // This allows the search for gdb-show options to always succeed when the
405   // option is not
406   // found (implemented).
407
408   return MIstatus::success;
409 }