[Lldb-commits] [lldb] [LLDB]Provide clearer error message for invalid commands. (PR #111891)

2024-10-12 Thread Vy Nguyen via lldb-commits

https://github.com/oontvoo updated 
https://github.com/llvm/llvm-project/pull/111891

>From 4493bf07c8b18dac39a2a421f97fa34cd15a6031 Mon Sep 17 00:00:00 2001
From: Vy Nguyen 
Date: Thu, 10 Oct 2024 14:48:08 -0400
Subject: [PATCH 1/3] [LLDB]Provide clearer error message for invalid commands.

Sometimes users (esp. gdb-longtime users) accidentally use GDB syntax, such as 
`breakpoint foo`, and they would get an error message from LLDB saying simply 
`Invalid command "breakpoint foo"`, which is not very helpful.
This change provides additional suggestions to help correcting the mistake.
---
 .../lldb/Interpreter/CommandObjectMultiword.h |  2 +
 .../Commands/CommandObjectMultiword.cpp   | 42 ++-
 .../Commands/command-breakpoint-col.test  |  2 +
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h 
b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
index bceb7f0e51edb6..cee118c3f454b5 100644
--- a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
+++ b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
@@ -70,6 +70,8 @@ class CommandObjectMultiword : public CommandObject {
 return m_subcommand_dict;
   }
 
+  std::string GetTopSubcommands(int count);
+
   CommandObject::CommandMap m_subcommand_dict;
   bool m_can_be_removed;
 };
diff --git a/lldb/source/Commands/CommandObjectMultiword.cpp 
b/lldb/source/Commands/CommandObjectMultiword.cpp
index 4efa5652a71703..f7bb58187895b4 100644
--- a/lldb/source/Commands/CommandObjectMultiword.cpp
+++ b/lldb/source/Commands/CommandObjectMultiword.cpp
@@ -194,28 +194,50 @@ void CommandObjectMultiword::Execute(const char 
*args_string,
 
   std::string error_msg;
   const size_t num_subcmd_matches = matches.GetSize();
-  if (num_subcmd_matches > 0)
+  if (num_subcmd_matches > 0) {
 error_msg.assign("ambiguous command ");
-  else
-error_msg.assign("invalid command ");
-
-  error_msg.append("'");
-  error_msg.append(std::string(GetCommandName()));
-  error_msg.append(" ");
-  error_msg.append(std::string(sub_command));
-  error_msg.append("'.");
+error_msg.append("'");
+error_msg.append(std::string(GetCommandName()));
+error_msg.append(" ");
+error_msg.append(std::string(sub_command));
+error_msg.append("'.");
 
-  if (num_subcmd_matches > 0) {
 error_msg.append(" Possible completions:");
 for (const std::string &match : matches) {
   error_msg.append("\n\t");
   error_msg.append(match);
 }
+  } else {
+// Rather than simply complaining about the invalid (sub) command,
+// try to offer some alternatives.
+// This is especially useful for cases where the user types something
+// seamingly trivial, such as `breakpoint foo`.
+error_msg.assign(
+llvm::Twine("'" + sub_command + "' is not a valid subcommand of \"" +
+GetCommandName() + "\". Valid subcommands are " +
+GetTopSubcommands(/*count=*/5) + ". Use \"help " +
+GetCommandName() + "\" to find out more.")
+.str());
   }
   error_msg.append("\n");
   result.AppendRawError(error_msg.c_str());
 }
 
+std::string CommandObjectMultiword::GetTopSubcommands(int count) {
+  if (m_subcommand_dict.empty())
+return "";
+  std::string buffer = "{";
+  CommandMap::iterator pos;
+  for (pos = m_subcommand_dict.begin();
+   pos != m_subcommand_dict.end() && count > 0; ++pos, --count) {
+buffer.append("'");
+buffer.append(pos->first);
+buffer.append("',");
+  }
+  buffer.append("...}");
+  return buffer;
+}
+
 void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
   // First time through here, generate the help text for the object and push it
   // to the return result object as well
diff --git a/lldb/test/Shell/Commands/command-breakpoint-col.test 
b/lldb/test/Shell/Commands/command-breakpoint-col.test
index 65c1e220794303..fecb773d2b4c66 100644
--- a/lldb/test/Shell/Commands/command-breakpoint-col.test
+++ b/lldb/test/Shell/Commands/command-breakpoint-col.test
@@ -3,8 +3,10 @@
 # RUN: %clang_host -g -O0 %S/Inputs/main.c -o %t.out
 # RUN: %lldb -b -o 'help breakpoint set' -o 'breakpoint set -f main.c -l 2 -u 
21' %t.out | FileCheck %s --check-prefix HELP --check-prefix CHECK
 # RUN: %lldb -b -o 'help _regexp-break' -o 'b main.c:2:21' %t.out | FileCheck 
%s --check-prefix HELP-REGEX --check-prefix CHECK
+# RUN: not %lldb -b -o 'breakpoint foo' %t.out -o exit 2>&1 | FileCheck %s 
--check-prefix ERROR-MSG
 # HELP: -u  ( --column  )
 # HELP: Specifies the column number on which to set this breakpoint.
 # HELP-REGEX: _regexp-break ::
 # HELP-REGEX: main.c:12:21{{.*}}Break at line 12 and column 21 of main.c
 # CHECK: at main.c:2:21
+# ERROR-MSG: 'foo' is not a valid subcommand of "breakpoint". Valid 
subcommands are {'clear','command','delete','disable','enable',...}. Use "help 
breakpoint" to find out more.

>From 8dfb266f7eed943f7d9c4bd00e09ef86ae1c5d6e Mon

[Lldb-commits] [lldb] [LLDB]Provide clearer error message for invalid commands. (PR #111891)

2024-10-12 Thread Vy Nguyen via lldb-commits


@@ -3,8 +3,10 @@
 # RUN: %clang_host -g -O0 %S/Inputs/main.c -o %t.out
 # RUN: %lldb -b -o 'help breakpoint set' -o 'breakpoint set -f main.c -l 2 -u 
21' %t.out | FileCheck %s --check-prefix HELP --check-prefix CHECK
 # RUN: %lldb -b -o 'help _regexp-break' -o 'b main.c:2:21' %t.out | FileCheck 
%s --check-prefix HELP-REGEX --check-prefix CHECK
+# RUN: not %lldb -b -o 'breakpoint foo' %t.out -o exit 2>&1 | FileCheck %s 
--check-prefix ERROR-MSG

oontvoo wrote:

done

https://github.com/llvm/llvm-project/pull/111891
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Escape ? for zsh (PR #112107)

2024-10-12 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere approved this pull request.


https://github.com/llvm/llvm-project/pull/112107
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Expose structured command diagnostics via the SBAPI. (PR #112109)

2024-10-12 Thread Jonas Devlieghere via lldb-commits


@@ -9,6 +9,7 @@
 #ifndef LLDB_API_SBSTRUCTUREDDATA_H
 #define LLDB_API_SBSTRUCTUREDDATA_H
 
+#include "SBCommandReturnObject.h"

JDevlieghere wrote:

```suggestion
#include "lldb/API/SBCommandReturnObject.h"
```

https://github.com/llvm/llvm-project/pull/112109
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Expose structured command diagnostics via the SBAPI. (PR #112109)

2024-10-12 Thread Jonas Devlieghere via lldb-commits


@@ -45,13 +45,14 @@ class LLDB_API SBCommandReturnObject {
   const char *GetOutput();
 
   const char *GetError();
+  SBStructuredData GetErrorData();
 
 #ifndef SWIG
   LLDB_DEPRECATED_FIXME("Use PutOutput(SBFile) or PutOutput(FileSP)",
 "PutOutput(SBFile)")
   size_t PutOutput(FILE *fh);
 #endif
-
+\

JDevlieghere wrote:

?

https://github.com/llvm/llvm-project/pull/112109
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Expose structured command diagnostics via the SBAPI. (PR #112109)

2024-10-12 Thread Jonas Devlieghere via lldb-commits


@@ -123,30 +123,80 @@ void CommandReturnObject::SetError(llvm::Error error) {
   }
 }
 
-llvm::StringRef
+std::string
 CommandReturnObject::GetInlineDiagnosticString(unsigned indent) {
-  RenderDiagnosticDetails(m_diag_stream, indent, true, m_diagnostics);
+  StreamString diag_stream(m_colors);
+  RenderDiagnosticDetails(diag_stream, indent, true, m_diagnostics);
   // Duplex the diagnostics to the secondary stream (but not inlined).
-  if (auto stream_sp = m_err_stream.GetStreamAtIndex(eStreamStringIndex))
+  if (auto stream_sp = m_err_stream.GetStreamAtIndex(eImmediateStreamIndex))
 RenderDiagnosticDetails(*stream_sp, std::nullopt, false, m_diagnostics);
 
-  // Clear them so GetErrorData() doesn't render them again.
-  m_diagnostics.clear();
-  return m_diag_stream.GetString();
+  return diag_stream.GetString().str();
 }
 
-llvm::StringRef CommandReturnObject::GetErrorString() {
-  // Diagnostics haven't been fetched; render them now (not inlined).
-  if (!m_diagnostics.empty()) {
-RenderDiagnosticDetails(GetErrorStream(), std::nullopt, false,
-m_diagnostics);
-m_diagnostics.clear();
-  }
+std::string CommandReturnObject::GetErrorString(bool with_diagnostics) {
+  StreamString stream(m_colors);
+  if (with_diagnostics)
+RenderDiagnosticDetails(stream, std::nullopt, false, m_diagnostics);
 
   lldb::StreamSP stream_sp(m_err_stream.GetStreamAtIndex(eStreamStringIndex));
   if (stream_sp)
-return std::static_pointer_cast(stream_sp)->GetString();
-  return llvm::StringRef();
+stream << std::static_pointer_cast(stream_sp)->GetString();
+  return stream.GetString().str();
+}
+
+StructuredData::ObjectSP CommandReturnObject::GetErrorData() {
+  auto make_array = []() { return std::make_unique(); };
+  auto make_bool = [](bool b) {
+return std::make_unique(b);
+  };
+  auto make_dict = []() {
+return std::make_unique();
+  };
+  auto make_int = [](unsigned i) {
+return std::make_unique(i);

JDevlieghere wrote:

Should this be `StructuredData::UnsignedInteger` or 
`StructuredData::SignedInteger`?

https://github.com/llvm/llvm-project/pull/112109
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Expose structured command diagnostics via the SBAPI. (PR #112109)

2024-10-12 Thread via lldb-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff c2750807ba2a419425ee90dadda09ad5121517fe 
cf7ea7aa4d458ad82c39afb2b0879ec32a88a2db --extensions h,cpp -- 
lldb/include/lldb/API/SBCommandReturnObject.h 
lldb/include/lldb/API/SBStructuredData.h 
lldb/include/lldb/Interpreter/CommandReturnObject.h 
lldb/source/API/SBCommandReturnObject.cpp 
lldb/source/Commands/CommandObjectExpression.cpp 
lldb/source/Interpreter/CommandInterpreter.cpp 
lldb/source/Interpreter/CommandReturnObject.cpp
``





View the diff from clang-format here.


``diff
diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h 
b/lldb/include/lldb/API/SBCommandReturnObject.h
index f0a4738cc3..e8e20a3f30 100644
--- a/lldb/include/lldb/API/SBCommandReturnObject.h
+++ b/lldb/include/lldb/API/SBCommandReturnObject.h
@@ -52,7 +52,7 @@ public:
 "PutOutput(SBFile)")
   size_t PutOutput(FILE *fh);
 #endif
-\
+
   size_t PutOutput(SBFile file);
 
   size_t PutOutput(FileSP BORROWED);
diff --git a/lldb/source/Interpreter/CommandReturnObject.cpp 
b/lldb/source/Interpreter/CommandReturnObject.cpp
index 8cd798f62f..6855c6fcb6 100644
--- a/lldb/source/Interpreter/CommandReturnObject.cpp
+++ b/lldb/source/Interpreter/CommandReturnObject.cpp
@@ -123,8 +123,7 @@ void CommandReturnObject::SetError(llvm::Error error) {
   }
 }
 
-std::string
-CommandReturnObject::GetInlineDiagnosticString(unsigned indent) {
+std::string CommandReturnObject::GetInlineDiagnosticString(unsigned indent) {
   StreamString diag_stream(m_colors);
   RenderDiagnosticDetails(diag_stream, indent, true, m_diagnostics);
   // Duplex the diagnostics to the secondary stream (but not inlined).

``




https://github.com/llvm/llvm-project/pull/112109
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Expose structured command diagnostics via the SBAPI. (PR #112109)

2024-10-12 Thread via lldb-commits

github-actions[bot] wrote:




:warning: Python code formatter, darker found issues in your code. :warning:



You can test this locally with the following command:


``bash
darker --check --diff -r 
c2750807ba2a419425ee90dadda09ad5121517fe...cf7ea7aa4d458ad82c39afb2b0879ec32a88a2db
 lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py
``





View the diff from darker here.


``diff
--- TestExprDiagnostics.py  2024-10-12 20:37:19.00 +
+++ TestExprDiagnostics.py  2024-10-12 20:41:04.212598 +
@@ -256,6 +256,5 @@
 self.assertIn("user expression", str(sloc.GetValueForKey("file")))
 self.assertFalse(sloc.GetValueForKey("hidden").GetBooleanValue())
 self.assertTrue(sloc.GetValueForKey("in_user_input").GetBooleanValue())
 diag = details.GetItemAtIndex(1)
 self.assertIn("undeclared identifier 'b'", 
str(diag.GetValueForKey("message")))
-

``




https://github.com/llvm/llvm-project/pull/112109
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add early CMake check for 'make' tool (PR #111531)

2024-10-12 Thread Stefan Gränitz via lldb-commits

weliveindetail wrote:

In fact, I ran into that on Friday myself. I checked `LLDB_INCLUDE_TESTS=Off` 
in my setup and it appeared to be incompatible with `LLDB_ENABLE_PYTHON=On` if 
`lldb-python` is part of `LLVM_DISTRIBUTION_COMPONENTS`. The error said 
something like `lldb-python-scripts` is lacking an `install-stripped` target. I 
couldn't fix that quickly and just wired up the `LLDB_TEST_MAKE` config.

@zeroomega Any similar experiences with `LLDB_INCLUDE_TESTS=Off`?

https://github.com/llvm/llvm-project/pull/111531
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] c275080 - [lldb] Rename CommandReturnObject::Get.*Data -> Get.*String (#112062)

2024-10-12 Thread via lldb-commits

Author: Adrian Prantl
Date: 2024-10-12T13:36:33-07:00
New Revision: c2750807ba2a419425ee90dadda09ad5121517fe

URL: 
https://github.com/llvm/llvm-project/commit/c2750807ba2a419425ee90dadda09ad5121517fe
DIFF: 
https://github.com/llvm/llvm-project/commit/c2750807ba2a419425ee90dadda09ad5121517fe.diff

LOG: [lldb] Rename CommandReturnObject::Get.*Data -> Get.*String (#112062)

In a later commit, I want to add a method to access diagnostics as
actual structured data, which will make these function names rather
confusing.

Added: 


Modified: 
lldb/include/lldb/Interpreter/CommandReturnObject.h
lldb/source/API/SBCommandReturnObject.cpp
lldb/source/Commands/CommandObjectCommands.cpp
lldb/source/Core/Debugger.cpp
lldb/source/Interpreter/CommandInterpreter.cpp
lldb/source/Interpreter/CommandReturnObject.cpp
lldb/tools/lldb-test/lldb-test.cpp

Removed: 




diff  --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h 
b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index e13c3b7b8e0437..eda841869ba432 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -30,16 +30,17 @@ class CommandReturnObject {
 
   ~CommandReturnObject() = default;
 
-  llvm::StringRef GetInlineDiagnosticsData(unsigned indent);
+  /// Format any inline diagnostics with an indentation of \c indent.
+  llvm::StringRef GetInlineDiagnosticString(unsigned indent);
 
-  llvm::StringRef GetOutputData() {
+  llvm::StringRef GetOutputString() {
 lldb::StreamSP 
stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex));
 if (stream_sp)
   return std::static_pointer_cast(stream_sp)->GetString();
 return llvm::StringRef();
   }
 
-  llvm::StringRef GetErrorData();
+  llvm::StringRef GetErrorString();
 
   Stream &GetOutputStream() {
 // Make sure we at least have our normal string stream output stream

diff  --git a/lldb/source/API/SBCommandReturnObject.cpp 
b/lldb/source/API/SBCommandReturnObject.cpp
index d0cdebe8c64911..a94eff75ffcb9e 100644
--- a/lldb/source/API/SBCommandReturnObject.cpp
+++ b/lldb/source/API/SBCommandReturnObject.cpp
@@ -85,27 +85,27 @@ SBCommandReturnObject::operator bool() const {
 const char *SBCommandReturnObject::GetOutput() {
   LLDB_INSTRUMENT_VA(this);
 
-  ConstString output(ref().GetOutputData());
+  ConstString output(ref().GetOutputString());
   return output.AsCString(/*value_if_empty*/ "");
 }
 
 const char *SBCommandReturnObject::GetError() {
   LLDB_INSTRUMENT_VA(this);
 
-  ConstString output(ref().GetErrorData());
+  ConstString output(ref().GetErrorString());
   return output.AsCString(/*value_if_empty*/ "");
 }
 
 size_t SBCommandReturnObject::GetOutputSize() {
   LLDB_INSTRUMENT_VA(this);
 
-  return ref().GetOutputData().size();
+  return ref().GetOutputString().size();
 }
 
 size_t SBCommandReturnObject::GetErrorSize() {
   LLDB_INSTRUMENT_VA(this);
 
-  return ref().GetErrorData().size();
+  return ref().GetErrorString().size();
 }
 
 size_t SBCommandReturnObject::PutOutput(FILE *fh) {

diff  --git a/lldb/source/Commands/CommandObjectCommands.cpp 
b/lldb/source/Commands/CommandObjectCommands.cpp
index 845b89a75b7b39..f069b2feb5cb7b 100644
--- a/lldb/source/Commands/CommandObjectCommands.cpp
+++ b/lldb/source/Commands/CommandObjectCommands.cpp
@@ -1099,7 +1099,7 @@ class CommandObjectPythonFunction : public 
CommandObjectRaw {
 } else {
   // Don't change the status if the command already set it...
   if (result.GetStatus() == eReturnStatusInvalid) {
-if (result.GetOutputData().empty())
+if (result.GetOutputString().empty())
   result.SetStatus(eReturnStatusSuccessFinishNoResult);
 else
   result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -1205,7 +1205,7 @@ class CommandObjectScriptingObjectRaw : public 
CommandObjectRaw {
 } else {
   // Don't change the status if the command already set it...
   if (result.GetStatus() == eReturnStatusInvalid) {
-if (result.GetOutputData().empty())
+if (result.GetOutputString().empty())
   result.SetStatus(eReturnStatusSuccessFinishNoResult);
 else
   result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -2137,7 +2137,7 @@ class CommandObjectScriptingObjectParsed : public 
CommandObjectParsed {
 } else {
   // Don't change the status if the command already set it...
   if (result.GetStatus() == eReturnStatusInvalid) {
-if (result.GetOutputData().empty())
+if (result.GetOutputString().empty())
   result.SetStatus(eReturnStatusSuccessFinishNoResult);
 else
   result.SetStatus(eReturnStatusSuccessFinishResult);

diff  --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index e6b9eedd89b4e3..c666a753343c9d 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ 

[Lldb-commits] [lldb] [lldb] Rename CommandReturnObject::Get.*Data -> Get.*String (PR #112062)

2024-10-12 Thread Adrian Prantl via lldb-commits

https://github.com/adrian-prantl closed 
https://github.com/llvm/llvm-project/pull/112062
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Expose structured command diagnostics via the SBAPI. (PR #112109)

2024-10-12 Thread Adrian Prantl via lldb-commits

https://github.com/adrian-prantl created 
https://github.com/llvm/llvm-project/pull/112109

This allows IDEs to render LLDB expression diagnostics to their liking without 
relying on characterprecise ASCII art from LLDB. It is exposed as a versioned 
SBStructuredData object, since it is expected that this may need to be tweaked 
based on actual usage.

>From cf7ea7aa4d458ad82c39afb2b0879ec32a88a2db Mon Sep 17 00:00:00 2001
From: Adrian Prantl 
Date: Fri, 11 Oct 2024 19:27:37 -0700
Subject: [PATCH] [lldb] Expose structured command diagnostics via the SBAPI.

This allows IDEs to render LLDB expression diagnostics to their liking
without relying on characterprecise ASCII art from LLDB. It is exposed
as a versioned SBStructuredData object, since it is expected that this
may need to be tweaked based on actual usage.
---
 lldb/include/lldb/API/SBCommandReturnObject.h |  3 +-
 lldb/include/lldb/API/SBStructuredData.h  |  2 +
 .../lldb/Interpreter/CommandReturnObject.h| 13 ++-
 lldb/source/API/SBCommandReturnObject.cpp | 11 +++
 .../Commands/CommandObjectExpression.cpp  | 29 +--
 .../source/Interpreter/CommandInterpreter.cpp | 23 +++---
 .../Interpreter/CommandReturnObject.cpp   | 82 +++
 .../diagnostics/TestExprDiagnostics.py| 25 ++
 8 files changed, 128 insertions(+), 60 deletions(-)

diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h 
b/lldb/include/lldb/API/SBCommandReturnObject.h
index f96384a4710b16..f0a4738cc346e4 100644
--- a/lldb/include/lldb/API/SBCommandReturnObject.h
+++ b/lldb/include/lldb/API/SBCommandReturnObject.h
@@ -45,13 +45,14 @@ class LLDB_API SBCommandReturnObject {
   const char *GetOutput();
 
   const char *GetError();
+  SBStructuredData GetErrorData();
 
 #ifndef SWIG
   LLDB_DEPRECATED_FIXME("Use PutOutput(SBFile) or PutOutput(FileSP)",
 "PutOutput(SBFile)")
   size_t PutOutput(FILE *fh);
 #endif
-
+\
   size_t PutOutput(SBFile file);
 
   size_t PutOutput(FileSP BORROWED);
diff --git a/lldb/include/lldb/API/SBStructuredData.h 
b/lldb/include/lldb/API/SBStructuredData.h
index fc6e1ec95c7b86..c309e28a190691 100644
--- a/lldb/include/lldb/API/SBStructuredData.h
+++ b/lldb/include/lldb/API/SBStructuredData.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_API_SBSTRUCTUREDDATA_H
 #define LLDB_API_SBSTRUCTUREDDATA_H
 
+#include "SBCommandReturnObject.h"
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBModule.h"
 #include "lldb/API/SBScriptObject.h"
@@ -110,6 +111,7 @@ class SBStructuredData {
 
 protected:
   friend class SBAttachInfo;
+  friend class SBCommandReturnObject;
   friend class SBLaunchInfo;
   friend class SBDebugger;
   friend class SBTarget;
diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h 
b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index eda841869ba432..a491a6c1535b11 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -13,6 +13,7 @@
 #include "lldb/Utility/DiagnosticsRendering.h"
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/StreamTee.h"
+#include "lldb/Utility/StructuredData.h"
 #include "lldb/lldb-private.h"
 
 #include "llvm/ADT/StringRef.h"
@@ -31,7 +32,7 @@ class CommandReturnObject {
   ~CommandReturnObject() = default;
 
   /// Format any inline diagnostics with an indentation of \c indent.
-  llvm::StringRef GetInlineDiagnosticString(unsigned indent);
+  std::string GetInlineDiagnosticString(unsigned indent);
 
   llvm::StringRef GetOutputString() {
 lldb::StreamSP 
stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex));
@@ -40,7 +41,13 @@ class CommandReturnObject {
 return llvm::StringRef();
   }
 
-  llvm::StringRef GetErrorString();
+  /// Return the errors as a string.
+  ///
+  /// If \c with_diagnostics is true, all diagnostics are also
+  /// rendered into the string. Otherwise the expectation is that they
+  /// are fetched with \ref GetInlineDiagnosticString().
+  std::string GetErrorString(bool with_diagnostics = true);
+  StructuredData::ObjectSP GetErrorData();
 
   Stream &GetOutputStream() {
 // Make sure we at least have our normal string stream output stream
@@ -168,7 +175,6 @@ class CommandReturnObject {
   StreamTee m_out_stream;
   StreamTee m_err_stream;
   std::vector m_diagnostics;
-  StreamString m_diag_stream;
   std::optional m_diagnostic_indent;
 
   lldb::ReturnStatus m_status = lldb::eReturnStatusStarted;
@@ -178,6 +184,7 @@ class CommandReturnObject {
 
   /// If true, then the input handle from the debugger will be hooked up.
   bool m_interactive = true;
+  bool m_colors;
 };
 
 } // namespace lldb_private
diff --git a/lldb/source/API/SBCommandReturnObject.cpp 
b/lldb/source/API/SBCommandReturnObject.cpp
index a94eff75ffcb9e..9df8aa48b99366 100644
--- a/lldb/source/API/SBCommandReturnObject.cpp
+++ b/lldb/source/API/SBCommandReturnObject.cpp
@@ -11,6 +11,8 @@
 #include "lldb/API/SBError.h"
 #include "lldb/API/SBFile.h"
 #include 

[Lldb-commits] [lldb] [lldb] Expose structured command diagnostics via the SBAPI. (PR #112109)

2024-10-12 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Adrian Prantl (adrian-prantl)


Changes

This allows IDEs to render LLDB expression diagnostics to their liking without 
relying on characterprecise ASCII art from LLDB. It is exposed as a versioned 
SBStructuredData object, since it is expected that this may need to be tweaked 
based on actual usage.

---
Full diff: https://github.com/llvm/llvm-project/pull/112109.diff


8 Files Affected:

- (modified) lldb/include/lldb/API/SBCommandReturnObject.h (+2-1) 
- (modified) lldb/include/lldb/API/SBStructuredData.h (+2) 
- (modified) lldb/include/lldb/Interpreter/CommandReturnObject.h (+10-3) 
- (modified) lldb/source/API/SBCommandReturnObject.cpp (+11) 
- (modified) lldb/source/Commands/CommandObjectExpression.cpp (+1-28) 
- (modified) lldb/source/Interpreter/CommandInterpreter.cpp (+11-12) 
- (modified) lldb/source/Interpreter/CommandReturnObject.cpp (+66-16) 
- (modified) 
lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py (+25) 


``diff
diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h 
b/lldb/include/lldb/API/SBCommandReturnObject.h
index f96384a4710b16..f0a4738cc346e4 100644
--- a/lldb/include/lldb/API/SBCommandReturnObject.h
+++ b/lldb/include/lldb/API/SBCommandReturnObject.h
@@ -45,13 +45,14 @@ class LLDB_API SBCommandReturnObject {
   const char *GetOutput();
 
   const char *GetError();
+  SBStructuredData GetErrorData();
 
 #ifndef SWIG
   LLDB_DEPRECATED_FIXME("Use PutOutput(SBFile) or PutOutput(FileSP)",
 "PutOutput(SBFile)")
   size_t PutOutput(FILE *fh);
 #endif
-
+\
   size_t PutOutput(SBFile file);
 
   size_t PutOutput(FileSP BORROWED);
diff --git a/lldb/include/lldb/API/SBStructuredData.h 
b/lldb/include/lldb/API/SBStructuredData.h
index fc6e1ec95c7b86..c309e28a190691 100644
--- a/lldb/include/lldb/API/SBStructuredData.h
+++ b/lldb/include/lldb/API/SBStructuredData.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_API_SBSTRUCTUREDDATA_H
 #define LLDB_API_SBSTRUCTUREDDATA_H
 
+#include "SBCommandReturnObject.h"
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBModule.h"
 #include "lldb/API/SBScriptObject.h"
@@ -110,6 +111,7 @@ class SBStructuredData {
 
 protected:
   friend class SBAttachInfo;
+  friend class SBCommandReturnObject;
   friend class SBLaunchInfo;
   friend class SBDebugger;
   friend class SBTarget;
diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h 
b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index eda841869ba432..a491a6c1535b11 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -13,6 +13,7 @@
 #include "lldb/Utility/DiagnosticsRendering.h"
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/StreamTee.h"
+#include "lldb/Utility/StructuredData.h"
 #include "lldb/lldb-private.h"
 
 #include "llvm/ADT/StringRef.h"
@@ -31,7 +32,7 @@ class CommandReturnObject {
   ~CommandReturnObject() = default;
 
   /// Format any inline diagnostics with an indentation of \c indent.
-  llvm::StringRef GetInlineDiagnosticString(unsigned indent);
+  std::string GetInlineDiagnosticString(unsigned indent);
 
   llvm::StringRef GetOutputString() {
 lldb::StreamSP 
stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex));
@@ -40,7 +41,13 @@ class CommandReturnObject {
 return llvm::StringRef();
   }
 
-  llvm::StringRef GetErrorString();
+  /// Return the errors as a string.
+  ///
+  /// If \c with_diagnostics is true, all diagnostics are also
+  /// rendered into the string. Otherwise the expectation is that they
+  /// are fetched with \ref GetInlineDiagnosticString().
+  std::string GetErrorString(bool with_diagnostics = true);
+  StructuredData::ObjectSP GetErrorData();
 
   Stream &GetOutputStream() {
 // Make sure we at least have our normal string stream output stream
@@ -168,7 +175,6 @@ class CommandReturnObject {
   StreamTee m_out_stream;
   StreamTee m_err_stream;
   std::vector m_diagnostics;
-  StreamString m_diag_stream;
   std::optional m_diagnostic_indent;
 
   lldb::ReturnStatus m_status = lldb::eReturnStatusStarted;
@@ -178,6 +184,7 @@ class CommandReturnObject {
 
   /// If true, then the input handle from the debugger will be hooked up.
   bool m_interactive = true;
+  bool m_colors;
 };
 
 } // namespace lldb_private
diff --git a/lldb/source/API/SBCommandReturnObject.cpp 
b/lldb/source/API/SBCommandReturnObject.cpp
index a94eff75ffcb9e..9df8aa48b99366 100644
--- a/lldb/source/API/SBCommandReturnObject.cpp
+++ b/lldb/source/API/SBCommandReturnObject.cpp
@@ -11,6 +11,8 @@
 #include "lldb/API/SBError.h"
 #include "lldb/API/SBFile.h"
 #include "lldb/API/SBStream.h"
+#include "lldb/API/SBStructuredData.h"
+#include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/Instrumentation.h"
@@ -96,6 +98,15 @@ const char *SBCommandReturnObject::GetError() {
   return output.

[Lldb-commits] [lldb] [lldb] Speed up FindInMemory tests (PR #111951)

2024-10-12 Thread Igor Kudrin via lldb-commits

https://github.com/igorkudrin updated 
https://github.com/llvm/llvm-project/pull/111951

>From e027444340be4020002126da0d2c8a705c2c7e3f Mon Sep 17 00:00:00 2001
From: Igor Kudrin 
Date: Thu, 10 Oct 2024 20:27:10 -0700
Subject: [PATCH 1/2] [lldb] Speed up FindInMemory tests

A memory region can be relatively large. Searching for a value in the
entire region is time-consuming, especially when running tests against
a remote target, because the memory data is transferred in small chunks
over a relatively slow GDB Remote Protocol. The patch limits the address
range to be searched to 2K, which seems sufficient for these tests. In
my setup, for local runs, these tests now take half the time they did
before the patch. For a remote target, the improvement is even more
significant.
---
 .../find_in_memory/TestFindInMemory.py| 10 ++--
 .../find_in_memory/TestFindRangesInMemory.py  | 16 +++---
 .../find_in_memory/address_ranges_helper.py   | 50 ---
 3 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py 
b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
index 9ab4619b1f8f4f..04e807c5c6201d 100644
--- a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
+++ b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
@@ -55,7 +55,7 @@ def test_find_in_memory_ok(self):
 error = lldb.SBError()
 addr = self.process.FindInMemory(
 SINGLE_INSTANCE_PATTERN_STACK,
-GetStackRange(self),
+GetStackRange(self, True),
 1,
 error,
 )
@@ -70,7 +70,7 @@ def test_find_in_memory_double_instance_ok(self):
 error = lldb.SBError()
 addr = self.process.FindInMemory(
 DOUBLE_INSTANCE_PATTERN_HEAP,
-GetHeapRanges(self)[0],
+GetHeapRanges(self, True)[0],
 1,
 error,
 )
@@ -86,7 +86,7 @@ def test_find_in_memory_invalid_alignment(self):
 error = lldb.SBError()
 addr = self.process.FindInMemory(
 SINGLE_INSTANCE_PATTERN_STACK,
-GetStackRange(self),
+GetStackRange(self, True),
 0,
 error,
 )
@@ -118,7 +118,7 @@ def test_find_in_memory_invalid_buffer(self):
 error = lldb.SBError()
 addr = self.process.FindInMemory(
 "",
-GetStackRange(self),
+GetStackRange(self, True),
 1,
 error,
 )
@@ -131,7 +131,7 @@ def test_find_in_memory_unaligned(self):
 self.assertTrue(self.process, PROCESS_IS_VALID)
 self.assertState(self.process.GetState(), lldb.eStateStopped, 
PROCESS_STOPPED)
 error = lldb.SBError()
-range = GetAlignedRange(self)
+range = GetAlignedRange(self, True)
 
 # First we make sure the pattern is found with alignment 1
 addr = self.process.FindInMemory(
diff --git a/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py 
b/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py
index 31bc0e99f4914f..895c527430f218 100644
--- a/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py
+++ b/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py
@@ -30,7 +30,7 @@ def test_find_ranges_in_memory_two_matches(self):
 self.assertTrue(self.process, PROCESS_IS_VALID)
 self.assertState(self.process.GetState(), lldb.eStateStopped, 
PROCESS_STOPPED)
 
-addr_ranges = GetHeapRanges(self)
+addr_ranges = GetHeapRanges(self, True)
 error = lldb.SBError()
 matches = self.process.FindRangesInMemory(
 DOUBLE_INSTANCE_PATTERN_HEAP,
@@ -48,7 +48,7 @@ def test_find_ranges_in_memory_one_match(self):
 self.assertTrue(self.process, PROCESS_IS_VALID)
 self.assertState(self.process.GetState(), lldb.eStateStopped, 
PROCESS_STOPPED)
 
-addr_ranges = GetStackRanges(self)
+addr_ranges = GetStackRanges(self, True)
 error = lldb.SBError()
 matches = self.process.FindRangesInMemory(
 SINGLE_INSTANCE_PATTERN_STACK,
@@ -66,7 +66,7 @@ def 
test_find_ranges_in_memory_one_match_multiple_ranges(self):
 self.assertTrue(self.process, PROCESS_IS_VALID)
 self.assertState(self.process.GetState(), lldb.eStateStopped, 
PROCESS_STOPPED)
 
-addr_ranges = GetRanges(self)
+addr_ranges = GetRanges(self, True)
 addr_ranges.Append(lldb.SBAddressRange())
 self.assertGreater(addr_ranges.GetSize(), 2)
 error = lldb.SBError()
@@ -86,7 +86,7 @@ def test_find_ranges_in_memory_one_match_max(self):
 self.assertTrue(self.process, PROCESS_IS_VALID)
 self.assertState(self.process.GetState(), lldb.eStateStopped, 
PROCESS_STOPPED)
 
-addr_ranges = GetHeapRanges(self)
+addr_ranges = GetHeapRanges(self, True)
 error = lldb.SBError()
 matches = self.proces

[Lldb-commits] [lldb] [lldb] Escape ? for zsh (PR #112107)

2024-10-12 Thread Keith Smiley via lldb-commits

https://github.com/keith created 
https://github.com/llvm/llvm-project/pull/112107

Previously on macOS with lldb-argdumper if you ran:

```
lldb -o r -- /tmp/foo "some arg?"
```

It would fail with this error:

```
error: shell expansion failed (reason: lldb-argdumper exited with error 1). 
consider launching with 'process launch'.
```

stderr is silenced here but the underlying error if you print it for
debugging is:

```
zsh: no matches found: ?
```

This change escapes the `?` so this argument works as expected.


>From 2cd6a6726373e8b499aba4e41dafad5780f2134f Mon Sep 17 00:00:00 2001
From: Keith Smiley 
Date: Sat, 12 Oct 2024 11:25:16 -0700
Subject: [PATCH] [lldb] Escape ? for zsh

Previously on macOS with lldb-argdumper if you ran:

```
lldb -o r -- /tmp/foo "some arg?"
```

It would fail with this error:

```
error: shell expansion failed (reason: lldb-argdumper exited with error 1). 
consider launching with 'process launch'.
```

stderr is silenced here but the underlying error if you print it for
debugging is:

```
zsh: no matches found: ?
```

This change escapes the `?` so this argument works as expected.
---
 lldb/source/Utility/Args.cpp| 2 +-
 lldb/unittests/Utility/ArgsTest.cpp | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lldb/source/Utility/Args.cpp b/lldb/source/Utility/Args.cpp
index 8ba40bae4d67e5..92a7ef03273fbc 100644
--- a/lldb/source/Utility/Args.cpp
+++ b/lldb/source/Utility/Args.cpp
@@ -401,7 +401,7 @@ std::string Args::GetShellSafeArgument(const FileSpec 
&shell,
   static ShellDescriptor g_Shells[] = {{"bash", " '\"<>()&;"},
{"fish", " '\"<>()&\\|;"},
{"tcsh", " '\"<>()&;"},
-   {"zsh", " '\"<>()&;\\|"},
+   {"zsh", " '\"<>()&;\\|?"},
{"sh", " '\"<>()&;"}};
 
   // safe minimal set
diff --git a/lldb/unittests/Utility/ArgsTest.cpp 
b/lldb/unittests/Utility/ArgsTest.cpp
index 8d2b625f524d67..34d6b4dd7c95a0 100644
--- a/lldb/unittests/Utility/ArgsTest.cpp
+++ b/lldb/unittests/Utility/ArgsTest.cpp
@@ -292,8 +292,8 @@ TEST(ArgsTest, GetShellSafeArgument) {
   EXPECT_EQ(Args::GetShellSafeArgument(bash, "a\"b"), "a\\\"b");
 
   FileSpec zsh("/bin/zsh", FileSpec::Style::posix);
-  EXPECT_EQ(Args::GetShellSafeArgument(zsh, R"('";()<>&|\)"),
-R"(\'\"\;\(\)\<\>\&\|\\)");
+  EXPECT_EQ(Args::GetShellSafeArgument(zsh, R"('"?;()<>&|\)"),
+R"(\'\"\?\;\(\)\<\>\&\|\\)");
   // Normal characters and expressions that shouldn't be escaped.
   EXPECT_EQ(Args::GetShellSafeArgument(zsh, "aA$1*"), "aA$1*");
 

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


[Lldb-commits] [lldb] [lldb] Escape ? for zsh (PR #112107)

2024-10-12 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Keith Smiley (keith)


Changes

Previously on macOS with lldb-argdumper if you ran:

```
lldb -o r -- /tmp/foo "some arg?"
```

It would fail with this error:

```
error: shell expansion failed (reason: lldb-argdumper exited with error 1). 
consider launching with 'process launch'.
```

stderr is silenced here but the underlying error if you print it for
debugging is:

```
zsh: no matches found: ?
```

This change escapes the `?` so this argument works as expected.


---
Full diff: https://github.com/llvm/llvm-project/pull/112107.diff


2 Files Affected:

- (modified) lldb/source/Utility/Args.cpp (+1-1) 
- (modified) lldb/unittests/Utility/ArgsTest.cpp (+2-2) 


``diff
diff --git a/lldb/source/Utility/Args.cpp b/lldb/source/Utility/Args.cpp
index 8ba40bae4d67e5..92a7ef03273fbc 100644
--- a/lldb/source/Utility/Args.cpp
+++ b/lldb/source/Utility/Args.cpp
@@ -401,7 +401,7 @@ std::string Args::GetShellSafeArgument(const FileSpec 
&shell,
   static ShellDescriptor g_Shells[] = {{"bash", " '\"<>()&;"},
{"fish", " '\"<>()&\\|;"},
{"tcsh", " '\"<>()&;"},
-   {"zsh", " '\"<>()&;\\|"},
+   {"zsh", " '\"<>()&;\\|?"},
{"sh", " '\"<>()&;"}};
 
   // safe minimal set
diff --git a/lldb/unittests/Utility/ArgsTest.cpp 
b/lldb/unittests/Utility/ArgsTest.cpp
index 8d2b625f524d67..34d6b4dd7c95a0 100644
--- a/lldb/unittests/Utility/ArgsTest.cpp
+++ b/lldb/unittests/Utility/ArgsTest.cpp
@@ -292,8 +292,8 @@ TEST(ArgsTest, GetShellSafeArgument) {
   EXPECT_EQ(Args::GetShellSafeArgument(bash, "a\"b"), "a\\\"b");
 
   FileSpec zsh("/bin/zsh", FileSpec::Style::posix);
-  EXPECT_EQ(Args::GetShellSafeArgument(zsh, R"('";()<>&|\)"),
-R"(\'\"\;\(\)\<\>\&\|\\)");
+  EXPECT_EQ(Args::GetShellSafeArgument(zsh, R"('"?;()<>&|\)"),
+R"(\'\"\?\;\(\)\<\>\&\|\\)");
   // Normal characters and expressions that shouldn't be escaped.
   EXPECT_EQ(Args::GetShellSafeArgument(zsh, "aA$1*"), "aA$1*");
 

``




https://github.com/llvm/llvm-project/pull/112107
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits