Add support for range arguments to var-list-children and stack-list-frames
authorIgor Kulaychuk <i.kulaychuk@samsung.com>
Thu, 13 Jul 2017 14:11:45 +0000 (17:11 +0300)
committerIgor Kulaychuk <i.kulaychuk@samsung.com>
Mon, 13 Nov 2017 19:22:40 +0000 (22:22 +0300)
src/debug/debugger/commands.cpp
src/debug/debugger/varobj.cpp

index dfa42c2a130fcd4441b430b148204aed7e6638be..1ce3da18e20b23338a5081bf067d364ff4701d75 100644 (file)
@@ -10,7 +10,7 @@
 // Varobj
 HRESULT ListVariables(ICorDebugFrame *pFrame, std::string &output);
 HRESULT CreateVar(ICorDebugThread *pThread, ICorDebugFrame *pFrame, const std::string &varobjName, const std::string &expression, std::string &output);
-HRESULT ListChildren(const std::string &name, int print_values, ICorDebugThread *pThread, ICorDebugFrame *pFrame, std::string &output);
+HRESULT ListChildren(int childStart, int childEnd, const std::string &name, int print_values, ICorDebugThread *pThread, ICorDebugFrame *pFrame, std::string &output);
 HRESULT DeleteVar(const std::string &varobjName);
 
 // Modules
@@ -81,6 +81,23 @@ static int GetIntArg(const std::vector<std::string> &args, const std::string nam
     return ok ? val : defaultValue;
 }
 
+static bool GetIndices(const std::vector<std::string> &args, int &index1, int &index2)
+{
+    if (args.size() < 2)
+        return false;
+
+    bool ok;
+    int val1 = ParseInt(args.at(args.size() - 2), ok);
+    if (!ok)
+        return false;
+    int val2 = ParseInt(args.at(args.size() - 1), ok);
+    if (!ok)
+        return false;
+    index1 = val1;
+    index2 = val2;
+    return true;
+}
+
 bool ParseBreakpoint(const std::vector<std::string> &args, std::string &filename, unsigned int &linenum)
 {
     if (args.empty())
@@ -193,18 +210,17 @@ static std::unordered_map<std::string, CommandCallback> commands {
     { "exec-next", StepCommand(STEP_OVER) },
     { "exec-finish", StepCommand(STEP_OUT) },
     { "stack-list-frames", [](ICorDebugProcess *pProcess, const std::vector<std::string> &args, std::string &output) -> HRESULT {
-        // TODO: Add parsing frame lowFrame and highFrame
         HRESULT Status;
         ToRelease<ICorDebugThread> pThread;
         DWORD threadId = GetIntArg(args, "--thread", GetLastStoppedThreadId());
         IfFailRet(pProcess->GetThread(threadId, &pThread));
         int lowFrame = 0;
         int highFrame = INT_MAX;
+        GetIndices(args, lowFrame, highFrame);
         IfFailRet(PrintFrames(pThread, output, lowFrame, highFrame));
         return S_OK;
     }},
     { "stack-list-variables", [](ICorDebugProcess *pProcess, const std::vector<std::string> &args, std::string &output) -> HRESULT {
-        // TODO: Add parsing arguments --frame
         HRESULT Status;
         ToRelease<ICorDebugThread> pThread;
         DWORD threadId = GetIntArg(args, "--thread", GetLastStoppedThreadId());
@@ -226,7 +242,6 @@ static std::unordered_map<std::string, CommandCallback> commands {
             return E_FAIL;
         }
 
-        // TODO: Add parsing arguments --frame
         ToRelease<ICorDebugThread> pThread;
         DWORD threadId = GetIntArg(args, "--thread", GetLastStoppedThreadId());
         IfFailRet(pProcess->GetThread(threadId, &pThread));
@@ -261,14 +276,16 @@ static std::unordered_map<std::string, CommandCallback> commands {
             return E_FAIL;
         }
 
-        // TODO: Add parsing arguments --frame and children indices
         ToRelease<ICorDebugThread> pThread;
         DWORD threadId = GetIntArg(args, "--thread", GetLastStoppedThreadId());
         IfFailRet(pProcess->GetThread(threadId, &pThread));
 
         ToRelease<ICorDebugFrame> pFrame;
         IfFailRet(pThread->GetActiveFrame(&pFrame));
-        return ListChildren(args.at(var_index), print_values, pThread, pFrame, output);
+        int childStart = 0;
+        int childEnd = INT_MAX;
+        GetIndices(args, childStart, childEnd);
+        return ListChildren(childStart, childEnd, args.at(var_index), print_values, pThread, pFrame, output);
     }},
     { "var-delete", [](ICorDebugProcess *, const std::vector<std::string> &args, std::string &output) -> HRESULT {
         if (args.size() < 1)
index 437eaf6bb304af725e025ff1749fd5669e8e96c7..8eafdf955e795edb2e90a63c1225ef6a8bf25995 100644 (file)
@@ -119,7 +119,9 @@ static HRESULT FetchFieldsAndProperties(ICorDebugValue *pInputValue,
                                         ICorDebugILFrame *pILFrame,
                                         std::vector<VarObjValue> &members,
                                         bool static_members,
-                                        bool &has_static_members)
+                                        bool &has_static_members,
+                                        int childStart,
+                                        int childEnd)
 {
     has_static_members = false;
     HRESULT Status;
@@ -127,6 +129,8 @@ static HRESULT FetchFieldsAndProperties(ICorDebugValue *pInputValue,
     DWORD threadId = 0;
     IfFailRet(pThread->GetID(&threadId));
 
+    int currentIndex = -1;
+
     IfFailRet(WalkMembers(pInputValue, pILFrame, [&](
         mdMethodDef mdGetter,
         ICorDebugModule *pModule,
@@ -142,6 +146,10 @@ static HRESULT FetchFieldsAndProperties(ICorDebugValue *pInputValue,
         if (!add_member)
             return S_OK;
 
+        ++currentIndex;
+        if (currentIndex < childStart || currentIndex >= childEnd)
+            return S_OK;
+
         std::string className;
         if (pType)
             TypePrinter::GetTypeOfValue(pType, className);
@@ -242,7 +250,14 @@ static void PrintChildren(std::vector<VarObjValue> &members, int print_values, I
     output = ss.str();
 }
 
-HRESULT ListChildren(VarObjValue &objValue, int print_values, ICorDebugThread *pThread, ICorDebugFrame *pFrame, std::string &output)
+HRESULT ListChildren(
+    int childStart,
+    int childEnd,
+    VarObjValue &objValue,
+    int print_values,
+    ICorDebugThread *pThread,
+    ICorDebugFrame *pFrame,
+    std::string &output)
 {
     HRESULT Status;
 
@@ -259,7 +274,9 @@ HRESULT ListChildren(VarObjValue &objValue, int print_values, ICorDebugThread *p
                                        pILFrame,
                                        members,
                                        objValue.statics_only,
-                                       has_static_members));
+                                       has_static_members,
+                                       childStart,
+                                       childEnd));
 
     if (!objValue.statics_only && has_static_members)
     {
@@ -274,12 +291,19 @@ HRESULT ListChildren(VarObjValue &objValue, int print_values, ICorDebugThread *p
     return S_OK;
 }
 
-HRESULT ListChildren(const std::string &name, int print_values, ICorDebugThread *pThread, ICorDebugFrame *pFrame, std::string &output)
+HRESULT ListChildren(
+    int childStart,
+    int childEnd,
+    const std::string &name,
+    int print_values,
+    ICorDebugThread *pThread,
+    ICorDebugFrame *pFrame,
+    std::string &output)
 {
     auto it = g_vars.find(name);
     if (it == g_vars.end())
         return E_FAIL;
-    return ListChildren(it->second, print_values, pThread, pFrame, output);
+    return ListChildren(childStart, childEnd, it->second, print_values, pThread, pFrame, output);
 }
 
 HRESULT ListVariables(ICorDebugFrame *pFrame, std::string &output)