1 //===-- MICmdCmdGdbShow.cpp -------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Overview: CMICmdCmdGdbShow implementation.
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"
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"
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}};
38 //------------------------------------------------------------------------------------
39 // Details: CMICmdCmdGdbShow constructor.
45 CMICmdCmdGdbShow::CMICmdCmdGdbShow()
46 : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
47 m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
48 m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
49 // Command factory matches this name with that received from the stdin stream
50 m_strMiCmd = "gdb-show";
52 // Required by the CMICmdFactory when registering *this command
53 m_pSelfCreatorFn = &CMICmdCmdGdbShow::CreateSelf;
57 //------------------------------------------------------------------------------------
58 // Details: CMICmdCmdGdbShow destructor.
59 // Type: Overrideable.
64 CMICmdCmdGdbShow::~CMICmdCmdGdbShow() {}
67 //------------------------------------------------------------------------------------
68 // Details: The invoker requires this function. The parses the command line
70 // arguments to extract values for each of those arguments.
73 // Return: MIstatus::success - Function succeeded.
74 // MIstatus::failure - Function failed.
77 bool CMICmdCmdGdbShow::ParseArgs() {
78 m_setCmdArgs.Add(new CMICmdArgValListOfN(
79 m_constStrArgNamedGdbOption, true, true,
80 CMICmdArgValListBase::eArgValType_StringAnything));
81 return ParseValidateCmdOptions();
85 //------------------------------------------------------------------------------------
86 // Details: The invoker requires this function. The command is executed in this
90 // Return: MIstatus::success - Function succeeded.
91 // MIstatus::failure - Function failed.
94 bool CMICmdCmdGdbShow::Execute() {
95 CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
96 const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
97 pArgGdbOption->GetExpectedOptions());
99 // Get the gdb-show option to carry out. This option will be used as an action
100 // which should be done. Further arguments will be used as parameters for it.
101 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
102 const CMICmdArgValString *pOption =
103 static_cast<const CMICmdArgValString *>(*it);
104 const CMIUtilString strOption(pOption->GetValue());
107 // Retrieve the parameter(s) for the option
108 CMIUtilString::VecString_t vecWords;
109 while (it != rVecWords.end()) {
110 const CMICmdArgValString *pWord =
111 static_cast<const CMICmdArgValString *>(*it);
112 vecWords.push_back(pWord->GetValue());
118 FnGdbOptionPtr pPrintRequestFn = nullptr;
119 if (!GetOptionFn(strOption, pPrintRequestFn)) {
120 // For unimplemented option handlers, fallback to a generic handler
121 // ToDo: Remove this when ALL options have been implemented
122 if (!GetOptionFn("fallback", pPrintRequestFn)) {
123 m_bGdbOptionRecognised = false;
124 m_strGdbOptionName = "fallback"; // This would be the strOption name
125 return MIstatus::success;
129 m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
130 if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
131 return MIstatus::failure;
133 return MIstatus::success;
137 //------------------------------------------------------------------------------------
138 // Details: The invoker requires this function. The command prepares a MI Record
140 // for the work carried out in the Execute() method.
143 // Return: MIstatus::success - Function succeeded.
144 // MIstatus::failure - Function failed.
147 bool CMICmdCmdGdbShow::Acknowledge() {
148 // Print error if option isn't recognized:
149 // ^error,msg="The request '%s' was not recognized, not implemented"
150 if (!m_bGdbOptionRecognised) {
151 const CMICmnMIValueConst miValueConst(
152 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
153 m_strGdbOptionName.c_str()));
154 const CMICmnMIValueResult miValueResult("msg", miValueConst);
155 const CMICmnMIResultRecord miRecordResult(
156 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
158 m_miResultRecord = miRecordResult;
159 return MIstatus::success;
163 if (m_bGdbOptionFnSuccessful && !m_strValue.empty()) {
164 const CMICmnMIValueConst miValueConst(m_strValue);
165 const CMICmnMIValueResult miValueResult("value", miValueConst);
166 const CMICmnMIResultRecord miRecordResult(
167 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
169 m_miResultRecord = miRecordResult;
170 return MIstatus::success;
171 } else if (m_bGdbOptionFnSuccessful) {
172 // Ignore empty value (for fallback)
173 const CMICmnMIResultRecord miRecordResult(
174 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
175 m_miResultRecord = miRecordResult;
176 return MIstatus::success;
179 // Print error if request failed:
180 // ^error,msg="The request '%s' failed.
181 const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
182 MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
183 const CMICmnMIValueResult miValueResult("msg", miValueConst);
184 const CMICmnMIResultRecord miRecordResult(
185 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
187 m_miResultRecord = miRecordResult;
189 return MIstatus::success;
193 //------------------------------------------------------------------------------------
194 // Details: Required by the CMICmdFactory when registering *this command. The
196 // calls this function to create an instance of *this command.
197 // Type: Static method.
199 // Return: CMICmdBase * - Pointer to a new command.
202 CMICmdBase *CMICmdCmdGdbShow::CreateSelf() { return new CMICmdCmdGdbShow(); }
205 //------------------------------------------------------------------------------------
206 // Details: Retrieve the print function's pointer for the matching print
209 // Args: vrPrintFnName - (R) The info requested.
210 // vrwpFn - (W) The print function's pointer of the function
212 // Return: bool - True = Print request is implemented, false = not found.
215 bool CMICmdCmdGdbShow::GetOptionFn(const CMIUtilString &vrPrintFnName,
216 FnGdbOptionPtr &vrwpFn) const {
219 const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
220 ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
221 if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
222 vrwpFn = (*it).second;
230 //------------------------------------------------------------------------------------
231 // Details: Carry out work to complete the GDB show option 'target-async' to
233 // and send back the requested information.
235 // Args: vrWords - (R) List of additional parameters used by this option.
236 // Return: MIstatus::success - Function succeeded.
237 // MIstatus::failure - Function failed.
240 bool CMICmdCmdGdbShow::OptionFnTargetAsync(
241 const CMIUtilString::VecString_t &vrWords) {
245 CMICmnLLDBDebugSessionInfo &rSessionInfo(
246 CMICmnLLDBDebugSessionInfo::Instance());
247 const bool bAsyncMode = rSessionInfo.GetDebugger().GetAsync();
249 m_strValue = bAsyncMode ? "on" : "off";
250 return MIstatus::success;
254 //------------------------------------------------------------------------------------
255 // Details: Carry out work to complete the GDB show option 'print' to prepare
257 // back the requested information.
259 // Args: vrWords - (R) List of additional parameters used by this option.
260 // Return: MIstatus::success - Function succeeded.
261 // MIstatus::failure - Function failed.
264 bool CMICmdCmdGdbShow::OptionFnPrint(
265 const CMIUtilString::VecString_t &vrWords) {
266 const bool bAllArgs(vrWords.size() == 1);
268 m_bGbbOptionFnHasError = true;
269 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS);
270 return MIstatus::failure;
273 const CMIUtilString strOption(vrWords[0]);
274 CMIUtilString strOptionKey;
275 bool bOptionValueDefault = false;
276 if (CMIUtilString::Compare(strOption, "char-array-as-string"))
277 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
278 else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
279 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
280 else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) {
281 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
282 bOptionValueDefault = true;
284 m_bGbbOptionFnHasError = true;
285 m_strGdbOptionFnError = CMIUtilString::Format(
286 MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION),
288 return MIstatus::failure;
291 bool bOptionValue = false;
292 bOptionValue = bOptionValueDefault
293 ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
294 strOptionKey, bOptionValue) ||
296 : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
297 strOptionKey, bOptionValue) &&
300 m_strValue = bOptionValue ? "on" : "off";
301 return MIstatus::success;
305 //------------------------------------------------------------------------------------
306 // Details: Carry out work to complete the GDB show option 'language' to prepare
307 // and send back the requested information.
309 // Args: vrWords - (R) List of additional parameters used by this option.
310 // Return: MIstatus::success - Function succeeded.
311 // MIstatus::failure - Function failed.
314 bool CMICmdCmdGdbShow::OptionFnLanguage(
315 const CMIUtilString::VecString_t &vrWords) {
318 // Get current language
319 CMICmnLLDBDebugSessionInfo &rSessionInfo(
320 CMICmnLLDBDebugSessionInfo::Instance());
321 lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
322 const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame();
323 lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit();
324 const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage();
326 m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType);
327 return MIstatus::success;
331 //------------------------------------------------------------------------------------
332 // Details: Carry out work to complete the GDB show option 'disassembly-flavor' to prepare
333 // and send back the requested information.
335 // Args: vrWords - (R) List of additional parameters used by this option.
336 // Return: MIstatus::success - Function succeeded.
337 // MIstatus::failure - Function failed.
340 bool CMICmdCmdGdbShow::OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords) {
343 // Get current disassembly flavor
344 lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
345 m_strValue = lldb::SBDebugger::GetInternalVariableValue("target.x86-disassembly-flavor",
346 rDbgr.GetInstanceName()).GetStringAtIndex(0);
347 return MIstatus::success;
351 //------------------------------------------------------------------------------------
352 // Details: Carry out work to complete the GDB show option to prepare and send
354 // requested information.
357 // Return: MIstatus::success - Function succeeded.
358 // MIstatus::failure - Function failed.
361 bool CMICmdCmdGdbShow::OptionFnFallback(
362 const CMIUtilString::VecString_t &vrWords) {
365 // Do nothing - intentional. This is a fallback function to do nothing.
366 // This allows the search for gdb-show options to always succeed when the
368 // found (implemented).
370 return MIstatus::success;