[Lldb-commits] [PATCH] D156493: [lldb-vsocde] Adding support for the "disassemble" request.

2023-08-02 Thread John Harrison via Phabricator via lldb-commits
ashgti added a comment.

Do you have any additional information about the failure? The link looks like a 
timeout, so I'm not sure where things are timing out.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156493/new/

https://reviews.llvm.org/D156493

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D156493: [lldb-vsocde] Adding support for the "disassemble" request.

2023-07-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 545278.
ashgti added a comment.

Adjusting the unit test to only check 2 frames instead of 3 and adjusted the 
assertions.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156493/new/

https://reviews.llvm.org/D156493

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/coreFile/TestVSCode_coreFile.py
  lldb/test/API/tools/lldb-vscode/disassemble/Makefile
  lldb/test/API/tools/lldb-vscode/disassemble/TestVSCode_disassemble.py
  lldb/test/API/tools/lldb-vscode/disassemble/main.c
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/SourceReference.h
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/VSCodeForward.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -50,6 +50,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
@@ -1563,6 +1564,8 @@
   body.try_emplace("supportsStepInTargetsRequest", false);
   // The debug adapter supports the completions request.
   body.try_emplace("supportsCompletionsRequest", true);
+  // The debug adapter supports the disassembly request.
+  body.try_emplace("supportsDisassembleRequest", true);
 
   llvm::json::Array completion_characters;
   completion_characters.emplace_back(".");
@@ -2588,18 +2591,7 @@
 void request_source(const llvm::json::Object ) {
   llvm::json::Object response;
   FillResponse(request, response);
-  llvm::json::Object body;
-
-  auto arguments = request.getObject("arguments");
-  auto source = arguments->getObject("source");
-  auto sourceReference = GetSigned(source, "sourceReference", -1);
-  auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference);
-  if (pos != g_vsc.source_map.end()) {
-EmplaceSafeString(body, "content", pos->second.content);
-  } else {
-response["success"] = llvm::json::Value(false);
-  }
-  EmplaceSafeString(body, "mimeType", "text/x-lldb.disassembly");
+  llvm::json::Object body{{"content", ""}};
   response.try_emplace("body", std::move(body));
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
@@ -3290,6 +3282,211 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+// "DisassembleRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Disassembles code stored at the provided
+// location.\nClients should only call this request if the corresponding
+// capability `supportsDisassembleRequest` is true.", "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "disassemble" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/DisassembleArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "DisassembleArguments": {
+//   "type": "object",
+//   "description": "Arguments for `disassemble` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location containing the
+//   instructions to disassemble."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before disassembling. Can be negative."
+// },
+// "instructionOffset": {
+//   "type": "integer",
+//   "description": "Offset (in instructions) to be applied after the byte
+//   offset (if any) before disassembling. Can be negative."
+// },
+// "instructionCount": {
+//   "type": "integer",
+//   "description": "Number of instructions to disassemble starting at the
+//   specified location and offset.\nAn adapter must return exactly this
+//   number of instructions - any unavailable instructions should be
+//   replaced with an implementation-defined 'invalid instruction' value."
+// },
+// "resolveSymbols": {
+//   "type": "boolean",
+//   "description": "If true, the adapter should attempt to resolve memory
+//   addresses and other values to symbolic names."
+// }
+//   },
+//   "required": [ "memoryReference", "instructionCount" ]
+// },
+// "DisassembleResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `disassemble` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//  

[Lldb-commits] [PATCH] D156493: [lldb-vsocde] Adding support for the "disassemble" request.

2023-07-27 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 544982.
ashgti added a comment.

Adding new tests to cover the behavior of the disassemble request.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156493/new/

https://reviews.llvm.org/D156493

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/coreFile/TestVSCode_coreFile.py
  lldb/test/API/tools/lldb-vscode/disassemble/Makefile
  lldb/test/API/tools/lldb-vscode/disassemble/TestVSCode_disassemble.py
  lldb/test/API/tools/lldb-vscode/disassemble/main.c
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/SourceReference.h
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/VSCodeForward.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -50,6 +50,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
@@ -1563,6 +1564,8 @@
   body.try_emplace("supportsStepInTargetsRequest", false);
   // The debug adapter supports the completions request.
   body.try_emplace("supportsCompletionsRequest", true);
+  // The debug adapter supports the disassembly request.
+  body.try_emplace("supportsDisassembleRequest", true);
 
   llvm::json::Array completion_characters;
   completion_characters.emplace_back(".");
@@ -2588,18 +2591,7 @@
 void request_source(const llvm::json::Object ) {
   llvm::json::Object response;
   FillResponse(request, response);
-  llvm::json::Object body;
-
-  auto arguments = request.getObject("arguments");
-  auto source = arguments->getObject("source");
-  auto sourceReference = GetSigned(source, "sourceReference", -1);
-  auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference);
-  if (pos != g_vsc.source_map.end()) {
-EmplaceSafeString(body, "content", pos->second.content);
-  } else {
-response["success"] = llvm::json::Value(false);
-  }
-  EmplaceSafeString(body, "mimeType", "text/x-lldb.disassembly");
+  llvm::json::Object body{{"content", ""}};
   response.try_emplace("body", std::move(body));
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
@@ -3290,6 +3282,211 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+// "DisassembleRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Disassembles code stored at the provided
+// location.\nClients should only call this request if the corresponding
+// capability `supportsDisassembleRequest` is true.", "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "disassemble" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/DisassembleArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "DisassembleArguments": {
+//   "type": "object",
+//   "description": "Arguments for `disassemble` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location containing the
+//   instructions to disassemble."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before disassembling. Can be negative."
+// },
+// "instructionOffset": {
+//   "type": "integer",
+//   "description": "Offset (in instructions) to be applied after the byte
+//   offset (if any) before disassembling. Can be negative."
+// },
+// "instructionCount": {
+//   "type": "integer",
+//   "description": "Number of instructions to disassemble starting at the
+//   specified location and offset.\nAn adapter must return exactly this
+//   number of instructions - any unavailable instructions should be
+//   replaced with an implementation-defined 'invalid instruction' value."
+// },
+// "resolveSymbols": {
+//   "type": "boolean",
+//   "description": "If true, the adapter should attempt to resolve memory
+//   addresses and other values to symbolic names."
+// }
+//   },
+//   "required": [ "memoryReference", "instructionCount" ]
+// },
+// "DisassembleResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `disassemble` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "instructions": {
+// 

[Lldb-commits] [PATCH] D156493: [lldb-vsocde] Adding support for the "disassemble" request.

2023-07-27 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 544977.
ashgti added a comment.

Fixing a test and removing dead code.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156493/new/

https://reviews.llvm.org/D156493

Files:
  lldb/test/API/tools/lldb-vscode/coreFile/TestVSCode_coreFile.py
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/SourceReference.h
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/VSCodeForward.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -50,6 +50,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
@@ -1563,6 +1564,8 @@
   body.try_emplace("supportsStepInTargetsRequest", false);
   // The debug adapter supports the completions request.
   body.try_emplace("supportsCompletionsRequest", true);
+  // The debug adapter supports the disassembly request.
+  body.try_emplace("supportsDisassembleRequest", true);
 
   llvm::json::Array completion_characters;
   completion_characters.emplace_back(".");
@@ -2588,18 +2591,7 @@
 void request_source(const llvm::json::Object ) {
   llvm::json::Object response;
   FillResponse(request, response);
-  llvm::json::Object body;
-
-  auto arguments = request.getObject("arguments");
-  auto source = arguments->getObject("source");
-  auto sourceReference = GetSigned(source, "sourceReference", -1);
-  auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference);
-  if (pos != g_vsc.source_map.end()) {
-EmplaceSafeString(body, "content", pos->second.content);
-  } else {
-response["success"] = llvm::json::Value(false);
-  }
-  EmplaceSafeString(body, "mimeType", "text/x-lldb.disassembly");
+  llvm::json::Object body{{"content", ""}};
   response.try_emplace("body", std::move(body));
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
@@ -3290,6 +3282,211 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+// "DisassembleRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Disassembles code stored at the provided
+// location.\nClients should only call this request if the corresponding
+// capability `supportsDisassembleRequest` is true.", "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "disassemble" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/DisassembleArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "DisassembleArguments": {
+//   "type": "object",
+//   "description": "Arguments for `disassemble` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location containing the
+//   instructions to disassemble."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before disassembling. Can be negative."
+// },
+// "instructionOffset": {
+//   "type": "integer",
+//   "description": "Offset (in instructions) to be applied after the byte
+//   offset (if any) before disassembling. Can be negative."
+// },
+// "instructionCount": {
+//   "type": "integer",
+//   "description": "Number of instructions to disassemble starting at the
+//   specified location and offset.\nAn adapter must return exactly this
+//   number of instructions - any unavailable instructions should be
+//   replaced with an implementation-defined 'invalid instruction' value."
+// },
+// "resolveSymbols": {
+//   "type": "boolean",
+//   "description": "If true, the adapter should attempt to resolve memory
+//   addresses and other values to symbolic names."
+// }
+//   },
+//   "required": [ "memoryReference", "instructionCount" ]
+// },
+// "DisassembleResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `disassemble` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "instructions": {
+// "type": "array",
+// "items": {
+//   "$ref": "#/definitions/DisassembledInstruction"
+// },
+// "description": "The list of disassembled instructions."
+//   }
+// },
+// "required": [ "instructions" ]
+//   }
+// }
+//   }]
+// }
+void 

[Lldb-commits] [PATCH] D156493: [lldb-vsocde] Adding support for the "disassemble" request.

2023-07-27 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 544957.
ashgti added a comment.
Herald added a subscriber: JDevlieghere.

Minor fix.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156493/new/

https://reviews.llvm.org/D156493

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -50,6 +50,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
@@ -1563,6 +1564,8 @@
   body.try_emplace("supportsStepInTargetsRequest", false);
   // The debug adapter supports the completions request.
   body.try_emplace("supportsCompletionsRequest", true);
+  // The debug adapter supports the disassembly request.
+  body.try_emplace("supportsDisassembleRequest", true);
 
   llvm::json::Array completion_characters;
   completion_characters.emplace_back(".");
@@ -3290,6 +3293,211 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+// "DisassembleRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Disassembles code stored at the provided
+// location.\nClients should only call this request if the corresponding
+// capability `supportsDisassembleRequest` is true.", "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "disassemble" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/DisassembleArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "DisassembleArguments": {
+//   "type": "object",
+//   "description": "Arguments for `disassemble` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location containing the
+//   instructions to disassemble."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before disassembling. Can be negative."
+// },
+// "instructionOffset": {
+//   "type": "integer",
+//   "description": "Offset (in instructions) to be applied after the byte
+//   offset (if any) before disassembling. Can be negative."
+// },
+// "instructionCount": {
+//   "type": "integer",
+//   "description": "Number of instructions to disassemble starting at the
+//   specified location and offset.\nAn adapter must return exactly this
+//   number of instructions - any unavailable instructions should be
+//   replaced with an implementation-defined 'invalid instruction' value."
+// },
+// "resolveSymbols": {
+//   "type": "boolean",
+//   "description": "If true, the adapter should attempt to resolve memory
+//   addresses and other values to symbolic names."
+// }
+//   },
+//   "required": [ "memoryReference", "instructionCount" ]
+// },
+// "DisassembleResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `disassemble` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "instructions": {
+// "type": "array",
+// "items": {
+//   "$ref": "#/definitions/DisassembledInstruction"
+// },
+// "description": "The list of disassembled instructions."
+//   }
+// },
+// "required": [ "instructions" ]
+//   }
+// }
+//   }]
+// }
+void request_disassemble(const llvm::json::Object ) {
+  llvm::json::Object response;
+  FillResponse(request, response);
+  auto arguments = request.getObject("arguments");
+
+  auto memoryReference = GetString(arguments, "memoryReference");
+  lldb::addr_t addr_ptr;
+  if (memoryReference.consumeInteger(0, addr_ptr)) {
+response["success"] = false;
+response["message"] =
+"Malformed memory reference: " + memoryReference.str();
+g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  addr_ptr += GetSigned(arguments, "instructionOffset", 0);
+  lldb::SBAddress addr(addr_ptr, g_vsc.target);
+  if (!addr.IsValid()) {
+response["success"] = false;
+response["message"] = "Memory reference not found in the current binary.";
+g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  const auto inst_count = GetUnsigned(arguments, "instructionCount", 0);
+  lldb::SBInstructionList insts =
+  g_vsc.target.ReadInstructions(addr, inst_count);
+
+  if (!insts.IsValid()) {
+

[Lldb-commits] [PATCH] D156493: [lldb-vsocde] Adding support for the "disassemble" request.

2023-07-27 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Instead of creating psuedo source files for each stack frame this change adopts 
the new DAP “disassemble” request, allowing clients to inspect assembly 
instructions of files with debug info in addition to files without debug info.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156493

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -50,6 +50,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
@@ -1563,6 +1564,8 @@
   body.try_emplace("supportsStepInTargetsRequest", false);
   // The debug adapter supports the completions request.
   body.try_emplace("supportsCompletionsRequest", true);
+  // The debug adapter supports the disassembly request.
+  body.try_emplace("supportsDisassembleRequest", true);
 
   llvm::json::Array completion_characters;
   completion_characters.emplace_back(".");
@@ -3290,6 +3293,212 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+// "DisassembleRequest": {
+//   "allOf": [ { "$ref": "#/definitions/Request" }, {
+// "type": "object",
+// "description": "Disassembles code stored at the provided
+// location.\nClients should only call this request if the corresponding
+// capability `supportsDisassembleRequest` is true.", "properties": {
+//   "command": {
+// "type": "string",
+// "enum": [ "disassemble" ]
+//   },
+//   "arguments": {
+// "$ref": "#/definitions/DisassembleArguments"
+//   }
+// },
+// "required": [ "command", "arguments" ]
+//   }]
+// },
+// "DisassembleArguments": {
+//   "type": "object",
+//   "description": "Arguments for `disassemble` request.",
+//   "properties": {
+// "memoryReference": {
+//   "type": "string",
+//   "description": "Memory reference to the base location containing the
+//   instructions to disassemble."
+// },
+// "offset": {
+//   "type": "integer",
+//   "description": "Offset (in bytes) to be applied to the reference
+//   location before disassembling. Can be negative."
+// },
+// "instructionOffset": {
+//   "type": "integer",
+//   "description": "Offset (in instructions) to be applied after the byte
+//   offset (if any) before disassembling. Can be negative."
+// },
+// "instructionCount": {
+//   "type": "integer",
+//   "description": "Number of instructions to disassemble starting at the
+//   specified location and offset.\nAn adapter must return exactly this
+//   number of instructions - any unavailable instructions should be
+//   replaced with an implementation-defined 'invalid instruction' value."
+// },
+// "resolveSymbols": {
+//   "type": "boolean",
+//   "description": "If true, the adapter should attempt to resolve memory
+//   addresses and other values to symbolic names."
+// }
+//   },
+//   "required": [ "memoryReference", "instructionCount" ]
+// },
+// "DisassembleResponse": {
+//   "allOf": [ { "$ref": "#/definitions/Response" }, {
+// "type": "object",
+// "description": "Response to `disassemble` request.",
+// "properties": {
+//   "body": {
+// "type": "object",
+// "properties": {
+//   "instructions": {
+// "type": "array",
+// "items": {
+//   "$ref": "#/definitions/DisassembledInstruction"
+// },
+// "description": "The list of disassembled instructions."
+//   }
+// },
+// "required": [ "instructions" ]
+//   }
+// }
+//   }]
+// }
+void request_disassemble(const llvm::json::Object ) {
+  llvm::json::Object response;
+  FillResponse(request, response);
+  auto arguments = request.getObject("arguments");
+
+  auto memoryReference = GetString(arguments, "memoryReference");
+  lldb::addr_t addr_ptr;
+  if (memoryReference.consumeInteger(0, addr_ptr)) {
+response["success"] = false;
+response["message"] =
+"Malformed memory reference: " + memoryReference.str();
+g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }
+
+  addr_ptr += GetSigned(arguments, "instructionOffset", 0);
+  lldb::SBAddress addr(addr_ptr, g_vsc.target);
+  if (!addr.IsValid()) {
+response["success"] = false;
+response["message"] = "Memory reference not found in the current binary.";
+g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+return;
+  }

[Lldb-commits] [PATCH] D156465: [lldb-vscode] Adding support for displaying backtraces.

2023-07-27 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 544946.
ashgti edited the summary of this revision.
ashgti added a comment.

Applying clang-format.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156465/new/

https://reviews.llvm.org/D156465

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -2687,13 +2687,72 @@
 const auto startFrame = GetUnsigned(arguments, "startFrame", 0);
 const auto levels = GetUnsigned(arguments, "levels", 0);
 const auto endFrame = (levels == 0) ? INT64_MAX : (startFrame + levels);
+auto totalFrames = thread.GetNumFrames();
+
+// This will always return an invalid thread when
+// libBacktraceRecording.dylib is not loaded or if there is no extended
+// backtrace.
+lldb::SBThread queue_backtrace_thread =
+thread.GetExtendedBacktraceThread("libdispatch");
+if (queue_backtrace_thread.IsValid()) {
+  // One extra frame as a label to mark the enqueued thread.
+  totalFrames += queue_backtrace_thread.GetNumFrames() + 1;
+}
+
+// This will always return an invalid thread when there is no exception in
+// the current thread.
+lldb::SBThread exception_backtrace_thread =
+thread.GetCurrentExceptionBacktrace();
+if (exception_backtrace_thread.IsValid()) {
+  // One extra frame as a label to mark the exception thread.
+  totalFrames += exception_backtrace_thread.GetNumFrames() + 1;
+}
+
 for (uint32_t i = startFrame; i < endFrame; ++i) {
-  auto frame = thread.GetFrameAtIndex(i);
+  lldb::SBFrame frame;
+  std::string prefix;
+  if (i < thread.GetNumFrames()) {
+frame = thread.GetFrameAtIndex(i);
+  } else if (queue_backtrace_thread.IsValid() &&
+ i < (thread.GetNumFrames() +
+  queue_backtrace_thread.GetNumFrames() + 1)) {
+if (i == thread.GetNumFrames()) {
+  const uint32_t thread_idx =
+  queue_backtrace_thread.GetExtendedBacktraceOriginatingIndexID();
+  const char *queue_name = queue_backtrace_thread.GetQueueName();
+  auto name = llvm::formatv("Enqueued from {0} (Thread {1})",
+queue_name, thread_idx);
+  stackFrames.emplace_back(
+  llvm::json::Object{{"id", thread.GetThreadID() + 1},
+ {"name", name},
+ {"presentationHint", "label"}});
+  continue;
+}
+frame = queue_backtrace_thread.GetFrameAtIndex(
+i - thread.GetNumFrames() - 1);
+  } else if (exception_backtrace_thread.IsValid()) {
+if (i == thread.GetNumFrames() +
+ (queue_backtrace_thread.IsValid()
+  ? queue_backtrace_thread.GetNumFrames() + 1
+  : 0)) {
+  stackFrames.emplace_back(
+  llvm::json::Object{{"id", thread.GetThreadID() + 2},
+ {"name", "Original Exception Backtrace"},
+ {"presentationHint", "label"}});
+  continue;
+}
+
+frame = exception_backtrace_thread.GetFrameAtIndex(
+i - thread.GetNumFrames() -
+(queue_backtrace_thread.IsValid()
+ ? queue_backtrace_thread.GetNumFrames() + 1
+ : 0));
+  }
   if (!frame.IsValid())
 break;
   stackFrames.emplace_back(CreateStackFrame(frame));
 }
-const auto totalFrames = thread.GetNumFrames();
+
 body.try_emplace("totalFrames", totalFrames);
   }
   body.try_emplace("stackFrames", std::move(stackFrames));
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -815,17 +815,30 @@
 llvm::json::Value CreateThread(lldb::SBThread ) {
   llvm::json::Object object;
   object.try_emplace("id", (int64_t)thread.GetThreadID());
-  char thread_str[64];
-  snprintf(thread_str, sizeof(thread_str), "Thread #%u", thread.GetIndexID());
-  const char *name = thread.GetName();
-  if (name) {
-std::string thread_with_name(thread_str);
-thread_with_name += ' ';
-thread_with_name += name;
-EmplaceSafeString(object, "name", thread_with_name);
+  const char *thread_name = thread.GetName();
+  const char *queue_name = thread.GetQueueName();
+
+  std::string thread_str;
+  if (thread_name) {
+thread_str = std::string(thread_name);
+  } else if (queue_name) {
+auto kind = thread.GetQueue().GetKind();
+std::string queue_kind_label = "";
+if (kind == lldb::eQueueKindSerial) {
+  queue_kind_label = " (serial)";
+} else if (kind == 

[Lldb-commits] [PATCH] D156465: [lldb-vscode] Adding support for displaying backtraces.

2023-07-27 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

On Apple platforms when debugging with libBacktraceRecording.dylib backtraces 
are stored as part of the thread stack. This change includes support for 
displaying the back traces when they are present in the stack trace.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156465

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -2687,13 +2687,61 @@
 const auto startFrame = GetUnsigned(arguments, "startFrame", 0);
 const auto levels = GetUnsigned(arguments, "levels", 0);
 const auto endFrame = (levels == 0) ? INT64_MAX : (startFrame + levels);
+auto totalFrames = thread.GetNumFrames();
+
+// This will always return an invalid thread when libBacktraceRecording.dylib
+// is not loaded or if there is no extended backtrace.
+lldb::SBThread queue_backtrace_thread =
+thread.GetExtendedBacktraceThread("libdispatch");
+if (queue_backtrace_thread.IsValid()) {
+  // One extra frame as a label to mark the enqueued thread.
+  totalFrames += queue_backtrace_thread.GetNumFrames() + 1;
+}
+
+// This will always return an invalid thread when there is no exception in the
+// current thread.
+lldb::SBThread exception_backtrace_thread =
+thread.GetCurrentExceptionBacktrace();
+if (exception_backtrace_thread.IsValid()) {
+  // One extra frame as a label to mark the exception thread.
+  totalFrames += exception_backtrace_thread.GetNumFrames() + 1;
+}
+
 for (uint32_t i = startFrame; i < endFrame; ++i) {
-  auto frame = thread.GetFrameAtIndex(i);
+  lldb::SBFrame frame;
+  std::string prefix;
+  if (i < thread.GetNumFrames()) {
+frame = thread.GetFrameAtIndex(i);
+  } else if (queue_backtrace_thread.IsValid() && i < (thread.GetNumFrames() + queue_backtrace_thread.GetNumFrames() + 1)) {
+if (i == thread.GetNumFrames()) {
+  const uint32_t thread_idx = queue_backtrace_thread.GetExtendedBacktraceOriginatingIndexID();
+  const char *queue_name = queue_backtrace_thread.GetQueueName();
+  auto name = llvm::formatv("Enqueued from {0} (Thread {1})", queue_name, thread_idx);
+  stackFrames.emplace_back(llvm::json::Object{
+{"id", thread.GetThreadID() + 1}, 
+{"name", name},
+{"presentationHint", "label"}
+  });
+  continue;
+}
+frame = queue_backtrace_thread.GetFrameAtIndex(i - thread.GetNumFrames() - 1);
+  } else if (exception_backtrace_thread.IsValid()) {
+if (i == thread.GetNumFrames() + (queue_backtrace_thread.IsValid() ? queue_backtrace_thread.GetNumFrames() + 1 : 0)) {
+  stackFrames.emplace_back(llvm::json::Object{
+{"id", thread.GetThreadID() + 2}, 
+{"name", "Original Exception Backtrace"}, 
+{"presentationHint", "label"}
+  });
+  continue;
+}
+
+frame = exception_backtrace_thread.GetFrameAtIndex(i - thread.GetNumFrames() - (queue_backtrace_thread.IsValid() ? queue_backtrace_thread.GetNumFrames() + 1 : 0));
+  }
   if (!frame.IsValid())
 break;
   stackFrames.emplace_back(CreateStackFrame(frame));
 }
-const auto totalFrames = thread.GetNumFrames();
+
 body.try_emplace("totalFrames", totalFrames);
   }
   body.try_emplace("stackFrames", std::move(stackFrames));
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -815,17 +815,30 @@
 llvm::json::Value CreateThread(lldb::SBThread ) {
   llvm::json::Object object;
   object.try_emplace("id", (int64_t)thread.GetThreadID());
-  char thread_str[64];
-  snprintf(thread_str, sizeof(thread_str), "Thread #%u", thread.GetIndexID());
-  const char *name = thread.GetName();
-  if (name) {
-std::string thread_with_name(thread_str);
-thread_with_name += ' ';
-thread_with_name += name;
-EmplaceSafeString(object, "name", thread_with_name);
+  const char *thread_name = thread.GetName();
+  const char *queue_name = thread.GetQueueName();
+
+  std::string thread_str;
+  if (thread_name) {
+thread_str = std::string(thread_name);
+  } else if (queue_name) {
+auto kind = thread.GetQueue().GetKind();
+std::string queue_kind_label = "";
+if (kind == lldb::eQueueKindSerial) {
+  queue_kind_label = " (serial)";
+} else if (kind == lldb::eQueueKindConcurrent) {
+  queue_kind_label = " (concurrent)";
+}
+
+thread_str = llvm::formatv("Thread {0} 

[Lldb-commits] [PATCH] D154989: [lldb-vsocde] Add a 'continued' event for programmatic continue events.

2023-07-25 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 544017.
ashgti added a comment.

Adding back the 'threadCausedFocus' field, that is used in tests to verify 
behavior.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154989/new/

https://reviews.llvm.org/D154989

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/lldb-vscode.cpp


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,28 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (!g_vsc.configuration_done_sent ||
+  g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +274,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -262,6 +284,7 @@
   // we at least let the UI know we stopped.
   if (num_threads_with_reason == 0) {
 lldb::SBThread thread = process.GetThreadAtIndex(0);
+g_vsc.focus_tid = thread.GetThreadID();
 g_vsc.SendJSON(CreateThreadStopped(thread, stop_id));
   } else {
 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
@@ -468,6 +491,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -766,10 +790,6 @@
   llvm::json::Object response;
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
-  auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -907,6 +907,8 @@
   uint64_t bp_loc_id = thread.GetStopReasonDataAtIndex(1);
   snprintf(desc_str, sizeof(desc_str), "breakpoint %" PRIu64 ".%" PRIu64,
bp_id, bp_loc_id);
+  body.try_emplace("hitBreakpointIds",
+   llvm::json::Array{llvm::json::Value(bp_id)});
   EmplaceSafeString(body, "description", desc_str);
 }
   } break;
@@ -951,6 +953,7 @@
   EmplaceSafeString(body, "description", std::string(description));
 }
   }
+  // "threadCausedFocus" is used in tests to validate breaking behavior.
   if (tid == g_vsc.focus_tid) {
 body.try_emplace("threadCausedFocus", true);
   }


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,28 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (!g_vsc.configuration_done_sent ||
+  g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", 

[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-18 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 541728.
ashgti added a comment.

Updating patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
-  const auto expression = GetString(arguments, "expression");
+  std::string expression = GetString(arguments, "expression").str();
   llvm::StringRef context = 

[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-13 Thread John Harrison via Phabricator via lldb-commits
ashgti added a reviewer: wallace.
ashgti added a comment.

Hi wallace, this is a second attempt at this change set including updates to 
existing tests to check the behavior changes. LMKWYT


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-13 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 540219.
ashgti added a comment.

Adjusting the startDebugging test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
-  const auto expression = GetString(arguments, "expression");
+  std::string expression = GetString(arguments, "expression").str();
   

[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-13 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 540216.
ashgti added a comment.

Applying formatting.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
-  const auto expression = GetString(arguments, "expression");
+  std::string expression = GetString(arguments, "expression").str();
   llvm::StringRef 

[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-13 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

This adds a new flag and lldb runtime command to allow users to manage the 
behavior of the lldb-vscode evaluate repl request.

When evaluating a repl context this now has runtime managed flag for control 
how the repl behaviors with the follow values:

- `variable` - the existing behavior, with this mode requests are evaluted in 
the current frame context as variable expressions. To trigger a lldb command 
prefix an expression with ` and it will be evaluted as an lldb command.
- `command` - all expressions are evaluated as lldb commands.
- `auto` - An alternative mode that will attempt to determine if the expression 
is an lldb command or a variable expression. Based off the intepreted results 
the expression will be evaluted either as a command or an expression.

Additionally, I enabled completions and ensured they work with the new repl 
expression behavior to provide auto-completes.

This commit includes updates to the tests to verify the new behavior after the 
previous failures from submitting https://reviews.llvm.org/D154030.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-11 Thread John Harrison via Phabricator via lldb-commits
ashgti marked an inline comment as done.
ashgti added a comment.

In D154030#4491470 , @rastogishubham 
wrote:

> I am reverting the change for now, I apologize for any inconvenience

Thanks for reverting that, I'll take a look at the tests and double check them 
on linux as well.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154989: [lldb-vsocde] Add a 'continued' event for programmatic continue events.

2023-07-11 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 539304.
ashgti added a comment.

Applying clang-format.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154989/new/

https://reviews.llvm.org/D154989

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/lldb-vscode.cpp


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,28 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (!g_vsc.configuration_done_sent ||
+  g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +274,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -262,6 +284,7 @@
   // we at least let the UI know we stopped.
   if (num_threads_with_reason == 0) {
 lldb::SBThread thread = process.GetThreadAtIndex(0);
+g_vsc.focus_tid = thread.GetThreadID();
 g_vsc.SendJSON(CreateThreadStopped(thread, stop_id));
   } else {
 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
@@ -468,6 +491,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -766,10 +790,6 @@
   llvm::json::Object response;
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
-  auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -901,6 +901,8 @@
   uint64_t bp_loc_id = thread.GetStopReasonDataAtIndex(1);
   snprintf(desc_str, sizeof(desc_str), "breakpoint %" PRIu64 ".%" PRIu64,
bp_id, bp_loc_id);
+  body.try_emplace("hitBreakpointIds",
+   llvm::json::Array{llvm::json::Value(bp_id)});
   EmplaceSafeString(body, "description", desc_str);
 }
   } break;
@@ -945,9 +947,6 @@
   EmplaceSafeString(body, "description", std::string(description));
 }
   }
-  if (tid == g_vsc.focus_tid) {
-body.try_emplace("threadCausedFocus", true);
-  }
   body.try_emplace("preserveFocusHint", tid != g_vsc.focus_tid);
   body.try_emplace("allThreadsStopped", true);
   event.try_emplace("body", std::move(body));


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,28 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (!g_vsc.configuration_done_sent ||
+  g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);
+  body.try_emplace("allThreadsContinued", true);
+  

[Lldb-commits] [PATCH] D154989: [lldb-vsocde] Add a 'continued' event for programmatic continue events.

2023-07-11 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 539302.
ashgti added a comment.

Removing the focus_tid invalidation on the continue event, that was incorrectly 
setting the focus_tid to 0 for all continue events. Instead allow the existing 
logic in the SendThreadStoppedEvent to infer the correct focus_tid updates 
(if needed).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154989/new/

https://reviews.llvm.org/D154989

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (!g_vsc.configuration_done_sent || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +273,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -262,6 +283,7 @@
   // we at least let the UI know we stopped.
   if (num_threads_with_reason == 0) {
 lldb::SBThread thread = process.GetThreadAtIndex(0);
+g_vsc.focus_tid = thread.GetThreadID();
 g_vsc.SendJSON(CreateThreadStopped(thread, stop_id));
   } else {
 for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
@@ -468,6 +490,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -766,10 +789,6 @@
   llvm::json::Object response;
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
-  auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -264,7 +264,9 @@
   void RegisterRequestCallback(std::string request, RequestCallback callback);
 
   /// Debuggee will continue from stopped state.
-  void WillContinue() { variables.Clear(); }
+  void WillContinue() {
+variables.Clear();
+  }
 
   /// Poll the process to wait for it to reach the eStateStopped state.
   ///
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -901,6 +901,8 @@
   uint64_t bp_loc_id = thread.GetStopReasonDataAtIndex(1);
   snprintf(desc_str, sizeof(desc_str), "breakpoint %" PRIu64 ".%" PRIu64,
bp_id, bp_loc_id);
+  body.try_emplace("hitBreakpointIds",
+   llvm::json::Array{llvm::json::Value(bp_id)});
   EmplaceSafeString(body, "description", desc_str);
 }
   } break;
@@ -945,9 +947,6 @@
   EmplaceSafeString(body, "description", std::string(description));
 }
   }
-  if (tid == g_vsc.focus_tid) {
-body.try_emplace("threadCausedFocus", true);
-  }
   body.try_emplace("preserveFocusHint", tid != g_vsc.focus_tid);
   body.try_emplace("allThreadsStopped", true);
   event.try_emplace("body", std::move(body));
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154990: [lldb-vsocde] Cleaning up the usage of the Separate helper in Options.td.

2023-07-11 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added subscribers: lldb-commits, wangpc.
Herald added a project: LLDB.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154990

Files:
  lldb/tools/lldb-vscode/Options.td


Index: lldb/tools/lldb-vscode/Options.td
===
--- lldb/tools/lldb-vscode/Options.td
+++ lldb/tools/lldb-vscode/Options.td
@@ -17,25 +17,25 @@
   Alias,
   HelpText<"Alias for --wait-for-debugger">;
 
-def port: Separate<["--", "-"], "port">,
+def port: S<"port">,
   MetaVarName<"">,
   HelpText<"Communicate with the lldb-vscode tool over the defined port.">;
 def: Separate<["-"], "p">,
   Alias,
   HelpText<"Alias for --port">;
 
-def launch_target: Separate<["--", "-"], "launch-target">,
+def launch_target: S<"launch-target">,
   MetaVarName<"">,
   HelpText<"Launch a target for the launchInTerminal request. Any argument "
 "provided after this one will be passed to the target. The parameter "
 "--comm-file must also be specified.">;
 
-def comm_file: Separate<["--", "-"], "comm-file">,
+def comm_file: S<"comm-file">,
   MetaVarName<"">,
   HelpText<"The fifo file used to communicate the with the debug adaptor "
 "when using --launch-target.">;
 
-def debugger_pid: Separate<["--", "-"], "debugger-pid">,
+def debugger_pid: S<"debugger-pid">,
   MetaVarName<"">,
   HelpText<"The PID of the lldb-vscode instance that sent the launchInTerminal 
"
 "request when using --launch-target.">;


Index: lldb/tools/lldb-vscode/Options.td
===
--- lldb/tools/lldb-vscode/Options.td
+++ lldb/tools/lldb-vscode/Options.td
@@ -17,25 +17,25 @@
   Alias,
   HelpText<"Alias for --wait-for-debugger">;
 
-def port: Separate<["--", "-"], "port">,
+def port: S<"port">,
   MetaVarName<"">,
   HelpText<"Communicate with the lldb-vscode tool over the defined port.">;
 def: Separate<["-"], "p">,
   Alias,
   HelpText<"Alias for --port">;
 
-def launch_target: Separate<["--", "-"], "launch-target">,
+def launch_target: S<"launch-target">,
   MetaVarName<"">,
   HelpText<"Launch a target for the launchInTerminal request. Any argument "
 "provided after this one will be passed to the target. The parameter "
 "--comm-file must also be specified.">;
 
-def comm_file: Separate<["--", "-"], "comm-file">,
+def comm_file: S<"comm-file">,
   MetaVarName<"">,
   HelpText<"The fifo file used to communicate the with the debug adaptor "
 "when using --launch-target.">;
 
-def debugger_pid: Separate<["--", "-"], "debugger-pid">,
+def debugger_pid: S<"debugger-pid">,
   MetaVarName<"">,
   HelpText<"The PID of the lldb-vscode instance that sent the launchInTerminal "
 "request when using --launch-target.">;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154989: [lldb-vsocde] Add a 'continued' event for programmatic continue events.

2023-07-11 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 539185.
ashgti added a comment.
Herald added a subscriber: JDevlieghere.

Applying clang-format.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154989/new/

https://reviews.llvm.org/D154989

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +273,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -468,6 +489,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -766,10 +788,6 @@
   llvm::json::Object response;
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
-  auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -264,7 +264,10 @@
   void RegisterRequestCallback(std::string request, RequestCallback callback);
 
   /// Debuggee will continue from stopped state.
-  void WillContinue() { variables.Clear(); }
+  void WillContinue() {
+variables.Clear();
+focus_tid = LLDB_INVALID_THREAD_ID;
+  }
 
   /// Poll the process to wait for it to reach the eStateStopped state.
   ///
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -901,6 +901,8 @@
   uint64_t bp_loc_id = thread.GetStopReasonDataAtIndex(1);
   snprintf(desc_str, sizeof(desc_str), "breakpoint %" PRIu64 ".%" PRIu64,
bp_id, bp_loc_id);
+  body.try_emplace("hitBreakpointIds",
+   llvm::json::Array{llvm::json::Value(bp_id)});
   EmplaceSafeString(body, "description", desc_str);
 }
   } break;
@@ -945,9 +947,6 @@
   EmplaceSafeString(body, "description", std::string(description));
 }
   }
-  if (tid == g_vsc.focus_tid) {
-body.try_emplace("threadCausedFocus", true);
-  }
   body.try_emplace("preserveFocusHint", tid != g_vsc.focus_tid);
   body.try_emplace("allThreadsStopped", true);
   event.try_emplace("body", std::move(body));


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object 

[Lldb-commits] [PATCH] D154989: [lldb-vsocde] Add a 'continued' event for programmatic continue events.

2023-07-11 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

When the process is contiuned using an lldb command expression the thread state 
in VS Code is never informed and will be out of sync with the current state of 
the process. The new event will fire whenever the process is continued and 
keeps the debugger in sync with the dap client.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154989

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);  
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +273,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -468,6 +489,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -766,10 +788,6 @@
   llvm::json::Object response;
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
-  auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -264,7 +264,10 @@
   void RegisterRequestCallback(std::string request, RequestCallback callback);
 
   /// Debuggee will continue from stopped state.
-  void WillContinue() { variables.Clear(); }
+  void WillContinue() { 
+variables.Clear(); 
+focus_tid = LLDB_INVALID_THREAD_ID;
+  }
 
   /// Poll the process to wait for it to reach the eStateStopped state.
   ///
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -901,6 +901,8 @@
   uint64_t bp_loc_id = thread.GetStopReasonDataAtIndex(1);
   snprintf(desc_str, sizeof(desc_str), "breakpoint %" PRIu64 ".%" PRIu64,
bp_id, bp_loc_id);
+  body.try_emplace("hitBreakpointIds",
+   llvm::json::Array{llvm::json::Value(bp_id)});
   EmplaceSafeString(body, "description", desc_str);
 }
   } break;
@@ -945,9 +947,6 @@
   EmplaceSafeString(body, "description", std::string(description));
 }
   }
-  if (tid == g_vsc.focus_tid) {
-body.try_emplace("threadCausedFocus", true);
-  }
   body.try_emplace("preserveFocusHint", tid != g_vsc.focus_tid);
   body.try_emplace("allThreadsStopped", true);
   event.try_emplace("body", std::move(body));


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-11 Thread John Harrison via Phabricator via lldb-commits
ashgti marked 2 inline comments as done.
ashgti added inline comments.



Comment at: lldb/tools/lldb-vscode/Options.td:20-38
+def port: S<"port">,
   MetaVarName<"">,
   HelpText<"Communicate with the lldb-vscode tool over the defined port.">;
 def: Separate<["-"], "p">,
   Alias,
   HelpText<"Alias for --port">;
 

wallace wrote:
> +1
Moving this into its own commit.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-11 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 539182.
ashgti marked an inline comment as done.
ashgti added a comment.

Apply clang-format and split out some parts of this into smaller commits.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,63 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1236,17 @@
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
-  const auto expression = GetString(arguments, "expression");
+  std::string expression = GetString(arguments, "expression").str();
   llvm::StringRef context = GetString(arguments, "context");
 
-  if (!expression.empty() && expression[0] == '`') {
-auto result =
-RunLLDBCommands(llvm::StringRef(), {std::string(expression.substr(1))});
+  if (context 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-05 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 537538.
ashgti added a comment.

Removing a log statement that is not needed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);  
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +273,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -468,6 +489,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -767,9 +789,10 @@
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
   auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
+  // Invalidate the focused, continuing the process may land on any thread, not
+  // just the current thread in which case we want the client to update focus to
+  // the new stopped thread.
+  g_vsc.focus_tid = LLDB_INVALID_THREAD_ID;
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
@@ -1065,50 +1088,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(frame, text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-05 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 537536.
ashgti added a comment.

Uploading latest diff


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);  
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +273,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -468,6 +489,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -767,9 +789,10 @@
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
   auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
+  // Invalidate the focused, continuing the process may land on any thread, not
+  // just the current thread in which case we want the client to update focus to
+  // the new stopped thread.
+  g_vsc.focus_tid = LLDB_INVALID_THREAD_ID;
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
@@ -1065,50 +1088,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(frame, text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-05 Thread John Harrison via Phabricator via lldb-commits
ashgti added inline comments.



Comment at: lldb/tools/lldb-vscode/JSONUtils.h:239
+/// useful to ensure the same column provided by the setBreakpoints request
+/// are returned to the IDE as a fallback.
 ///

DavidSpickett wrote:
> Appears that this got clang-formatted accidentally. Formatting it is fine but 
> put it in an NFC change if you're gonna do that.
> 
> If you aren't already using it, the clang-format-diff script will help you 
> limit formatting to only what you've edited (with occasional extra bits): 
> https://clang.llvm.org/docs/ClangFormat.html
I had another commit (https://reviews.llvm.org/D154029) that touched this area 
of the code so I think thats how this snuck in. Reverted this change.



Comment at: lldb/tools/lldb-vscode/VSCode.cpp:797
+g_vsc.repl_mode = ReplMode::Variable;
+result.AppendMessage("lldb-vscode repl-mode variable set.");
+  } else if (new_mode == "command") {

DavidSpickett wrote:
> There is AppendMessageWithFormat that you could use to avoid repeating the 
> string here.
Do you mean Printf? Switched to that instead.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-05 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 537496.
ashgti marked 4 inline comments as done.
ashgti added a comment.

Updating the behavior of auto mode to try to evalute local variables over lldb 
commands.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-06-29 Thread John Harrison via Phabricator via lldb-commits
ashgti added a reviewer: wallace.
ashgti added a comment.

Hi wallace,

I created to improve the repl behavior of lldb-vscode allowing users to more 
easily run lldb commands. I started 
https://discourse.llvm.org/t/rfc-lldb-vscode-evaluate-repl-behavior-and-improvements/71667
 as well to outline some of behaviors from this patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-06-29 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 536031.
ashgti added a comment.

Pull + Rebase.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-06-29 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535911.
ashgti added a comment.

Adding ` as an escape hatch in auto mode to ensure lldb commands can always be 
run directly.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ 

[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.

2023-06-29 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535864.
ashgti added a comment.

Fixing stale comment.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153447/new/

https://reviews.llvm.org/D153447

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py
  lldb/test/API/tools/lldb-vscode/startDebugging/Makefile
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/test/API/tools/lldb-vscode/startDebugging/main.c
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1471,6 +1471,13 @@
 
   g_vsc.debugger =
   lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  auto cmd = g_vsc.debugger.GetCommandInterpreter().AddMultiwordCommand(
+  "lldb-vscode", nullptr);
+  cmd.AddCommand(
+  "startDebugging", _vsc.start_debugging_request_handler,
+  "Sends a startDebugging request from the debug adapter to the client to "
+  "start a child debug session of the same type as the caller.");
+
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1564,7 +1571,8 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
-llvm::Error request_runInTerminal(const llvm::json::Object _request) {
+llvm::Error request_runInTerminal(const llvm::json::Object _request,
+  const uint64_t timeout_seconds) {
   g_vsc.is_attach = true;
   lldb::SBAttachInfo attach_info;
 
@@ -1582,13 +1590,15 @@
 #endif
   llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
   launch_request, g_vsc.debug_adaptor_path, comm_file.m_path, debugger_pid);
-  llvm::json::Object reverse_response;
-  lldb_vscode::PacketStatus status =
-  g_vsc.SendReverseRequest(reverse_request, reverse_response);
-  if (status != lldb_vscode::PacketStatus::Success)
-return llvm::createStringError(llvm::inconvertibleErrorCode(),
-   "Process cannot be launched by the IDE. %s",
-   comm_channel.GetLauncherError().c_str());
+  g_vsc.SendReverseRequest("runInTerminal", std::move(reverse_request),
+   [](llvm::Expected value) {
+ if (!value) {
+   llvm::Error err = value.takeError();
+   llvm::errs()
+   << "runInTerminal request failed: "
+   << llvm::toString(std::move(err)) << "\n";
+ }
+   });
 
   if (llvm::Expected pid = comm_channel.GetLauncherPid())
 attach_info.SetProcessID(*pid);
@@ -1676,7 +1686,7 @@
   const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
 
   if (GetBoolean(arguments, "runInTerminal", false)) {
-if (llvm::Error err = request_runInTerminal(request))
+if (llvm::Error err = request_runInTerminal(request, timeout_seconds))
   error.SetErrorString(llvm::toString(std::move(err)).c_str());
   } else if (launchCommands.empty()) {
 // Disable async events so the launch will be successful when we return from
@@ -3464,17 +3474,13 @@
 g_vsc.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false);
   }
 
-  while (!g_vsc.sent_terminated_event) {
-llvm::json::Object object;
-lldb_vscode::PacketStatus status = g_vsc.GetNextObject(object);
-if (status == lldb_vscode::PacketStatus::EndOfFile)
-  break;
-if (status != lldb_vscode::PacketStatus::Success)
-  return 1; // Fatal error
-
-if (!g_vsc.HandleObject(object))
-  return 1;
+  bool CleanExit = true;
+  if (auto Err = g_vsc.Loop()) {
+if (g_vsc.log)
+  *g_vsc.log << "Transport Error: " << llvm::toString(std::move(Err))
+ << "\n";
+CleanExit = false;
   }
 
-  return EXIT_SUCCESS;
+  return CleanExit ? EXIT_SUCCESS : EXIT_FAILURE;
 }
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -11,8 +11,10 @@
 
 #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -73,6 +75,7 @@
 };
 
 typedef void (*RequestCallback)(const llvm::json::Object );
+typedef void (*ResponseCallback)(llvm::Expected value);
 
 enum class PacketStatus {
   Success = 0,
@@ -121,6 +124,11 @@
   void Clear();
 };
 
+struct StartDebuggingRequestHandler : 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535592.
ashgti added a comment.

Formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535591.
ashgti added a comment.

Formatting.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535590.
ashgti added a comment.

Another tweak to the auto mode behavior.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto 

[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535580.
ashgti added a comment.

Small tweak to the auto expression mode.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154030/new/

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto 

[Lldb-commits] [PATCH] D154029: [lldb-vscode] Adding support for column break points.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti added reviewers: wallace, ivanhernandez13.
ashgti added a comment.

Adding column information to breakpoints, including the ability to set column 
inline breakpoints from VS Code.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154029/new/

https://reviews.llvm.org/D154029

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154028: [lldb-vscode] Prior to running the launchCommands during a launch request set the launch info so the configured launch information is accessible by the launch commands.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti added a reviewer: wallace.
ashgti added a comment.

A small improvement to allow launchCommands to access the configured launch 
info.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154028/new/

https://reviews.llvm.org/D154028

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154026: [lldb-vscode] Adjusting CreateSource to detect compiler generated frames.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti added reviewers: ivanhernandez13, wallace.
ashgti added a comment.

A small fix for displaying compiler-generated frames.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154026/new/

https://reviews.llvm.org/D154026

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

This adds a new flag and lldb runtime command to allow users to manage the 
behavior of the lldb-vscode evaluate repl request.

When evaluating a repl context this now has runtime managed flag for control 
how the repl behaviors with the follow values:

- `variable` - the existing behavior, with this mode requests are evaluted in 
the current frame context as variable expressions. To trigger a lldb command 
prefix an expression with ` and it will be evaluted as an lldb command.
- `command` - all expressions are evaluated as lldb commands.
- `auto` - An alternative mode that will attempt to determine if the expression 
is an lldb command or a variable expression. Based off the intepreted results 
the expression will be evaluted either as a command or an expression.

Additionally, I enabled completions and ensured they work with the new repl 
expression behavior to provide auto-completes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  

[Lldb-commits] [PATCH] D154029: [lldb-vscode] Adding support for column break points.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154029

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp


Index: lldb/tools/lldb-vscode/SourceBreakpoint.cpp
===
--- lldb/tools/lldb-vscode/SourceBreakpoint.cpp
+++ lldb/tools/lldb-vscode/SourceBreakpoint.cpp
@@ -16,7 +16,9 @@
   column(GetUnsigned(obj, "column", 0)) {}
 
 void SourceBreakpoint::SetBreakpoint(const llvm::StringRef source_path) {
-  bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), 
line);
+  lldb::SBFileSpecList module_list;
+  bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line,
+   column, 0, module_list);
   // See comments in BreakpointBase::GetBreakpointLabel() for details of why
   // we add a label to our breakpoints.
   bp.AddName(GetBreakpointLabel());
Index: lldb/tools/lldb-vscode/JSONUtils.h
===
--- lldb/tools/lldb-vscode/JSONUtils.h
+++ lldb/tools/lldb-vscode/JSONUtils.h
@@ -232,13 +232,21 @@
 /// provided by the setBreakpoints request are returned to the IDE as a
 /// fallback.
 ///
+/// \param[in] request_column
+/// An optional column to use when creating the resulting "Breakpoint" 
object.
+/// It is used if the breakpoint has no valid locations.
+/// It is useful to ensure the same column
+/// provided by the setBreakpoints request are returned to the IDE as a
+/// fallback.
+///
 /// \return
 /// A "Breakpoint" JSON object with that follows the formal JSON
 /// definition outlined by Microsoft.
 llvm::json::Value
 CreateBreakpoint(lldb::SBBreakpoint ,
  std::optional request_path = std::nullopt,
- std::optional request_line = std::nullopt);
+ std::optional request_line = std::nullopt,
+ std::optional request_column = std::nullopt);
 
 /// Converts a LLDB module to a VS Code DAP module for use in "modules" events.
 ///
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -308,7 +308,8 @@
 // }
 llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint ,
std::optional request_path,
-   std::optional request_line) {
+   std::optional request_line,
+   std::optional request_column) {
   // Each breakpoint location is treated as a separate breakpoint for VS code.
   // They don't have the notion of a single breakpoint with multiple locations.
   llvm::json::Object object;
@@ -345,11 +346,16 @@
 const auto line = line_entry.GetLine();
 if (line != UINT32_MAX)
   object.try_emplace("line", line);
+const auto column = line_entry.GetColumn();
+if (column != 0)
+  object.try_emplace("column", column);
 object.try_emplace("source", CreateSource(line_entry));
   }
   // We try to add request_line as a fallback
   if (request_line)
 object.try_emplace("line", *request_line);
+  if (request_column)
+object.try_emplace("column", *request_column);
   return llvm::json::Value(std::move(object));
 }
 


Index: lldb/tools/lldb-vscode/SourceBreakpoint.cpp
===
--- lldb/tools/lldb-vscode/SourceBreakpoint.cpp
+++ lldb/tools/lldb-vscode/SourceBreakpoint.cpp
@@ -16,7 +16,9 @@
   column(GetUnsigned(obj, "column", 0)) {}
 
 void SourceBreakpoint::SetBreakpoint(const llvm::StringRef source_path) {
-  bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line);
+  lldb::SBFileSpecList module_list;
+  bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line,
+   column, 0, module_list);
   // See comments in BreakpointBase::GetBreakpointLabel() for details of why
   // we add a label to our breakpoints.
   bp.AddName(GetBreakpointLabel());
Index: lldb/tools/lldb-vscode/JSONUtils.h
===
--- lldb/tools/lldb-vscode/JSONUtils.h
+++ lldb/tools/lldb-vscode/JSONUtils.h
@@ -232,13 +232,21 @@
 /// provided by the setBreakpoints request are returned to the IDE as a
 /// fallback.
 ///
+/// \param[in] request_column
+/// An optional column to use when creating the resulting "Breakpoint" object.
+/// It is used if the breakpoint has no valid locations.
+/// It is useful to ensure the same column
+/// provided by the setBreakpoints request are 

[Lldb-commits] [PATCH] D154028: [lldb-vscode] Prior to running the launchCommands during a launch request set the launch info so the configured launch information is accessible by the launch commands.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154028

Files:
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/lldb-vscode.cpp


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1695,6 +1695,9 @@
 g_vsc.target.Launch(launch_info, error);
 g_vsc.debugger.SetAsync(true);
   } else {
+// Set the launch info so that run commands can access the configured 
+// launch details.
+g_vsc.target.SetLaunchInfo(launch_info);
 g_vsc.RunLLDBCommands("Running launchCommands:", launchCommands);
 // The custom commands might have created a new target so we should use the
 // selected target after these commands are run.
Index: lldb/tools/lldb-vscode/README.md
===
--- lldb/tools/lldb-vscode/README.md
+++ lldb/tools/lldb-vscode/README.md
@@ -95,6 +95,7 @@
 |**initCommands**   |[string]| | LLDB commands executed upon debugger startup 
prior to creating the LLDB target. Commands and command output will be sent to 
the debugger console when they are executed.
 |**preRunCommands** |[string]| | LLDB commands executed just before launching 
after the LLDB target has been created. Commands and command output will be 
sent to the debugger console when they are executed.
 |**stopCommands**   |[string]| | LLDB commands executed just after each stop. 
Commands and command output will be sent to the debugger console when they are 
executed.
+|**launchCommands** |[string]| | LLDB commands executed to launch the program. 
Commands and command output will be sent to the debugger console when they are 
executed.
 |**exitCommands**   |[string]| | LLDB commands executed when the program 
exits. Commands and command output will be sent to the debugger console when 
they are executed.
 |**terminateCommands** |[string]| | LLDB commands executed when the debugging 
session ends. Commands and command output will be sent to the debugger console 
when they are executed.
 |**sourceMap**  |[string[2]]| | Specify an array of path re-mappings. Each 
element in the array must be a two element array containing a source and 
destination pathname.


Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1695,6 +1695,9 @@
 g_vsc.target.Launch(launch_info, error);
 g_vsc.debugger.SetAsync(true);
   } else {
+// Set the launch info so that run commands can access the configured 
+// launch details.
+g_vsc.target.SetLaunchInfo(launch_info);
 g_vsc.RunLLDBCommands("Running launchCommands:", launchCommands);
 // The custom commands might have created a new target so we should use the
 // selected target after these commands are run.
Index: lldb/tools/lldb-vscode/README.md
===
--- lldb/tools/lldb-vscode/README.md
+++ lldb/tools/lldb-vscode/README.md
@@ -95,6 +95,7 @@
 |**initCommands**   |[string]| | LLDB commands executed upon debugger startup prior to creating the LLDB target. Commands and command output will be sent to the debugger console when they are executed.
 |**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed.
 |**stopCommands**   |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed.
+|**launchCommands** |[string]| | LLDB commands executed to launch the program. Commands and command output will be sent to the debugger console when they are executed.
 |**exitCommands**   |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed.
 |**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed.
 |**sourceMap**  |[string[2]]| | Specify an array of path re-mappings. Each element in the array must be a two element array containing a source and destination pathname.
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154026: [lldb-vscode] Adjusting CreateSource to detect compiler generated frames.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154026

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp


Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -613,7 +613,9 @@
 llvm::json::Value CreateSource(lldb::SBFrame , int64_t _line) {
   disasm_line = 0;
   auto line_entry = frame.GetLineEntry();
-  if (line_entry.GetFileSpec().IsValid())
+  // A line entry of 0 indicates the line is compiler generated i.e. no source
+  // file so don't return early with the line entry.
+  if (line_entry.GetFileSpec().IsValid() && line_entry.GetLine() != 0)
 return CreateSource(line_entry);
 
   llvm::json::Object object;
@@ -650,7 +652,11 @@
   }
   const auto num_insts = insts.GetSize();
   if (low_pc != LLDB_INVALID_ADDRESS && num_insts > 0) {
-EmplaceSafeString(object, "name", frame.GetFunctionName());
+if (line_entry.GetLine() == 0) {
+  EmplaceSafeString(object, "name", "");
+} else {
+  EmplaceSafeString(object, "name", frame.GetDisplayFunctionName());
+}
 SourceReference source;
 llvm::raw_string_ostream src_strm(source.content);
 std::string line;


Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -613,7 +613,9 @@
 llvm::json::Value CreateSource(lldb::SBFrame , int64_t _line) {
   disasm_line = 0;
   auto line_entry = frame.GetLineEntry();
-  if (line_entry.GetFileSpec().IsValid())
+  // A line entry of 0 indicates the line is compiler generated i.e. no source
+  // file so don't return early with the line entry.
+  if (line_entry.GetFileSpec().IsValid() && line_entry.GetLine() != 0)
 return CreateSource(line_entry);
 
   llvm::json::Object object;
@@ -650,7 +652,11 @@
   }
   const auto num_insts = insts.GetSize();
   if (low_pc != LLDB_INVALID_ADDRESS && num_insts > 0) {
-EmplaceSafeString(object, "name", frame.GetFunctionName());
+if (line_entry.GetLine() == 0) {
+  EmplaceSafeString(object, "name", "");
+} else {
+  EmplaceSafeString(object, "name", frame.GetDisplayFunctionName());
+}
 SourceReference source;
 llvm::raw_string_ostream src_strm(source.content);
 std::string line;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D154025: [lldb-vscode] Prior to running the launchCommands during a launch request set the launch info so the configured launch information is accessible by the launch commands.

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

[lldb-vscode] Adding support for column break points.

[lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl 
expressions to allow users to more easily invoke lldb commands.

This adds a new flag and lldb runtime command to allow users to manage the 
behavior of the lldb-vscode evaluate repl request.

When evaluating a repl context this now has runtime managed flag for control 
how the repl behaviors with the follow values:

- `variable` - the existing behavior, with this mode requests are evaluted in 
the current frame context as variable expressions. To trigger a lldb command 
prefix an expression with ` and it will be evaluted as an lldb command.
- `command` - all expressions are evaluated as lldb commands.
- `auto` - An alternative mode that will attempt to determine if the expression 
is an lldb command or a variable expression. Based off the intepreted results 
the expression will be evaluted either as a command or an expression.

Additionally, I enabled completions and ensured they work with the new repl 
expression behavior to provide auto-completes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154025

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+  
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+  
   std::string text = std::string(GetString(arguments, "text"));
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for all
+// the matches. The rest of the elements are the matches.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = 

[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.

2023-06-27 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535072.
ashgti added a comment.

Removing a dead comment that is not needed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153447/new/

https://reviews.llvm.org/D153447

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py
  lldb/test/API/tools/lldb-vscode/startDebugging/Makefile
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/test/API/tools/lldb-vscode/startDebugging/main.c
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1471,6 +1471,13 @@
 
   g_vsc.debugger =
   lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  auto cmd = g_vsc.debugger.GetCommandInterpreter().AddMultiwordCommand(
+  "lldb-vscode", nullptr);
+  cmd.AddCommand(
+  "startDebugging", _vsc.start_debugging_request_handler,
+  "Sends a startDebugging request from the debug adapter to the client to "
+  "start a child debug session of the same type as the caller.");
+
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1564,7 +1571,8 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
-llvm::Error request_runInTerminal(const llvm::json::Object _request) {
+llvm::Error request_runInTerminal(const llvm::json::Object _request,
+  const uint64_t timeout_seconds) {
   g_vsc.is_attach = true;
   lldb::SBAttachInfo attach_info;
 
@@ -1582,13 +1590,15 @@
 #endif
   llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
   launch_request, g_vsc.debug_adaptor_path, comm_file.m_path, debugger_pid);
-  llvm::json::Object reverse_response;
-  lldb_vscode::PacketStatus status =
-  g_vsc.SendReverseRequest(reverse_request, reverse_response);
-  if (status != lldb_vscode::PacketStatus::Success)
-return llvm::createStringError(llvm::inconvertibleErrorCode(),
-   "Process cannot be launched by the IDE. %s",
-   comm_channel.GetLauncherError().c_str());
+  g_vsc.SendReverseRequest("runInTerminal", std::move(reverse_request),
+   [](llvm::Expected value) {
+ if (!value) {
+   llvm::Error err = value.takeError();
+   llvm::errs()
+   << "runInTerminal request failed: "
+   << llvm::toString(std::move(err)) << "\n";
+ }
+   });
 
   if (llvm::Expected pid = comm_channel.GetLauncherPid())
 attach_info.SetProcessID(*pid);
@@ -1676,7 +1686,7 @@
   const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
 
   if (GetBoolean(arguments, "runInTerminal", false)) {
-if (llvm::Error err = request_runInTerminal(request))
+if (llvm::Error err = request_runInTerminal(request, timeout_seconds))
   error.SetErrorString(llvm::toString(std::move(err)).c_str());
   } else if (launchCommands.empty()) {
 // Disable async events so the launch will be successful when we return from
@@ -3464,17 +3474,13 @@
 g_vsc.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false);
   }
 
-  while (!g_vsc.sent_terminated_event) {
-llvm::json::Object object;
-lldb_vscode::PacketStatus status = g_vsc.GetNextObject(object);
-if (status == lldb_vscode::PacketStatus::EndOfFile)
-  break;
-if (status != lldb_vscode::PacketStatus::Success)
-  return 1; // Fatal error
-
-if (!g_vsc.HandleObject(object))
-  return 1;
+  bool CleanExit = true;
+  if (auto Err = g_vsc.Loop()) {
+if (g_vsc.log)
+  *g_vsc.log << "Transport Error: " << llvm::toString(std::move(Err))
+ << "\n";
+CleanExit = false;
   }
 
-  return EXIT_SUCCESS;
+  return CleanExit ? EXIT_SUCCESS : EXIT_FAILURE;
 }
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -11,8 +11,10 @@
 
 #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -73,6 +75,7 @@
 };
 
 typedef void (*RequestCallback)(const llvm::json::Object );
+typedef void (*ResponseCallback)(llvm::Expected value);
 
 enum class PacketStatus {
   Success = 0,
@@ -121,6 +124,11 @@
   void Clear();
 };
 
+struct 

[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.

2023-06-22 Thread John Harrison via Phabricator via lldb-commits
ashgti requested review of this revision.
ashgti added a comment.

Hi @wallace I updated the tests and discovered a deadlock with my 
implementation of the SendReverseRequest. I refactored the function and added 
some additional tests to cover this more thoroughly.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153447/new/

https://reviews.llvm.org/D153447

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.

2023-06-22 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 533806.
ashgti added a comment.

Cleaning up the runInTerminal test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153447/new/

https://reviews.llvm.org/D153447

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py
  lldb/test/API/tools/lldb-vscode/startDebugging/Makefile
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/test/API/tools/lldb-vscode/startDebugging/main.c
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1471,6 +1471,13 @@
 
   g_vsc.debugger =
   lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  auto cmd = g_vsc.debugger.GetCommandInterpreter().AddMultiwordCommand(
+  "lldb-vscode", nullptr);
+  cmd.AddCommand(
+  "startDebugging", _vsc.start_debugging_request_handler,
+  "Sends a startDebugging request from the debug adapter to the client to "
+  "start a child debug session of the same type as the caller.");
+
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1564,7 +1571,8 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
-llvm::Error request_runInTerminal(const llvm::json::Object _request) {
+llvm::Error request_runInTerminal(const llvm::json::Object _request,
+  const uint64_t timeout_seconds) {
   g_vsc.is_attach = true;
   lldb::SBAttachInfo attach_info;
 
@@ -1582,13 +1590,15 @@
 #endif
   llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
   launch_request, g_vsc.debug_adaptor_path, comm_file.m_path, debugger_pid);
-  llvm::json::Object reverse_response;
-  lldb_vscode::PacketStatus status =
-  g_vsc.SendReverseRequest(reverse_request, reverse_response);
-  if (status != lldb_vscode::PacketStatus::Success)
-return llvm::createStringError(llvm::inconvertibleErrorCode(),
-   "Process cannot be launched by the IDE. %s",
-   comm_channel.GetLauncherError().c_str());
+  g_vsc.SendReverseRequest("runInTerminal", std::move(reverse_request),
+   [](llvm::Expected value) {
+ if (!value) {
+   llvm::Error err = value.takeError();
+   llvm::errs()
+   << "runInTerminal request failed: "
+   << llvm::toString(std::move(err)) << "\n";
+ }
+   });
 
   if (llvm::Expected pid = comm_channel.GetLauncherPid())
 attach_info.SetProcessID(*pid);
@@ -1676,7 +1686,7 @@
   const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
 
   if (GetBoolean(arguments, "runInTerminal", false)) {
-if (llvm::Error err = request_runInTerminal(request))
+if (llvm::Error err = request_runInTerminal(request, timeout_seconds))
   error.SetErrorString(llvm::toString(std::move(err)).c_str());
   } else if (launchCommands.empty()) {
 // Disable async events so the launch will be successful when we return from
@@ -3464,17 +3474,13 @@
 g_vsc.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false);
   }
 
-  while (!g_vsc.sent_terminated_event) {
-llvm::json::Object object;
-lldb_vscode::PacketStatus status = g_vsc.GetNextObject(object);
-if (status == lldb_vscode::PacketStatus::EndOfFile)
-  break;
-if (status != lldb_vscode::PacketStatus::Success)
-  return 1; // Fatal error
-
-if (!g_vsc.HandleObject(object))
-  return 1;
+  bool CleanExit = true;
+  if (auto Err = g_vsc.Loop()) {
+if (g_vsc.log)
+  *g_vsc.log << "Transport Error: " << llvm::toString(std::move(Err))
+ << "\n";
+CleanExit = false;
   }
 
-  return EXIT_SUCCESS;
+  return CleanExit ? EXIT_SUCCESS : EXIT_FAILURE;
 }
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -11,8 +11,10 @@
 
 #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -73,6 +75,7 @@
 };
 
 typedef void (*RequestCallback)(const llvm::json::Object );
+typedef void (*ResponseCallback)(llvm::Expected value);
 
 enum class PacketStatus {
   Success = 0,
@@ -121,6 +124,11 @@
   void Clear();
 };
 
+struct 

[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.

2023-06-22 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 533804.
ashgti added a comment.

Enhancing the test coverage and fixing an issue when a reverse request is 
invoked a request from a DAP request handler.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153447/new/

https://reviews.llvm.org/D153447

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py
  lldb/test/API/tools/lldb-vscode/startDebugging/Makefile
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/test/API/tools/lldb-vscode/startDebugging/main.c
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1471,6 +1471,13 @@
 
   g_vsc.debugger =
   lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  auto cmd = g_vsc.debugger.GetCommandInterpreter().AddMultiwordCommand(
+  "lldb-vscode", nullptr);
+  cmd.AddCommand(
+  "startDebugging", _vsc.start_debugging_request_handler,
+  "Sends a startDebugging request from the debug adapter to the client to "
+  "start a child debug session of the same type as the caller.");
+
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1564,7 +1571,8 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
-llvm::Error request_runInTerminal(const llvm::json::Object _request) {
+llvm::Error request_runInTerminal(const llvm::json::Object _request,
+  const uint64_t timeout_seconds) {
   g_vsc.is_attach = true;
   lldb::SBAttachInfo attach_info;
 
@@ -1582,13 +1590,15 @@
 #endif
   llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
   launch_request, g_vsc.debug_adaptor_path, comm_file.m_path, debugger_pid);
-  llvm::json::Object reverse_response;
-  lldb_vscode::PacketStatus status =
-  g_vsc.SendReverseRequest(reverse_request, reverse_response);
-  if (status != lldb_vscode::PacketStatus::Success)
-return llvm::createStringError(llvm::inconvertibleErrorCode(),
-   "Process cannot be launched by the IDE. %s",
-   comm_channel.GetLauncherError().c_str());
+  g_vsc.SendReverseRequest("runInTerminal", std::move(reverse_request),
+   [](llvm::Expected value) {
+ if (!value) {
+   llvm::Error err = value.takeError();
+   llvm::errs()
+   << "runInTerminal request failed: "
+   << llvm::toString(std::move(err)) << "\n";
+ }
+   });
 
   if (llvm::Expected pid = comm_channel.GetLauncherPid())
 attach_info.SetProcessID(*pid);
@@ -1676,7 +1686,7 @@
   const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
 
   if (GetBoolean(arguments, "runInTerminal", false)) {
-if (llvm::Error err = request_runInTerminal(request))
+if (llvm::Error err = request_runInTerminal(request, timeout_seconds))
   error.SetErrorString(llvm::toString(std::move(err)).c_str());
   } else if (launchCommands.empty()) {
 // Disable async events so the launch will be successful when we return from
@@ -3464,17 +3474,13 @@
 g_vsc.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false);
   }
 
-  while (!g_vsc.sent_terminated_event) {
-llvm::json::Object object;
-lldb_vscode::PacketStatus status = g_vsc.GetNextObject(object);
-if (status == lldb_vscode::PacketStatus::EndOfFile)
-  break;
-if (status != lldb_vscode::PacketStatus::Success)
-  return 1; // Fatal error
-
-if (!g_vsc.HandleObject(object))
-  return 1;
+  bool CleanExit = true;
+  if (auto Err = g_vsc.Loop()) {
+if (g_vsc.log)
+  *g_vsc.log << "Transport Error: " << llvm::toString(std::move(Err))
+ << "\n";
+CleanExit = false;
   }
 
-  return EXIT_SUCCESS;
+  return CleanExit ? EXIT_SUCCESS : EXIT_FAILURE;
 }
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -11,8 +11,10 @@
 
 #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -73,6 +75,7 @@
 };
 
 typedef void (*RequestCallback)(const llvm::json::Object );
+typedef void (*ResponseCallback)(llvm::Expected value);
 
 enum class PacketStatus {

[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.

2023-06-21 Thread John Harrison via Phabricator via lldb-commits
ashgti added a comment.

In D153447#4439359 , @wallace wrote:

> Please write an entry about this in the documentation of lldb-vscode

Updated with some additional documentation in the lldb-vscode/README.md


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153447/new/

https://reviews.llvm.org/D153447

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.

2023-06-21 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 533440.
ashgti marked 3 inline comments as done.
ashgti added a comment.

Adding documentation to the lldb-vscode/README.md.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153447/new/

https://reviews.llvm.org/D153447

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/startDebugging/Makefile
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/test/API/tools/lldb-vscode/startDebugging/main.c
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1471,6 +1471,13 @@
 
   g_vsc.debugger =
   lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  auto cmd = g_vsc.debugger.GetCommandInterpreter().AddMultiwordCommand(
+  "lldb-vscode", nullptr);
+  cmd.AddCommand(
+  "startDebugging", _vsc.start_debugging_request_handler,
+  "Sends a startDebugging request from the debug adapter to the client to "
+  "start a child debug session of the same type as the caller.");
+
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1564,7 +1571,8 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
-llvm::Error request_runInTerminal(const llvm::json::Object _request) {
+llvm::Error request_runInTerminal(const llvm::json::Object _request,
+  const uint64_t timeout_seconds) {
   g_vsc.is_attach = true;
   lldb::SBAttachInfo attach_info;
 
@@ -1582,10 +1590,10 @@
 #endif
   llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
   launch_request, g_vsc.debug_adaptor_path, comm_file.m_path, debugger_pid);
-  llvm::json::Object reverse_response;
-  lldb_vscode::PacketStatus status =
-  g_vsc.SendReverseRequest(reverse_request, reverse_response);
-  if (status != lldb_vscode::PacketStatus::Success)
+  auto sent =
+  g_vsc.SendReverseRequest("runInTerminal", std::move(reverse_request));
+  if (std::future_status::ready !=
+  sent.wait_for(std::chrono::seconds(timeout_seconds)))
 return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Process cannot be launched by the IDE. %s",
comm_channel.GetLauncherError().c_str());
@@ -1676,7 +1684,7 @@
   const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
 
   if (GetBoolean(arguments, "runInTerminal", false)) {
-if (llvm::Error err = request_runInTerminal(request))
+if (llvm::Error err = request_runInTerminal(request, timeout_seconds))
   error.SetErrorString(llvm::toString(std::move(err)).c_str());
   } else if (launchCommands.empty()) {
 // Disable async events so the launch will be successful when we return from
@@ -3464,17 +3472,13 @@
 g_vsc.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false);
   }
 
-  while (!g_vsc.sent_terminated_event) {
-llvm::json::Object object;
-lldb_vscode::PacketStatus status = g_vsc.GetNextObject(object);
-if (status == lldb_vscode::PacketStatus::EndOfFile)
-  break;
-if (status != lldb_vscode::PacketStatus::Success)
-  return 1; // Fatal error
-
-if (!g_vsc.HandleObject(object))
-  return 1;
+  bool CleanExit = true;
+  if (auto Err = g_vsc.Loop()) {
+if (g_vsc.log)
+  *g_vsc.log << "Transport Error: " << llvm::toString(std::move(Err))
+ << "\n";
+CleanExit = false;
   }
 
-  return EXIT_SUCCESS;
+  return CleanExit ? EXIT_SUCCESS : EXIT_FAILURE;
 }
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -11,8 +11,10 @@
 
 #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -121,6 +123,11 @@
   void Clear();
 };
 
+struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface {
+  bool DoExecute(lldb::SBDebugger debugger, char **command,
+ lldb::SBCommandReturnObject ) override;
+};
+
 struct VSCode {
   std::string debug_adaptor_path;
   InputStream input;
@@ -146,7 +153,7 @@
   // arguments if we get a RestartRequest.
   std::optional last_launch_or_attach_request;
   lldb::tid_t focus_tid;
-  bool sent_terminated_event;
+  std::atomic sent_terminated_event;
   bool stop_at_entry;
   bool is_attach;
   // The process event thread normally responds to process exited events by
@@ -154,13 +161,20 @@
   // the old 

[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.

2023-06-21 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti updated this revision to Diff 533349.
ashgti added a comment.
ashgti published this revision for review.
ashgti added reviewers: wallace, ivanhernandez13.
ashgti added a project: LLDB.
Herald added subscribers: lldb-commits, JDevlieghere.

Corrected a makefile reference.


Adds support for a reverse DAP request to startDebugging. The new request can 
be used to launch child processes from lldb scripts, for example it would be 
start forward to configure a debug configuration for a server and a client 
allowing you to launch both processes with a single debug configuraiton.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153447

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/startDebugging/Makefile
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/test/API/tools/lldb-vscode/startDebugging/main.c
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1471,6 +1471,13 @@
 
   g_vsc.debugger =
   lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  auto cmd = g_vsc.debugger.GetCommandInterpreter().AddMultiwordCommand(
+  "dap", nullptr);
+  cmd.AddCommand(
+  "startDebugging", _vsc.start_debugging_request_handler,
+  "Sends a startDebugging from the debug adapter to the client to start "
+  "child debug session of the same type as the caller.");
+
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1564,7 +1571,8 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
-llvm::Error request_runInTerminal(const llvm::json::Object _request) {
+llvm::Error request_runInTerminal(const llvm::json::Object _request,
+  const uint64_t timeout_seconds) {
   g_vsc.is_attach = true;
   lldb::SBAttachInfo attach_info;
 
@@ -1582,10 +1590,10 @@
 #endif
   llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
   launch_request, g_vsc.debug_adaptor_path, comm_file.m_path, debugger_pid);
-  llvm::json::Object reverse_response;
-  lldb_vscode::PacketStatus status =
-  g_vsc.SendReverseRequest(reverse_request, reverse_response);
-  if (status != lldb_vscode::PacketStatus::Success)
+  auto sent =
+  g_vsc.SendReverseRequest("runInTerminal", std::move(reverse_request));
+  if (std::future_status::ready !=
+  sent.wait_for(std::chrono::seconds(timeout_seconds)))
 return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Process cannot be launched by the IDE. %s",
comm_channel.GetLauncherError().c_str());
@@ -1676,7 +1684,7 @@
   const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
 
   if (GetBoolean(arguments, "runInTerminal", false)) {
-if (llvm::Error err = request_runInTerminal(request))
+if (llvm::Error err = request_runInTerminal(request, timeout_seconds))
   error.SetErrorString(llvm::toString(std::move(err)).c_str());
   } else if (launchCommands.empty()) {
 // Disable async events so the launch will be successful when we return from
@@ -3464,17 +3472,13 @@
 g_vsc.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false);
   }
 
-  while (!g_vsc.sent_terminated_event) {
-llvm::json::Object object;
-lldb_vscode::PacketStatus status = g_vsc.GetNextObject(object);
-if (status == lldb_vscode::PacketStatus::EndOfFile)
-  break;
-if (status != lldb_vscode::PacketStatus::Success)
-  return 1; // Fatal error
-
-if (!g_vsc.HandleObject(object))
-  return 1;
+  bool CleanExit = true;
+  if (auto Err = g_vsc.Loop()) {
+if (g_vsc.log)
+  *g_vsc.log << "Transport Error: " << llvm::toString(std::move(Err))
+ << "\n";
+CleanExit = false;
   }
 
-  return EXIT_SUCCESS;
+  return CleanExit ? EXIT_SUCCESS : EXIT_FAILURE;
 }
Index: lldb/tools/lldb-vscode/VSCode.h
===
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -11,8 +11,10 @@
 
 #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -121,6 +123,11 @@
   void Clear();
 };
 
+struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface {
+  bool DoExecute(lldb::SBDebugger debugger, char **command,
+ lldb::SBCommandReturnObject ) override;
+};
+
 struct VSCode {
   std::string debug_adaptor_path;
   InputStream