| //===-- MICmdCmdGdbShow.cpp -------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| // Overview: CMICmdCmdGdbShow implementation. |
| |
| // Third party headers: |
| #include "lldb/API/SBCompileUnit.h" |
| #include "lldb/API/SBFrame.h" |
| #include "lldb/API/SBLanguageRuntime.h" |
| #include "lldb/API/SBThread.h" |
| |
| // In-house headers: |
| #include "MICmdCmdGdbShow.h" |
| #include "MICmnMIResultRecord.h" |
| #include "MICmnMIValueConst.h" |
| #include "MICmdArgValString.h" |
| #include "MICmdArgValListOfN.h" |
| #include "MICmdArgValOptionLong.h" |
| #include "MICmnLLDBDebugSessionInfo.h" |
| |
| // Instantiations: |
| const CMICmdCmdGdbShow::MapGdbOptionNameToFnGdbOptionPtr_t CMICmdCmdGdbShow::ms_mapGdbOptionNameToFnGdbOptionPtr = { |
| {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync}, |
| {"print", &CMICmdCmdGdbShow::OptionFnPrint}, |
| {"language", &CMICmdCmdGdbShow::OptionFnLanguage}, |
| {"fallback", &CMICmdCmdGdbShow::OptionFnFallback}}; |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdGdbShow constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdGdbShow::CMICmdCmdGdbShow() |
| : m_constStrArgNamedGdbOption("option") |
| , m_bGdbOptionRecognised(true) |
| , m_bGdbOptionFnSuccessful(false) |
| , m_bGbbOptionFnHasError(false) |
| , m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "gdb-show"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdGdbShow::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdGdbShow destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdGdbShow::~CMICmdCmdGdbShow() |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbShow::ParseArgs() |
| { |
| m_setCmdArgs.Add( |
| new CMICmdArgValListOfN(m_constStrArgNamedGdbOption, true, true, CMICmdArgValListBase::eArgValType_StringAnything)); |
| return ParseValidateCmdOptions(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command is executed in this function. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbShow::Execute() |
| { |
| CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption); |
| const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(pArgGdbOption->GetExpectedOptions()); |
| |
| // Get the gdb-show option to carry out. This option will be used as an action |
| // which should be done. Further arguments will be used as parameters for it. |
| CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin(); |
| const CMICmdArgValString *pOption = static_cast<const CMICmdArgValString *>(*it); |
| const CMIUtilString strOption(pOption->GetValue()); |
| ++it; |
| |
| // Retrieve the parameter(s) for the option |
| CMIUtilString::VecString_t vecWords; |
| while (it != rVecWords.end()) |
| { |
| const CMICmdArgValString *pWord = static_cast<const CMICmdArgValString *>(*it); |
| vecWords.push_back(pWord->GetValue()); |
| |
| // Next |
| ++it; |
| } |
| |
| FnGdbOptionPtr pPrintRequestFn = nullptr; |
| if (!GetOptionFn(strOption, pPrintRequestFn)) |
| { |
| // For unimplemented option handlers, fallback to a generic handler |
| // ToDo: Remove this when ALL options have been implemented |
| if (!GetOptionFn("fallback", pPrintRequestFn)) |
| { |
| m_bGdbOptionRecognised = false; |
| m_strGdbOptionName = "fallback"; // This would be the strOption name |
| return MIstatus::success; |
| } |
| } |
| |
| m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords); |
| if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError) |
| return MIstatus::failure; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute() method. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbShow::Acknowledge() |
| { |
| // Print error if option isn't recognized: |
| // ^error,msg="The request '%s' was not recognized, not implemented" |
| if (!m_bGdbOptionRecognised) |
| { |
| const CMICmnMIValueConst miValueConst( |
| CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND), m_strGdbOptionName.c_str())); |
| const CMICmnMIValueResult miValueResult("msg", miValueConst); |
| const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); |
| m_miResultRecord = miRecordResult; |
| return MIstatus::success; |
| } |
| |
| // ^done,value="%s" |
| if (m_bGdbOptionFnSuccessful && !m_strValue.empty()) |
| { |
| const CMICmnMIValueConst miValueConst(m_strValue); |
| const CMICmnMIValueResult miValueResult("value", miValueConst); |
| const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); |
| m_miResultRecord = miRecordResult; |
| return MIstatus::success; |
| } |
| else if (m_bGdbOptionFnSuccessful) |
| { |
| // Ignore empty value (for fallback) |
| const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); |
| m_miResultRecord = miRecordResult; |
| return MIstatus::success; |
| } |
| |
| // Print error if request failed: |
| // ^error,msg="The request '%s' failed. |
| const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str())); |
| const CMICmnMIValueResult miValueResult("msg", miValueConst); |
| const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * |
| CMICmdCmdGdbShow::CreateSelf() |
| { |
| return new CMICmdCmdGdbShow(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Retrieve the print function's pointer for the matching print request. |
| // Type: Method. |
| // Args: vrPrintFnName - (R) The info requested. |
| // vrwpFn - (W) The print function's pointer of the function to carry out |
| // Return: bool - True = Print request is implemented, false = not found. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbShow::GetOptionFn(const CMIUtilString &vrPrintFnName, FnGdbOptionPtr &vrwpFn) const |
| { |
| vrwpFn = nullptr; |
| |
| const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it = ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName); |
| if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) |
| { |
| vrwpFn = (*it).second; |
| return true; |
| } |
| |
| return false; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Carry out work to complete the GDB show option 'target-async' to prepare |
| // and send back the requested information. |
| // Type: Method. |
| // Args: vrWords - (R) List of additional parameters used by this option. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbShow::OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords) |
| { |
| MIunused(vrWords); |
| |
| // Get async mode |
| CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); |
| const bool bAsyncMode = rSessionInfo.GetDebugger().GetAsync(); |
| |
| m_strValue = bAsyncMode ? "on" : "off"; |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Carry out work to complete the GDB show option 'print' to prepare and send |
| // back the requested information. |
| // Type: Method. |
| // Args: vrWords - (R) List of additional parameters used by this option. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbShow::OptionFnPrint(const CMIUtilString::VecString_t &vrWords) |
| { |
| const bool bAllArgs(vrWords.size() == 1); |
| if (!bAllArgs) |
| { |
| m_bGbbOptionFnHasError = true; |
| m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS); |
| return MIstatus::failure; |
| } |
| |
| const CMIUtilString strOption(vrWords[0]); |
| CMIUtilString strOptionKey; |
| bool bOptionValueDefault = false; |
| if (CMIUtilString::Compare(strOption, "char-array-as-string")) |
| strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString; |
| else if (CMIUtilString::Compare(strOption, "expand-aggregates")) |
| strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates; |
| else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) |
| { |
| strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames; |
| bOptionValueDefault = true; |
| } |
| else |
| { |
| m_bGbbOptionFnHasError = true; |
| m_strGdbOptionFnError = CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str()); |
| return MIstatus::failure; |
| } |
| |
| bool bOptionValue = false; |
| bOptionValue = bOptionValueDefault ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(strOptionKey, bOptionValue) || bOptionValue |
| : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(strOptionKey, bOptionValue) && bOptionValue; |
| |
| m_strValue = bOptionValue ? "on" : "off"; |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Carry out work to complete the GDB show option 'language' to prepare |
| // and send back the requested information. |
| // Type: Method. |
| // Args: vrWords - (R) List of additional parameters used by this option. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbShow::OptionFnLanguage(const CMIUtilString::VecString_t &vrWords) |
| { |
| MIunused(vrWords); |
| |
| // Get current language |
| CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); |
| lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread(); |
| const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame(); |
| lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit(); |
| const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage(); |
| |
| m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType); |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Carry out work to complete the GDB show option to prepare and send back the |
| // requested information. |
| // Type: Method. |
| // Args: None. |
| // Return: MIstatus::success - Function succeeded. |
| // MIstatus::failure - Function failed. |
| // Throws: None. |
| //-- |
| bool |
| CMICmdCmdGdbShow::OptionFnFallback(const CMIUtilString::VecString_t &vrWords) |
| { |
| MIunused(vrWords); |
| |
| // Do nothing - intentional. This is a fallback function to do nothing. |
| // This allows the search for gdb-show options to always succeed when the option is not |
| // found (implemented). |
| |
| return MIstatus::success; |
| } |