1 //===-- MICmdCmdGdbShow.cpp -------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Overview: CMICmdCmdGdbShow implementation.
11 // Third party headers:
12 #include "lldb/API/SBCompileUnit.h"
13 #include "lldb/API/SBFrame.h"
14 #include "lldb/API/SBLanguageRuntime.h"
15 #include "lldb/API/SBStringList.h"
16 #include "lldb/API/SBThread.h"
19 #include "MICmdArgValListOfN.h"
20 #include "MICmdArgValOptionLong.h"
21 #include "MICmdArgValString.h"
22 #include "MICmdCmdGdbShow.h"
23 #include "MICmnLLDBDebugSessionInfo.h"
24 #include "MICmnMIResultRecord.h"
25 #include "MICmnMIValueConst.h"
28 const CMICmdCmdGdbShow::MapGdbOptionNameToFnGdbOptionPtr_t
29 CMICmdCmdGdbShow::ms_mapGdbOptionNameToFnGdbOptionPtr = {
30 {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync},
31 {"print", &CMICmdCmdGdbShow::OptionFnPrint},
32 {"language", &CMICmdCmdGdbShow::OptionFnLanguage},
33 {"disassembly-flavor", &CMICmdCmdGdbShow::OptionFnDisassemblyFlavor},
34 {"fallback", &CMICmdCmdGdbShow::OptionFnFallback},
35 {"breakpoint", &CMICmdCmdGdbShow::OptionFnBreakpoint}};
38 // Details: CMICmdCmdGdbShow constructor.
44 CMICmdCmdGdbShow::CMICmdCmdGdbShow()
45 : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
46 m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
47 m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
48 // Command factory matches this name with that received from the stdin stream
49 m_strMiCmd = "gdb-show";
51 // Required by the CMICmdFactory when registering *this command
52 m_pSelfCreatorFn = &CMICmdCmdGdbShow::CreateSelf;
56 // Details: CMICmdCmdGdbShow destructor.
57 // Type: Overrideable.
62 CMICmdCmdGdbShow::~CMICmdCmdGdbShow() {}
65 // Details: The invoker requires this function. The parses the command line
67 // arguments to extract values for each of those arguments.
70 // Return: MIstatus::success - Function succeeded.
71 // MIstatus::failure - Function failed.
74 bool CMICmdCmdGdbShow::ParseArgs() {
75 m_setCmdArgs.Add(new CMICmdArgValListOfN(
76 m_constStrArgNamedGdbOption, true, true,
77 CMICmdArgValListBase::eArgValType_StringAnything));
78 return ParseValidateCmdOptions();
82 // Details: The invoker requires this function. The command is executed in this
86 // Return: MIstatus::success - Function succeeded.
87 // MIstatus::failure - Function failed.
90 bool CMICmdCmdGdbShow::Execute() {
91 CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
92 const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
93 pArgGdbOption->GetExpectedOptions());
95 // Get the gdb-show option to carry out. This option will be used as an action
96 // which should be done. Further arguments will be used as parameters for it.
97 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
98 const CMICmdArgValString *pOption =
99 static_cast<const CMICmdArgValString *>(*it);
100 const CMIUtilString strOption(pOption->GetValue());
103 // Retrieve the parameter(s) for the option
104 CMIUtilString::VecString_t vecWords;
105 while (it != rVecWords.end()) {
106 const CMICmdArgValString *pWord =
107 static_cast<const CMICmdArgValString *>(*it);
108 vecWords.push_back(pWord->GetValue());
114 FnGdbOptionPtr pPrintRequestFn = nullptr;
115 if (!GetOptionFn(strOption, pPrintRequestFn)) {
116 // For unimplemented option handlers, fallback to a generic handler
117 // ToDo: Remove this when ALL options have been implemented
118 if (!GetOptionFn("fallback", pPrintRequestFn)) {
119 m_bGdbOptionRecognised = false;
120 m_strGdbOptionName = "fallback"; // This would be the strOption name
121 return MIstatus::success;
125 m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
126 if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
127 return MIstatus::failure;
129 return MIstatus::success;
133 // Details: The invoker requires this function. The command prepares a MI Record
135 // for the work carried out in the Execute() method.
138 // Return: MIstatus::success - Function succeeded.
139 // MIstatus::failure - Function failed.
142 bool CMICmdCmdGdbShow::Acknowledge() {
143 // Print error if option isn't recognized:
144 // ^error,msg="The request '%s' was not recognized, not implemented"
145 if (!m_bGdbOptionRecognised) {
146 const CMICmnMIValueConst miValueConst(
147 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
148 m_strGdbOptionName.c_str()));
149 const CMICmnMIValueResult miValueResult("msg", miValueConst);
150 const CMICmnMIResultRecord miRecordResult(
151 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
153 m_miResultRecord = miRecordResult;
154 return MIstatus::success;
158 if (m_bGdbOptionFnSuccessful && !m_strValue.empty()) {
159 const CMICmnMIValueConst miValueConst(m_strValue);
160 const CMICmnMIValueResult miValueResult("value", miValueConst);
161 const CMICmnMIResultRecord miRecordResult(
162 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
164 m_miResultRecord = miRecordResult;
165 return MIstatus::success;
166 } else if (m_bGdbOptionFnSuccessful) {
167 // Ignore empty value (for fallback)
168 const CMICmnMIResultRecord miRecordResult(
169 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
170 m_miResultRecord = miRecordResult;
171 return MIstatus::success;
174 // Print error if request failed:
175 // ^error,msg="The request '%s' failed.
176 const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
177 MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
178 const CMICmnMIValueResult miValueResult("msg", miValueConst);
179 const CMICmnMIResultRecord miRecordResult(
180 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
182 m_miResultRecord = miRecordResult;
184 return MIstatus::success;
188 // Details: Required by the CMICmdFactory when registering *this command. The
190 // calls this function to create an instance of *this command.
191 // Type: Static method.
193 // Return: CMICmdBase * - Pointer to a new command.
196 CMICmdBase *CMICmdCmdGdbShow::CreateSelf() { return new CMICmdCmdGdbShow(); }
199 // Details: Retrieve the print function's pointer for the matching print
202 // Args: vrPrintFnName - (R) The info requested.
203 // vrwpFn - (W) The print function's pointer of the function
205 // Return: bool - True = Print request is implemented, false = not found.
208 bool CMICmdCmdGdbShow::GetOptionFn(const CMIUtilString &vrPrintFnName,
209 FnGdbOptionPtr &vrwpFn) const {
212 const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
213 ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
214 if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
215 vrwpFn = (*it).second;
223 // Details: Carry out work to complete the GDB show option 'target-async' to
225 // and send back the requested information.
227 // Args: vrWords - (R) List of additional parameters used by this option.
228 // Return: MIstatus::success - Function succeeded.
229 // MIstatus::failure - Function failed.
232 bool CMICmdCmdGdbShow::OptionFnTargetAsync(
233 const CMIUtilString::VecString_t &vrWords) {
237 CMICmnLLDBDebugSessionInfo &rSessionInfo(
238 CMICmnLLDBDebugSessionInfo::Instance());
239 const bool bAsyncMode = rSessionInfo.GetDebugger().GetAsync();
241 m_strValue = bAsyncMode ? "on" : "off";
242 return MIstatus::success;
246 // Details: Carry out work to complete the GDB show option 'print' to prepare
248 // back the requested information.
250 // Args: vrWords - (R) List of additional parameters used by this option.
251 // Return: MIstatus::success - Function succeeded.
252 // MIstatus::failure - Function failed.
255 bool CMICmdCmdGdbShow::OptionFnPrint(
256 const CMIUtilString::VecString_t &vrWords) {
257 const bool bAllArgs(vrWords.size() == 1);
259 m_bGbbOptionFnHasError = true;
260 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS);
261 return MIstatus::failure;
264 const CMIUtilString strOption(vrWords[0]);
265 CMIUtilString strOptionKey;
266 bool bOptionValueDefault = false;
267 if (CMIUtilString::Compare(strOption, "char-array-as-string"))
268 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
269 else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
270 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
271 else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) {
272 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
273 bOptionValueDefault = true;
275 m_bGbbOptionFnHasError = true;
276 m_strGdbOptionFnError = CMIUtilString::Format(
277 MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION),
279 return MIstatus::failure;
282 bool bOptionValue = false;
283 bOptionValue = bOptionValueDefault
284 ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
285 strOptionKey, bOptionValue) ||
287 : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
288 strOptionKey, bOptionValue) &&
291 m_strValue = bOptionValue ? "on" : "off";
292 return MIstatus::success;
296 // Details: Carry out work to complete the GDB show option 'language' to prepare
297 // and send back the requested information.
299 // Args: vrWords - (R) List of additional parameters used by this option.
300 // Return: MIstatus::success - Function succeeded.
301 // MIstatus::failure - Function failed.
304 bool CMICmdCmdGdbShow::OptionFnLanguage(
305 const CMIUtilString::VecString_t &vrWords) {
308 // Get current language
309 CMICmnLLDBDebugSessionInfo &rSessionInfo(
310 CMICmnLLDBDebugSessionInfo::Instance());
311 lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
312 const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame();
313 lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit();
314 const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage();
316 m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType);
317 return MIstatus::success;
321 // Details: Carry out work to complete the GDB show option 'disassembly-flavor' to prepare
322 // and send back the requested information.
324 // Args: vrWords - (R) List of additional parameters used by this option.
325 // Return: MIstatus::success - Function succeeded.
326 // MIstatus::failure - Function failed.
329 bool CMICmdCmdGdbShow::OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords) {
332 // Get current disassembly flavor
333 lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
334 m_strValue = lldb::SBDebugger::GetInternalVariableValue("target.x86-disassembly-flavor",
335 rDbgr.GetInstanceName()).GetStringAtIndex(0);
336 return MIstatus::success;
340 // Details: Carry out work to complete the GDB show option 'breakpoint' to
342 // and send back the requested information.
344 // Args: vrWords - (R) List of additional parameters used by this option.
345 // Return: MIstatus::success - Function succeeded.
346 // MIstatus::failure - Function failed.
349 bool CMICmdCmdGdbShow::OptionFnBreakpoint(
350 const CMIUtilString::VecString_t &vrWords) {
351 if (vrWords.size() != 1) {
352 m_bGbbOptionFnHasError = true;
353 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS);
354 return MIstatus::failure;
357 const CMIUtilString strOption(vrWords[0]);
358 if (!CMIUtilString::Compare(strOption, "pending")) {
359 m_bGbbOptionFnHasError = true;
360 m_strGdbOptionFnError = CMIUtilString::Format(
361 MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION),
363 return MIstatus::failure;
366 if (!m_rLLDBDebugSessionInfo.SharedDataRetrieve("breakpoint.pending",
368 if (m_strValue.empty())
372 return MIstatus::success;
376 // Details: Carry out work to complete the GDB show option to prepare and send
378 // requested information.
381 // Return: MIstatus::success - Function succeeded.
382 // MIstatus::failure - Function failed.
385 bool CMICmdCmdGdbShow::OptionFnFallback(
386 const CMIUtilString::VecString_t &vrWords) {
389 // Do nothing - intentional. This is a fallback function to do nothing.
390 // This allows the search for gdb-show options to always succeed when the
392 // found (implemented).
394 return MIstatus::success;