#pragma once
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBTarget.h"
#include <map>
#include <type_traits>
#include <vector>
#include "MICmnBase.h"
#include "MICmnLLDBDebugSessionInfoVarObj.h"
#include "MICmnMIValueTuple.h"
#include "MIUtilMapIdToVariant.h"
#include "MIUtilSingletonBase.h"
#include "MIUtilThreadBaseStd.h"
class CMICmnLLDBDebugger;
struct SMICmdData;
class CMICmnMIValueTuple;
class CMICmnMIValueList;
class CMICmnLLDBDebugSessionInfo
: public CMICmnBase,
public MI::ISingleton<CMICmnLLDBDebugSessionInfo> {
friend class MI::ISingleton<CMICmnLLDBDebugSessionInfo>;
public:
enum VariableType_e {
eVariableType_InScope = (1u << 0),
eVariableType_Statics = (1u << 1),
eVariableType_Locals = (1u << 2),
eVariableType_Arguments = (1u << 3)
};
enum StoppointType_e {
eStoppointType_Breakpoint,
eStoppointType_Watchpoint,
};
enum VariableInfoFormat_e {
eVariableInfoFormat_NoValues = 0,
eVariableInfoFormat_AllValues = 1,
eVariableInfoFormat_SimpleValues = 2
};
enum ThreadInfoFormat_e {
eThreadInfoFormat_NoFrames,
eThreadInfoFormat_AllFrames
};
enum FrameInfoFormat_e {
eFrameInfoFormat_NoArguments,
eFrameInfoFormat_AllArguments,
eFrameInfoFormat_AllArgumentsInSimpleForm
};
public:
struct SStoppointInfo {
SStoppointInfo()
: m_nLldbId(0), m_nMiId(0), m_bDisp(false), m_bEnabled(false),
m_addr(0), m_nLine(0), m_bHaveArgOptionThreadGrp(false), m_nTimes(0),
m_watchpointVariable(false), m_watchpointRead(false),
m_watchpointWrite(false), m_bPending(false), m_nIgnore(0),
m_bCondition(false), m_bBreakpointThreadId(false),
m_nBreakpointThreadId(0) {}
MIuint m_nLldbId;
MIuint m_nMiId;
StoppointType_e m_eType;
bool m_bDisp;
bool m_bEnabled;
lldb::addr_t m_addr;
CMIUtilString m_fnName;
CMIUtilString m_fileName;
CMIUtilString m_path;
MIuint m_nLine;
bool m_bHaveArgOptionThreadGrp;
CMIUtilString m_strOptThrdGrp;
MIuint m_nTimes;
CMIUtilString m_strOrigLoc;
bool m_watchpointVariable;
CMIUtilString m_watchpointExpr;
bool m_watchpointRead;
bool m_watchpointWrite;
bool m_bPending;
MIuint m_nIgnore;
bool m_bCondition;
CMIUtilString m_strCondition;
bool m_bBreakpointThreadId;
MIuint m_nBreakpointThreadId;
};
public:
typedef std::vector<uint32_t> VecActiveThreadId_t;
public:
bool Initialize() override;
bool Shutdown() override;
template <typename T>
bool SharedDataAdd(const CMIUtilString &vKey, const T &vData);
template <typename T>
bool SharedDataRetrieve(const CMIUtilString &vKey, T &vwData);
void SharedDataDestroy();
bool AccessPath(const CMIUtilString &vPath, bool &vwbYesAccessible);
bool ResolvePath(const SMICmdData &vCmdData, const CMIUtilString &vPath,
CMIUtilString &vwrResolvedPath);
bool ResolvePath(const CMIUtilString &vstrUnknown,
CMIUtilString &vwrResolvedPath);
bool MIResponseFormFrameInfo(const lldb::SBThread &vrThread,
const MIuint vnLevel,
const FrameInfoFormat_e veFrameInfoFormat,
CMICmnMIValueTuple &vwrMiValueTuple);
bool MIResponseFormThreadInfo(const SMICmdData &vCmdData,
const lldb::SBThread &vrThread,
const ThreadInfoFormat_e veThreadInfoFormat,
CMICmnMIValueTuple &vwrMIValueTuple);
bool MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame,
const MIuint vMaskVarTypes,
const VariableInfoFormat_e veVarInfoFormat,
CMICmnMIValueList &vwrMiValueList,
const MIuint vnMaxDepth = 10,
const bool vbMarkArgs = false);
void MIResponseFormStoppointFrameInfo(const SStoppointInfo &vrStoppointInfo,
CMICmnMIValueTuple &vwrMiValueTuple);
bool MIResponseFormBreakpointInfo(const SStoppointInfo &vrStoppointInfo,
CMICmnMIValueTuple &vwrMiValueTuple);
void MIResponseFormWatchpointInfo(const SStoppointInfo &vrStoppointInfo,
CMICmnMIValueResult &vwrMiValueResult);
template <class T, class = std::enable_if_t<
std::is_same<T, lldb::SBBreakpoint>::value ||
std::is_same<T, lldb::SBWatchpoint>::value>>
bool GetStoppointInfo(const T &vrStoppoint, SStoppointInfo &vrwStoppointInfo);
bool RecordStoppointInfo(const SStoppointInfo &vrStoppointInfo);
bool RecordStoppointInfoGet(const MIuint vnMiStoppointId,
SStoppointInfo &vrwStoppointInfo) const;
bool RecordStoppointInfoDelete(const MIuint vnMiStoppointId);
MIuint GetOrCreateMiStoppointId(const MIuint vnLldbStoppointId,
const StoppointType_e veStoppointType);
bool RemoveLldbToMiStoppointIdMapping(const MIuint vnLldbStoppointId,
const StoppointType_e veStoppointType);
CMIUtilThreadMutex &GetSessionMutex() { return m_sessionMutex; }
lldb::SBDebugger &GetDebugger() const;
lldb::SBListener &GetListener() const;
lldb::SBTarget GetTarget() const;
lldb::SBTarget GetSelectedOrDummyTarget() const;
lldb::SBProcess GetProcess() const;
void SetCreateTty(bool val);
bool GetCreateTty() const;
public:
const MIuint m_nBreakpointCntMax = INT32_MAX;
VecActiveThreadId_t m_vecActiveThreadId;
lldb::tid_t m_currentSelectedThread = LLDB_INVALID_THREAD_ID;
const CMIUtilString m_constStrSharedDataKeyWkDir = "Working Directory";
const CMIUtilString m_constStrSharedDataSolibPath = "Solib Path";
const CMIUtilString m_constStrPrintCharArrayAsString =
"Print CharArrayAsString";
const CMIUtilString m_constStrPrintExpandAggregates =
"Print ExpandAggregates";
const CMIUtilString m_constStrPrintAggregateFieldNames =
"Print AggregateFieldNames";
private:
typedef std::vector<CMICmnLLDBDebugSessionInfoVarObj> VecVarObj_t;
typedef std::map<MIuint, SStoppointInfo> MapMiStoppointIdToStoppointInfo_t;
typedef std::pair<MIuint, SStoppointInfo>
MapPairMiStoppointIdToStoppointInfo_t;
typedef std::map<std::pair<MIuint, StoppointType_e>, MIuint>
MapLldbStoppointIdToMiStoppointId_t;
private:
CMICmnLLDBDebugSessionInfo() = default;
CMICmnLLDBDebugSessionInfo(const CMICmnLLDBDebugSessionInfo &);
void operator=(const CMICmnLLDBDebugSessionInfo &);
bool GetVariableInfo(const lldb::SBValue &vrValue, const bool vbInSimpleForm,
CMIUtilString &vwrStrValue);
bool GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc,
CMIUtilString &vwFnName, CMIUtilString &vwFileName,
CMIUtilString &vwPath, MIuint &vwnLine);
bool GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx,
const FrameInfoFormat_e veFrameInfoFormat,
CMIUtilString &vwrThreadFrames);
bool
MIResponseForVariableInfoInternal(const VariableInfoFormat_e veVarInfoFormat,
CMICmnMIValueList &vwrMiValueList,
const lldb::SBValueList &vwrSBValueList,
const MIuint vnMaxDepth,
const bool vbIsArgs, const bool vbMarkArgs);
private:
~CMICmnLLDBDebugSessionInfo() override;
private:
CMIUtilMapIdToVariant m_mapIdToSessionData;
VecVarObj_t m_vecVarObj;
MapMiStoppointIdToStoppointInfo_t m_mapMiStoppointIdToStoppointInfo;
CMIUtilThreadMutex m_sessionMutex;
MapLldbStoppointIdToMiStoppointId_t m_mapLldbStoppointIdToMiStoppointId;
MIuint m_nNextMiStoppointId = 1UL;
std::mutex m_miStoppointIdsMutex;
bool m_bCreateTty = false;
};
template <typename T>
bool CMICmnLLDBDebugSessionInfo::SharedDataAdd(const CMIUtilString &vKey,
const T &vData) {
if (!m_mapIdToSessionData.Add<T>(vKey, vData)) {
SetErrorDescription(m_mapIdToSessionData.GetErrorDescription());
return MIstatus::failure;
}
return MIstatus::success;
}
template <typename T>
bool CMICmnLLDBDebugSessionInfo::SharedDataRetrieve(const CMIUtilString &vKey,
T &vwData) {
bool bDataFound = false;
if (!m_mapIdToSessionData.Get<T>(vKey, vwData, bDataFound)) {
SetErrorDescription(m_mapIdToSessionData.GetErrorDescription());
return MIstatus::failure;
}
return bDataFound;
}