Add support for --engineLogging command line option
authorIgor Kulaychuk <i.kulaychuk@samsung.com>
Wed, 31 Jan 2018 18:06:03 +0000 (21:06 +0300)
committerIgor Kulaychuk <i.kulaychuk@samsung.com>
Wed, 31 Jan 2018 18:06:03 +0000 (21:06 +0300)
src/debug/netcoredbg/main.cpp
src/debug/netcoredbg/vscodeprotocol.cpp
src/debug/netcoredbg/vscodeprotocol.h

index 020dbf36e5923493a496f1f6cb8875bc720bc510..bb9222a867974b49d72071b341009b8e91aa0e37 100644 (file)
 
 static void print_help()
 {
-    fprintf(stderr,
+    fprintf(stdout,
         ".NET Core debugger for Linux/macOS.\n"
         "\n"
         "Options:\n"
         "--attach <process-id>                 Attach the debugger to the specified process id.\n"
         "--interpreter=mi                      Puts the debugger into MI mode.\n"
-        "--interpreter=vscode                  Puts the debugger into VS Code Debugger mode.\n");
+        "--interpreter=vscode                  Puts the debugger into VS Code Debugger mode.\n"
+        "--engineLogging[=<path to log file>]  Enable logging to VsDbg-UI or file for the engine.\n"
+        "                                      Only supported by the VsCode interpreter.\n"
+    );
 }
 
 int main(int argc, char *argv[])
@@ -30,6 +33,9 @@ int main(int argc, char *argv[])
         InterpreterVSCode
     } interpreterType = InterpreterMI;
 
+    bool engineLogging = false;
+    std::string logFilePath;
+
     for (int i = 1; i < argc; i++)
     {
         if (strcmp(argv[i], "--attach") == 0)
@@ -58,6 +64,17 @@ int main(int argc, char *argv[])
             interpreterType = InterpreterVSCode;
             continue;
         }
+        else if (strcmp(argv[i], "--engineLogging") == 0)
+        {
+            engineLogging = true;
+            continue;
+        }
+        else if (strstr(argv[i], "--engineLogging=") == argv[i])
+        {
+            engineLogging = true;
+            logFilePath = argv[i] + strlen("--engineLogging=");
+            continue;
+        }
         else if (strcmp(argv[i], "--help") == 0)
         {
             print_help();
@@ -76,13 +93,23 @@ int main(int argc, char *argv[])
     switch(interpreterType)
     {
         case InterpreterMI:
+            if (engineLogging)
+            {
+                fprintf(stderr, "Error: Engine logging is only supported in VsCode interpreter mode.\n");
+                return EXIT_FAILURE;
+            }
             protocol.reset(new MIProtocol());
             static_cast<MIProtocol*>(protocol.get())->SetDebugger(&debugger);
             break;
         case InterpreterVSCode:
-            protocol.reset(new VSCodeProtocol());
-            static_cast<VSCodeProtocol*>(protocol.get())->SetDebugger(&debugger);
+        {
+            VSCodeProtocol *vsCodeProtocol = new VSCodeProtocol();
+            protocol.reset(vsCodeProtocol);
+            vsCodeProtocol->SetDebugger(&debugger);
+            if (engineLogging)
+                vsCodeProtocol->EngineLogging(logFilePath);
             break;
+        }
     }
 
     debugger.SetProtocol(protocol.get());
index a7ade5297c52aac4fe836caea84fa6ad62ef10c8..56a943a454e15a2c7ea5fd2b4786a99e4f6c7f25 100644 (file)
@@ -246,6 +246,7 @@ void VSCodeProtocol::EmitEvent(const std::string &name, const nlohmann::json &bo
     std::string output = response.dump();
     std::cout << CONTENT_LENGTH << output.size() << TWO_CRLF << output;
     std::cout.flush();
+    Log(lock, LOG_EVENT, output);
 }
 
 typedef std::function<HRESULT(
@@ -471,6 +472,8 @@ void VSCodeProtocol::CommandLoop()
         if (requestText.empty())
             break;
 
+        Log(std::lock_guard<std::mutex>(m_outMutex), LOG_COMMAND, requestText);
+
         json request = json::parse(requestText);
 
         std::string command = request.at("command");
@@ -509,6 +512,7 @@ void VSCodeProtocol::CommandLoop()
             std::string output = response.dump();
             std::cout << CONTENT_LENGTH << output.size() << TWO_CRLF << output;
             std::cout.flush();
+            Log(lock, LOG_RESPONSE, output);
         }
     }
 
@@ -516,3 +520,48 @@ void VSCodeProtocol::CommandLoop()
         m_debugger->Disconnect();
 
 }
+
+const std::string VSCodeProtocol::LOG_COMMAND("-> (C) ");
+const std::string VSCodeProtocol::LOG_RESPONSE("<- (R) ");
+const std::string VSCodeProtocol::LOG_EVENT("<- (E) ");
+
+void VSCodeProtocol::EngineLogging(const std::string &path)
+{
+    if (path.empty())
+    {
+        m_engineLogOutput = LogConsole;
+    }
+    else
+    {
+        m_engineLogOutput = LogFile;
+        m_engineLog.open(path);
+    }
+}
+
+void VSCodeProtocol::Log(const std::lock_guard<std::mutex> &lock, const std::string &prefix, const std::string &text)
+{
+    switch(m_engineLogOutput)
+    {
+        case LogNone:
+            return;
+        case LogFile:
+            m_engineLog << prefix << text << std::endl;
+            m_engineLog.flush();
+            return;
+        case LogConsole:
+        {
+            json response;
+            response["seq"] = m_seqCounter++;
+            response["type"] = "event";
+            response["event"] = "output";
+            response["body"] = json{
+                {"category", "console"},
+                {"output", prefix + text + "\n"}
+            };
+            std::string output = response.dump();
+            std::cout << CONTENT_LENGTH << output.size() << TWO_CRLF << output;
+            std::cout.flush();
+            return;
+        }
+    }
+}
index bfc674081d35d9c4fa186a8241f6d262b68d411f..62e80dc0990be04678ea1a5be2dbfbcca5a39cc0 100644 (file)
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 #include <mutex>
+#include <fstream>
 
 #include "json.hpp"
 #include "debugger.h"
@@ -13,7 +14,17 @@ class VSCodeProtocol : public Protocol
     static const std::string TWO_CRLF;
     static const std::string CONTENT_LENGTH;
 
+    static const std::string LOG_COMMAND;
+    static const std::string LOG_RESPONSE;
+    static const std::string LOG_EVENT;
+
     std::mutex m_outMutex;
+    enum {
+        LogNone,
+        LogConsole,
+        LogFile
+    } m_engineLogOutput;
+    std::ofstream m_engineLog;
     bool m_exit;
     Debugger *m_debugger;
 
@@ -23,10 +34,15 @@ class VSCodeProtocol : public Protocol
 
     void EmitEvent(const std::string &name, const nlohmann::json &body);
     HRESULT HandleCommand(const std::string &command, const nlohmann::json &arguments, nlohmann::json &body);
+
+    void Log(const std::lock_guard<std::mutex> &lock, const std::string &prefix, const std::string &text);
+
 public:
 
-    VSCodeProtocol() : m_exit(false), m_seqCounter(1) {}
+    VSCodeProtocol() : m_engineLogOutput(LogNone), m_exit(false), m_seqCounter(1) {}
     void SetDebugger(Debugger *debugger) { m_debugger = debugger; }
+    void EngineLogging(const std::string &path);
+
     void EmitInitializedEvent() override;
     void EmitStoppedEvent(StoppedEvent event) override;
     void EmitExitedEvent(ExitedEvent event) override;