[Lldb-commits] [lldb] [LLDB] Finish implementing support for DW_FORM_data16 (PR #106799)

2024-09-02 Thread Pavel Labath via lldb-commits

labath wrote:

> Sadly, I haven't figured out a good way to test this.

`test/Shell/SymbolFile/DWARF/x86/DW_AT_const_value.s` tests various encodings 
of DW_AT_const_value.

It doesn't do DW_FORM_data16, most likely because it was not working at the 
time. You can add another case to the file to exercise this code path.

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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -38,6 +38,12 @@ endif()
 include(LLDBConfig)
 include(AddLLDB)
 
+# This has been added to keep the AIX build isolated for now.
+# It will need to be modified later.
+if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+  add_definitions("-D__AIX__")

labath wrote:

We shouldn't be defining a reserved identifier. Also, isn't there an existing 
macro that we could test use to check if we're on AIX?

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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Pavel Labath via lldb-commits

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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Pavel Labath via lldb-commits

https://github.com/labath commented:

So, how different is AIX from linux? Should we be treating it as a flavour of 
linux. E.g., have HostInfoAIX derive from HostInfoLinux instead of copying it ?

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


[Lldb-commits] [lldb] [lldb] fix(lldb/**.py): fix invalid escape sequences (PR #94034)

2024-09-02 Thread Eisuke Kawashima via lldb-commits

https://github.com/e-kwsm updated 
https://github.com/llvm/llvm-project/pull/94034

>From 92802878826c1bb0413373d1b05a7c52c8bc8c48 Mon Sep 17 00:00:00 2001
From: Eisuke Kawashima 
Date: Sat, 11 May 2024 02:39:21 +0900
Subject: [PATCH] fix(lldb/**.py): fix invalid escape sequences

---
 lldb/examples/python/crashlog.py  |   8 +-
 lldb/examples/python/delta.py |   2 +-
 lldb/examples/python/gdbremote.py |   4 +-
 lldb/examples/python/jump.py  |   6 +-
 lldb/examples/python/performance.py   |   2 +-
 lldb/examples/python/symbolication.py |   6 +-
 .../Python/lldbsuite/test/lldbpexpect.py  |   2 +-
 .../test/test_runner/process_control.py   |   2 +-
 .../command/backticks/TestBackticksInAlias.py |   4 +-
 .../TestMemoryAllocSettings.py|   2 +-
 .../API/commands/expression/test/TestExprs.py |   2 +-
 .../TestGuiExpandThreadsTree.py   |   2 +-
 lldb/test/API/commands/help/TestHelp.py   |   6 +-
 .../TestLaunchWithShellExpand.py  |   2 +-
 .../register/TestRegistersUnavailable.py  |   4 +-
 .../API/commands/settings/TestSettings.py |  12 +-
 .../target/basic/TestTargetCommand.py |   2 +-
 .../dwo/TestDumpDwo.py|  16 +-
 .../oso/TestDumpOso.py|  16 +-
 .../API/commands/trace/TestTraceDumpInfo.py   |   2 +-
 .../API/commands/trace/TestTraceEvents.py |   4 +-
 .../API/commands/trace/TestTraceStartStop.py  |  12 +-
 lldb/test/API/commands/trace/TestTraceTSC.py  |  10 +-
 .../driver/quit_speed/TestQuitWithProcess.py  |   2 +-
 .../TestBreakpointByLineAndColumn.py  |   2 +-
 .../TestBreakpointLocations.py|   2 +-
 .../TestDataFormatterAdv.py   |   8 +-
 .../TestDataFormatterCpp.py   |   6 +-
 .../TestDataFormatterObjCNSContainer.py   |  16 +-
 .../TestDataFormatterSkipSummary.py   |   2 +-
 .../TestDataFormatterGenericUnordered.py  |  22 +--
 .../libcxx/atomic/TestLibCxxAtomic.py |   2 +-
 .../initializerlist/TestInitializerList.py|   2 +-
 .../TestTypeSummaryListArg.py |   4 +-
 .../memory-region/TestMemoryRegion.py |   2 +-
 .../target_var/TestTargetVar.py   |   2 +-
 .../completion/TestIOHandlerCompletion.py |   2 +-
 .../c/function_types/TestFunctionTypes.py |   2 +-
 .../TestRegisterVariables.py  |   2 +-
 .../API/lang/c/set_values/TestSetValues.py|   4 +-
 lldb/test/API/lang/c/strings/TestCStrings.py  |   2 +-
 .../API/lang/c/tls_globals/TestTlsGlobals.py  |   8 +-
 .../API/lang/cpp/char1632_t/TestChar1632T.py  |   8 +-
 .../cpp/class_static/TestStaticVariables.py   |   4 +-
 .../lang/cpp/class_types/TestClassTypes.py|   2 +-
 .../cpp/dynamic-value/TestDynamicValue.py |   2 +-
 .../API/lang/cpp/namespace/TestNamespace.py   |   4 +-
 .../lang/cpp/signed_types/TestSignedTypes.py  |   4 +-
 .../cpp/unsigned_types/TestUnsignedTypes.py   |   2 +-
 .../test/API/lang/mixed/TestMixedLanguages.py |   4 +-
 .../lang/objc/foundation/TestObjCMethods.py   |   2 +-
 .../objc/foundation/TestObjCMethodsNSArray.py |  10 +-
 .../objc/foundation/TestObjCMethodsNSError.py |   2 +-
 .../objc/foundation/TestObjCMethodsString.py  |  10 +-
 .../TestObjCDynamicValue.py   |   2 +-
 .../TestObjCBuiltinTypes.py   |   4 +-
 .../TestAArch64LinuxMTEMemoryTagCoreFile.py   |  44 ++---
 .../TestAArch64LinuxMTEMemoryTagAccess.py | 160 +-
 .../TestAArch64LinuxMTEMemoryTagFaults.py |   6 +-
 .../TestAArch64LinuxTaggedMemoryRegion.py |   6 +-
 .../macosx/add-dsym/TestAddDsymDownload.py|   2 +-
 .../TestFirmwareCorefiles.py  |   2 +-
 .../kern-ver-str/TestKernVerStrLCNOTE.py  |   2 +-
 .../TestMultipleBinaryCorefile.py |   2 +-
 .../macosx/simulator/TestSimulatorPlatform.py |   2 +-
 .../skinny-corefile/TestSkinnyCorefile.py |   2 +-
 .../TestTargetArchFromModule.py   |   2 +-
 .../API/source-manager/TestSourceManager.py   |   2 +-
 .../lldb-server/TestGdbRemoteModuleInfo.py|   6 +-
 .../API/tools/lldb-server/TestPtyServer.py|   2 +-
 .../TestGdbRemoteTargetXmlPacket.py   |   2 +-
 lldb/test/API/types/AbstractBase.py   |   6 +-
 lldb/utils/lui/sourcewin.py   |   2 +-
 73 files changed, 267 insertions(+), 263 deletions(-)

diff --git a/lldb/examples/python/crashlog.py b/lldb/examples/python/crashlog.py
index 368437ed63e46b..bacba1b453fab6 100755
--- a/lldb/examples/python/crashlog.py
+++ b/lldb/examples/python/crashlog.py
@@ -296,7 +296,7 @@ class DarwinImage(symbolication.Image):
 except:
 dsymForUUIDBinary = ""
 
-dwarfdump_uuid_regex = re.compile("UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) 
.*")
+dwarfdump_uuid_regex = re.compile(r"UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) 
.*")
 
 def __init__(
 self, text_ad

[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Dhruv Srivastava via lldb-commits

DhruvSrivastavaX wrote:

> So, how different is AIX from linux? Should we be treating it as a flavour of 
> linux. E.g., have HostInfoAIX derive from HostInfoLinux instead of copying it 
> ?

AIX is UNIX based but its very different from Linux, so it cannot be treated as 
a flavour of Linux. 
For this PR, I have just added a boiler plate code from Linux, but the 
immediate next PR will be having AIX specific tweaks, as per community 
suggestions.
Here is the whole code in a draft PR:
#102601


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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Dhruv Srivastava via lldb-commits


@@ -38,6 +38,12 @@ endif()
 include(LLDBConfig)
 include(AddLLDB)
 
+# This has been added to keep the AIX build isolated for now.
+# It will need to be modified later.
+if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+  add_definitions("-D__AIX__")

DhruvSrivastavaX wrote:

It would be really helpful, if we can decide on a better alternative.

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


[Lldb-commits] [lldb] [lldb] Change the implementation of Status to store an llvm::Error (NFC) (PR #106774)

2024-09-02 Thread Pavel Labath via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Change the implementation of Status to store an llvm::Error (NFC) (PR #106774)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -174,33 +233,91 @@ const char *Status::AsCString(const char 
*default_error_str) const {
 
 // Clear the error and any cached error string that it might contain.
 void Status::Clear() {
-  m_code = 0;
-  m_type = eErrorTypeInvalid;
-  m_string.clear();
+  if (m_error)
+LLDB_LOG_ERRORV(GetLog(LLDBLog::API), std::move(m_error),
+"dropping error {0}");
+  m_error = llvm::Error::success();
+  llvm::consumeError(std::move(m_error));
 }
 
 // Access the error value.
-Status::ValueType Status::GetError() const { return m_code; }
+Status::ValueType Status::GetError() const {
+  Status::ValueType result = 0;
+  llvm::visitErrors(m_error, [&](const llvm::ErrorInfoBase &error) {
+std::error_code ec = error.convertToErrorCode();
+if (ec.category() == std::generic_category() ||
+ec.category() == generic_category() ||
+ec.category() == expression_category())
+  result = ec.value();
+else
+  result = 0xff;

labath wrote:

A more insteresting case is what should this return in case of multiple errors? 
Right now, it will return the last code, but maybe this is a better case for a 
special error code?

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


[Lldb-commits] [lldb] [lldb] Change the implementation of Status to store an llvm::Error (NFC) (PR #106774)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -96,16 +124,44 @@ Status Status::FromErrorStringWithFormat(const char 
*format, ...) {
   return Status(string);
 }
 
-llvm::Error Status::ToError() const {
-  if (Success())
-return llvm::Error::success();
-  if (m_type == ErrorType::eErrorTypePOSIX)
-return llvm::errorCodeToError(
-std::error_code(m_code, std::generic_category()));
-  return llvm::createStringError(AsCString());
+Status Status::FromExpressionError(lldb::ExpressionResults result,
+   std::string msg) {
+  return Status(llvm::make_error(
+  std::error_code(result, expression_category()), msg));
 }
 
-Status::~Status() = default;
+/// Creates a deep copy of all known errors and converts all other
+/// errors to a new llvm::StringError.
+static llvm::Error cloneError(llvm::Error &error) {
+  llvm::Error result = llvm::Error::success();
+  llvm::consumeError(std::move(result));
+  llvm::visitErrors(error, [&](const llvm::ErrorInfoBase &error) {
+if (error.isA())
+  result = llvm::make_error(error.convertToErrorCode());
+else if (error.isA())
+  result = llvm::make_error(error.convertToErrorCode());
+else if (error.isA())
+  result = llvm::make_error(error.convertToErrorCode(),
+ error.message());
+else
+  result =
+  llvm::createStringError(error.convertToErrorCode(), error.message());
+  });
+  return result;
+}
+
+Status Status::FromError(llvm::Error &&error) {
+  // Existing clients assume that the conversion to Status consumes
+  // and destroys the error. Use cloneError to convert all unnown
+  // errors to strings.
+  llvm::Error clone = cloneError(error);
+  llvm::consumeError(std::move(error));

labath wrote:

I'm still confused by this. Why isn't this just `return 
Status(std::move(error))` ?

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


[Lldb-commits] [lldb] [lldb] Change the implementation of Status to store an llvm::Error (NFC) (PR #106774)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -174,33 +233,91 @@ const char *Status::AsCString(const char 
*default_error_str) const {
 
 // Clear the error and any cached error string that it might contain.
 void Status::Clear() {
-  m_code = 0;
-  m_type = eErrorTypeInvalid;
-  m_string.clear();
+  if (m_error)
+LLDB_LOG_ERRORV(GetLog(LLDBLog::API), std::move(m_error),
+"dropping error {0}");
+  m_error = llvm::Error::success();
+  llvm::consumeError(std::move(m_error));
 }
 
 // Access the error value.
-Status::ValueType Status::GetError() const { return m_code; }
+Status::ValueType Status::GetError() const {
+  Status::ValueType result = 0;
+  llvm::visitErrors(m_error, [&](const llvm::ErrorInfoBase &error) {
+std::error_code ec = error.convertToErrorCode();
+if (ec.category() == std::generic_category() ||
+ec.category() == generic_category() ||
+ec.category() == expression_category())
+  result = ec.value();

labath wrote:

How about just returning `ec.value()` regardless of the category?

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


[Lldb-commits] [lldb] [lldb] Change the implementation of Status to store an llvm::Error (NFC) (PR #106774)

2024-09-02 Thread Pavel Labath via lldb-commits

https://github.com/labath commented:

Two high-level comments:
- I think that the `FromError`/`clone` changes would be better of as a separate 
patch(es). I have no problem with the changes themselves, but I think it'd be 
better to separate the meat of this patch from the mechanical renaming. The 
renames could be done either before an after the patch, as (AFAICT) the 
functions are just fancy names for (copy) constructors.
- I think this class should accept an open class hierarchy (like llvm::Error) 
does and not assume that it can enumerate all the error subclasses. I think the 
only additional property that we need of the error classes is the ability to 
clone themselves, which we could achieve by providing a `ClonableErrorInfo` 
class with an abstract `clone` method. We can still keep the code which 
converts all unclonable errors into a string error (but I'd only do it after a 
copy, not immediately during construction). The thing I want to avoid is the 
proliferation of very specific error types inside the base Status class -- the 
mach/windows error types should arguably be defined in the host library, and 
even the ExpressionError type might be better off inside the command 
interpreter or something. I'm not saying you have to do the refactor now, but 
I'd like to have the option to do so in the future.

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


[Lldb-commits] [lldb] [lldb] Change the implementation of Status to store an llvm::Error (NFC) (PR #106774)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -97,7 +97,7 @@ class LLDB_API SBError {
   friend class lldb_private::ScriptInterpreter;
   friend class lldb_private::python::SWIGBridge;
 
-  SBError(const lldb_private::Status &error);
+  SBError(lldb_private::Status &&error);

labath wrote:

Changing the argument type will also change the mangled name, so I don't think 
that the access level matters here (what this is really doing is adding a new 
function and (simultaneously) removing an existing one. However, I don't think 
that should be a problem, since people shouldn't be using the lldb_private 
functions.

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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -38,6 +38,12 @@ endif()
 include(LLDBConfig)
 include(AddLLDB)
 
+# This has been added to keep the AIX build isolated for now.
+# It will need to be modified later.
+if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+  add_definitions("-D__AIX__")

labath wrote:

You didn't really answer my question. Are there predefined compiler macros that 
we could use? I'd be surprised if there weren't any, as every platform I know 
of has some. FWIW, these are the predefined macros on linux: 
https://godbolt.org/z/EG9fKaxMv

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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Pavel Labath via lldb-commits

labath wrote:

> AIX specific tweaks

That's exactly what I'm worried about. I have seen the full PR, and while I 
haven't compared it side by side with linux, I did have a very strong sense of 
deja-vu when viewing it. So if like 80% of the code is going to be the same, 
then we should figure out how to share that code instead of making it a copy. 
Maybe both systems could be instances of some generic linux-like (whatever you 
want to call it) system...


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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Dhruv Srivastava via lldb-commits


@@ -38,6 +38,12 @@ endif()
 include(LLDBConfig)
 include(AddLLDB)
 
+# This has been added to keep the AIX build isolated for now.
+# It will need to be modified later.
+if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+  add_definitions("-D__AIX__")

DhruvSrivastavaX wrote:

At this point we are not aware of any predefined ones for AIX though. It would 
be great if the community can suggest something in this regard. We will also 
try to find some alternative accordingly. 

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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Dhruv Srivastava via lldb-commits

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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Dhruv Srivastava via lldb-commits

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


[Lldb-commits] [lldb] [lldb] gdb rsp file error pass fix (PR #106950)

2024-09-02 Thread via lldb-commits

https://github.com/dlav-sc created 
https://github.com/llvm/llvm-project/pull/106950

This patch fixes a error code parsing of gdb remote protocol response messages 
to File-I/O command.

>From 1f853519a648c2ebe3b2b26f9d51cacd2820be87 Mon Sep 17 00:00:00 2001
From: Daniil Avdeev 
Date: Tue, 23 Jul 2024 11:04:12 +
Subject: [PATCH] [lldb] gdb rsp file error pass fix

This patch fixes a error code parsing of gdb remote protocol response
messages to File-I/O command.
---
 .../GDBRemoteCommunicationClient.cpp  | 33 +++
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git 
a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 0297fe363f69e1..bce50eb4f8a907 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3064,22 +3064,41 @@ static int gdb_errno_to_system(int err) {
 
 static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
   uint64_t fail_result, Status &error) 
{
+  // The packet is expected to have the following format:
+  // 'F,'
+
   response.SetFilePos(0);
   if (response.GetChar() != 'F')
 return fail_result;
+
   int32_t result = response.GetS32(-2, 16);
   if (result == -2)
 return fail_result;
-  if (response.GetChar() == ',') {
-int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));
-if (result_errno != -1)
-  error = Status(result_errno, eErrorTypePOSIX);
-else
-  error = Status(-1, eErrorTypeGeneric);
-  } else
+
+  if (response.GetChar() != ',') {
 error.Clear();
+return result;
+  }
+
+  // Response packet should contain a error code at the end. This code
+  // corresponds either to the gdb IOFile error code, or to the posix errno.
+  int32_t result_errno = response.GetS32(-1, 16);
+  if (result_errno == -1) {
+error.SetError(-1, eErrorTypeGeneric);
+return result;
+  }
+
+  int rsp_errno = gdb_errno_to_system(result_errno);
+  if (rsp_errno != -1) {
+error.SetError(rsp_errno, eErrorTypePOSIX);
+return result;
+  }
+
+  // Have received a system error that isn't described in gdb rsp protocol
+  error.SetError(result_errno, eErrorTypePOSIX);
   return result;
 }
+
 lldb::user_id_t
 GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
File::OpenOptions flags, mode_t mode,

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


[Lldb-commits] [lldb] [lldb] gdb rsp file error pass fix (PR #106950)

2024-09-02 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: None (dlav-sc)


Changes

This patch fixes a error code parsing of gdb remote protocol response messages 
to File-I/O command.

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


1 Files Affected:

- (modified) 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (+26-7) 


``diff
diff --git 
a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 0297fe363f69e1..bce50eb4f8a907 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3064,22 +3064,41 @@ static int gdb_errno_to_system(int err) {
 
 static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
   uint64_t fail_result, Status &error) 
{
+  // The packet is expected to have the following format:
+  // 'F,'
+
   response.SetFilePos(0);
   if (response.GetChar() != 'F')
 return fail_result;
+
   int32_t result = response.GetS32(-2, 16);
   if (result == -2)
 return fail_result;
-  if (response.GetChar() == ',') {
-int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));
-if (result_errno != -1)
-  error = Status(result_errno, eErrorTypePOSIX);
-else
-  error = Status(-1, eErrorTypeGeneric);
-  } else
+
+  if (response.GetChar() != ',') {
 error.Clear();
+return result;
+  }
+
+  // Response packet should contain a error code at the end. This code
+  // corresponds either to the gdb IOFile error code, or to the posix errno.
+  int32_t result_errno = response.GetS32(-1, 16);
+  if (result_errno == -1) {
+error.SetError(-1, eErrorTypeGeneric);
+return result;
+  }
+
+  int rsp_errno = gdb_errno_to_system(result_errno);
+  if (rsp_errno != -1) {
+error.SetError(rsp_errno, eErrorTypePOSIX);
+return result;
+  }
+
+  // Have received a system error that isn't described in gdb rsp protocol
+  error.SetError(result_errno, eErrorTypePOSIX);
   return result;
 }
+
 lldb::user_id_t
 GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
File::OpenOptions flags, mode_t mode,

``




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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Dhruv Srivastava via lldb-commits

DhruvSrivastavaX wrote:

Thank you for your feedback; I understand the concern about potential code 
duplication. Indeed, components like `PlatformAIX, HostInfoAIX, and 
NativeProcess/Thread` do share significant similarities with their Linux 
counterparts. However, several other components, such as `ObjectFileXCOFF, the 
Big Archive container, and AIX-DYLD, `require more substantial changes due to 
platform-specific aspects like the AIX base object file formats, hardware 
architecture (PPC64), and other inherent differences.

We've also had to exclude certain functionalities that aren't feasible on AIX 
at this stage. The main intentionn for our current approach is to isolate 
platform dependencies, thereby avoiding conditional directives like `#if AIX 
#else` within the common codebase. Even in the draft PR, our long-term goal is 
to minimize such conditionals wherever possible.

That said, we've made every effort to keep the code as generic as possible, and 
we’re open to any further suggestions on how to improve this. It will help in 
refining the changes.

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


[Lldb-commits] [lldb] [llvm] [lldb][RISCV] function calls support in lldb expressions (PR #99336)

2024-09-02 Thread via lldb-commits

https://github.com/dlav-sc updated 
https://github.com/llvm/llvm-project/pull/99336

>From fb4e062d33c105591d8fb46d72dd64181880bdcd Mon Sep 17 00:00:00 2001
From: Daniil Avdeev 
Date: Thu, 11 Jul 2024 11:21:36 +
Subject: [PATCH 1/6] [lldb][RISCV] add jitted function calls to ABI

Function calls support in LLDB expressions for RISCV: 1 of 6

Augments corresponding functionality to RISCV ABI, which allows to jit
lldb expressions and thus make function calls inside them. Only function
calls with integer and void function arguments and return value are
supported.
---
 .../Plugins/ABI/RISCV/ABISysV_riscv.cpp   | 89 +--
 lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h |  3 +
 2 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp 
b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
index de304183f67175..6e7ab20c83bfe1 100644
--- a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
+++ b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
@@ -10,7 +10,9 @@
 
 #include 
 #include 
+#include 
 
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/IR/DerivedTypes.h"
 
 #include "Utility/RISCV_DWARF_Registers.h"
@@ -20,6 +22,7 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #define DEFINE_REG_NAME(reg_num) ConstString(#reg_num).GetCString()
@@ -164,11 +167,83 @@ TotalArgsSizeInWords(bool is_rv64,
   return total_size;
 }
 
+static bool UpdateRegister(RegisterContext *reg_ctx,
+   const lldb::RegisterKind reg_kind,
+   const uint32_t reg_num, const addr_t value) {
+  Log *log = GetLog(LLDBLog::Expressions);
+
+  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(reg_kind, reg_num);
+
+  LLDB_LOG(log, "Writing %s: 0x%" PRIx64, reg_info->name,
+   static_cast(value));
+  if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, value)) {
+LLDB_LOG(log, "Writing %s: failed", reg_info->name);
+return false;
+  }
+  return true;
+}
+
+static void LogInitInfo(Log *log, const Thread &thread, addr_t sp,
+addr_t func_addr, addr_t return_addr,
+const llvm::ArrayRef args) {
+  assert(log);
+  std::stringstream ss;
+  ss << "ABISysV_riscv::PrepareTrivialCall"
+ << " (tid = 0x%" << std::hex << thread.GetID() << ", sp = 0x%" << sp
+ << ", func_addr = 0x%" << func_addr << ", return_addr = 0x%"
+ << return_addr;
+
+  for (auto &&[idx, arg] : enumerate(args))
+ss << ", arg" << std::dec << idx << " = 0x%" << std::hex << arg;
+  ss << ")";
+  log->PutString(ss.str());
+}
+
 bool ABISysV_riscv::PrepareTrivialCall(Thread &thread, addr_t sp,
addr_t func_addr, addr_t return_addr,
llvm::ArrayRef args) const {
-  // TODO: Implement
-  return false;
+  Log *log = GetLog(LLDBLog::Expressions);
+  if (log)
+LogInitInfo(log, thread, sp, func_addr, return_addr, args);
+
+  const auto reg_ctx_sp = thread.GetRegisterContext();
+  if (!reg_ctx_sp) {
+LLDB_LOG(log, "Failed to get RegisterContext");
+return false;
+  }
+
+  if (args.size() > s_regs_for_args_count) {
+LLDB_LOG(log, "Function has %lu arguments, but only %lu are allowed!",
+ args.size(), s_regs_for_args_count);
+return false;
+  }
+
+  // Write arguments to registers
+  for (auto &&[idx, arg] : enumerate(args)) {
+const RegisterInfo *reg_info = reg_ctx_sp->GetRegisterInfo(
+eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + idx);
+LLDB_LOG(log, "About to write arg%lu (0x%" PRIx64 ") into %s", idx, arg,
+ reg_info->name);
+
+if (!reg_ctx_sp->WriteRegisterFromUnsigned(reg_info, arg)) {
+  LLDB_LOG(log, "Failed to write arg%lu (0x%" PRIx64 ") into %s", idx, arg,
+   reg_info->name);
+  return false;
+}
+  }
+
+  if (!UpdateRegister(reg_ctx_sp.get(), eRegisterKindGeneric,
+  LLDB_REGNUM_GENERIC_PC, func_addr))
+return false;
+  if (!UpdateRegister(reg_ctx_sp.get(), eRegisterKindGeneric,
+  LLDB_REGNUM_GENERIC_SP, sp))
+return false;
+  if (!UpdateRegister(reg_ctx_sp.get(), eRegisterKindGeneric,
+  LLDB_REGNUM_GENERIC_RA, return_addr))
+return false;
+
+  LLDB_LOG(log, "ABISysV_riscv::%s: success", __func__);
+  return true;
 }
 
 bool ABISysV_riscv::PrepareTrivialCall(
@@ -222,14 +297,14 @@ bool ABISysV_riscv::PrepareTrivialCall(
   assert(prototype.getFunctionNumParams() == args.size());
 
   const size_t num_args = args.size();
-  const size_t regs_for_args_count = 8U;
   const size_t num_args_in_regs =
-  num_args > regs_for_args_count ?  regs_for_args_count : num_args;
+  num_args > s_regs_for_args_count ? s_regs_for_args_count : num_args;
 
   // Number of arguments passed on stack.
   size_t args_size = TotalArgsS

[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread David Spickett via lldb-commits


@@ -38,6 +38,12 @@ endif()
 include(LLDBConfig)
 include(AddLLDB)
 
+# This has been added to keep the AIX build isolated for now.
+# It will need to be modified later.
+if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+  add_definitions("-D__AIX__")

DavidSpickett wrote:

There is `_AIX` at least in clang: https://godbolt.org/z/95MzjcsKn

And according to this (totally official, legit) doc 
(https://www.lnf.infn.it/computing/doc/aixcxx/html/language/ref/rnmcradd.htm) 
they exist for the AIX system compiler as well. I'm sure you can find the 
proper page :)

https://github.com/llvm/llvm-project/blob/0fa78b6c7bd43c2498700a98c47a02cf4fd06388/clang/lib/Basic/Targets/OSTargets.h#L641

If for some reason that's not going to work, then we would use something like 
`LLDB_...` as we have done for `LLDB_ENABLE_LIBXML2` and friends.

(but I'm yet to look at the whole PR so I don't know yet)

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


[Lldb-commits] [lldb] [lldb] gdb rsp file error pass fix (PR #106950)

2024-09-02 Thread David Spickett via lldb-commits

DavidSpickett wrote:

And this error is what exactly, what did we previously do and what does this PR 
now make us do?

I'm of course wondering if this can be tested too but let's be clear what's 
being fixed first and I'll see whether it can be added to some existing tests.

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


[Lldb-commits] [lldb] [lldb] Fix some tests that fail with system libstdc++ (PR #106885)

2024-09-02 Thread David Spickett via lldb-commits

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


[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)

2024-09-02 Thread via lldb-commits

https://github.com/Da-Viper updated 
https://github.com/llvm/llvm-project/pull/106919

>From 539d44a522e9e0563079ddbefb59e1b4b4caaca6 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka 
Date: Sun, 1 Sep 2024 17:26:11 +0100
Subject: [PATCH 1/5] [lldb-dap] Make environment option an object

---
 lldb/tools/lldb-dap/JSONUtils.cpp | 35 +--
 lldb/tools/lldb-dap/JSONUtils.h   | 21 +++
 lldb/tools/lldb-dap/README.md |  5 -
 lldb/tools/lldb-dap/lldb-dap.cpp  |  8 ++-
 lldb/tools/lldb-dap/package.json  | 11 +++---
 5 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 7338e7cf41eb03..fc2ef80c79cfad 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -136,6 +136,31 @@ std::vector GetStrings(const 
llvm::json::Object *obj,
   return strs;
 }
 
+std::unordered_map
+GetStringObject(const llvm::json::Object &obj, llvm::StringRef key) {
+  std::unordered_map strs;
+  const auto *const json_object = obj.getObject(key);
+  if (!json_object)
+return strs;
+
+  for (const auto &[key, value] : *json_object) {
+switch (value.kind()) {
+case llvm::json::Value::String:
+  strs.emplace(key.str(), value.getAsString()->str());
+  break;
+case llvm::json::Value::Number:
+case llvm::json::Value::Boolean:
+  strs.emplace(key.str(), llvm::to_string(value));
+  break;
+case llvm::json::Value::Null:
+case llvm::json::Value::Object:
+case llvm::json::Value::Array:
+  break;
+}
+  }
+  return strs;
+}
+
 static bool IsClassStructOrUnionType(lldb::SBType t) {
   return (t.GetTypeClass() & (lldb::eTypeClassUnion | lldb::eTypeClassStruct |
   lldb::eTypeClassArray)) != 0;
@@ -1370,13 +1395,11 @@ CreateRunInTerminalReverseRequest(const 
llvm::json::Object &launch_request,
   if (!cwd.empty())
 run_in_terminal_args.try_emplace("cwd", cwd);
 
-  // We need to convert the input list of environments variables into a
-  // dictionary
-  std::vector envs = GetStrings(launch_request_arguments, "env");
+  std::unordered_map envMap =
+  GetStringObject(*launch_request_arguments, "env");
   llvm::json::Object environment;
-  for (const std::string &env : envs) {
-size_t index = env.find('=');
-environment.try_emplace(env.substr(0, index), env.substr(index + 1));
+  for (const auto &[key, value] : envMap) {
+environment.try_emplace(key, value);
   }
   run_in_terminal_args.try_emplace("env",
llvm::json::Value(std::move(environment)));
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index b6356630b72682..de6228a0429944 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -16,6 +16,7 @@
 #include "llvm/Support/JSON.h"
 #include 
 #include 
+#include 
 
 namespace lldb_dap {
 
@@ -151,6 +152,26 @@ bool ObjectContainsKey(const llvm::json::Object &obj, 
llvm::StringRef key);
 /// strings, numbers or booleans.
 std::vector GetStrings(const llvm::json::Object *obj,
 llvm::StringRef key);
+/// Extract an object of key value strings for the specified key from an 
object.
+///
+/// String values in the array will be extracted without any quotes
+/// around them. Numbers and Booleans will be converted into
+/// strings. Any NULL, array or objects values in the array will be
+/// ignored.
+///
+/// \param[in] obj
+/// A JSON object that we will attempt to extract the array from
+///
+/// \param[in] key
+/// The key to use when extracting the value
+///
+/// \return
+/// An object of key value strings for the specified \a key, or
+/// \a fail_value if there is no key that matches or if the
+/// value is not an object or key and values in the object are not
+/// strings, numbers or booleans.
+std::unordered_map
+GetStringObject(const llvm::json::Object &obj, llvm::StringRef key);
 
 /// Fill a response object given the request object.
 ///
diff --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index 11a14d29ab51e2..5b6fc5ef990e60 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -77,7 +77,10 @@ adds `FOO=1` and `bar` to the environment:
   "name": "Debug",
   "program": "/tmp/a.out",
   "args": [ "one", "two", "three" ],
-  "env": [ "FOO=1", "BAR" ],
+  "env": {
+"FOO": "1"
+"BAR": ""
+  }
 }
 ```
 
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index c5c4b09f15622b..804f467c7a4e20 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -1831,7 +1831,13 @@ lldb::SBError LaunchProcess(const llvm::json::Object 
&request) {
 launch_info.SetArguments(MakeArgv(args).data(), true);
 
   // Pass any environment variables along that the user specified.
-  auto envs = GetStrings(arguments, "env");
+  auto envMa

[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Pavel Labath via lldb-commits

https://github.com/labath created 
https://github.com/llvm/llvm-project/pull/106955

The existing function already used the MainLoop class, which allows one to wait 
on multiple events at once. It needed to do this in order to wait for v4 and v6 
connections simultaneously. However, since it was creating its own instance of 
MainLoop, this meant that it was impossible to multiplex these sockets with 
anything else.

This patch simply adds a version of this function which uses an externally 
provided main loop instance, which allows the caller to add any events it deems 
necessary. The previous function becomes a very thin wrapper over the new one.

>From 50e1aeec73b5c5ad3571d040c2ecc04c8d7e4009 Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Mon, 2 Sep 2024 11:18:50 +0200
Subject: [PATCH] [lldb] Add a callback version of TCPSocket::Accept

The existing function already used the MainLoop class, which allows one
to wait on multiple events at once. It needed to do this in order to
wait for v4 and v6 connections simultaneously. However, since it was
creating its own instance of MainLoop, this meant that it was impossible
to multiplex these sockets with anything else.

This patch simply adds a version of this function which uses an
externally provided main loop instance, which allows the caller to add
any events it deems necessary. The previous function becomes a very thin
wrapper over the new one.
---
 lldb/include/lldb/Host/common/TCPSocket.h | 11 +++
 lldb/source/Host/common/TCPSocket.cpp | 96 +++
 lldb/unittests/Host/SocketTest.cpp| 35 +
 3 files changed, 91 insertions(+), 51 deletions(-)

diff --git a/lldb/include/lldb/Host/common/TCPSocket.h 
b/lldb/include/lldb/Host/common/TCPSocket.h
index b782c9e6096c44..78e80568e39967 100644
--- a/lldb/include/lldb/Host/common/TCPSocket.h
+++ b/lldb/include/lldb/Host/common/TCPSocket.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_HOST_COMMON_TCPSOCKET_H
 #define LLDB_HOST_COMMON_TCPSOCKET_H
 
+#include "lldb/Host/MainLoopBase.h"
 #include "lldb/Host/Socket.h"
 #include "lldb/Host/SocketAddress.h"
 #include 
@@ -40,6 +41,16 @@ class TCPSocket : public Socket {
 
   Status Connect(llvm::StringRef name) override;
   Status Listen(llvm::StringRef name, int backlog) override;
+
+  // Use the provided main loop instance to accept new connections. The 
callback
+  // will be called (from MainLoop::Run) for each new connection. This function
+  // does not block.
+  llvm::Expected>
+  Accept(MainLoopBase &loop,
+ std::function socket)> sock_cb);
+
+  // Accept a single connection and "return" it in the pointer argument. This
+  // function blocks until the connection arrives.
   Status Accept(Socket *&conn_socket) override;
 
   Status CreateSocket(int domain);
diff --git a/lldb/source/Host/common/TCPSocket.cpp 
b/lldb/source/Host/common/TCPSocket.cpp
index ea26d8433c370a..4699e34bff924c 100644
--- a/lldb/source/Host/common/TCPSocket.cpp
+++ b/lldb/source/Host/common/TCPSocket.cpp
@@ -19,6 +19,7 @@
 
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/WindowsError.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -254,67 +255,60 @@ void TCPSocket::CloseListenSockets() {
   m_listen_sockets.clear();
 }
 
-Status TCPSocket::Accept(Socket *&conn_socket) {
-  Status error;
-  if (m_listen_sockets.size() == 0) {
-error = Status::FromErrorString("No open listening sockets!");
-return error;
-  }
+llvm::Expected> TCPSocket::Accept(
+MainLoopBase &loop,
+std::function socket)> sock_cb) {
+  if (m_listen_sockets.size() == 0)
+return llvm::createStringError("No open listening sockets!");
 
-  NativeSocket sock = kInvalidSocketValue;
-  NativeSocket listen_sock = kInvalidSocketValue;
-  lldb_private::SocketAddress AcceptAddr;
-  MainLoop accept_loop;
   std::vector handles;
   for (auto socket : m_listen_sockets) {
 auto fd = socket.first;
-auto inherit = this->m_child_processes_inherit;
-auto io_sp = IOObjectSP(new TCPSocket(socket.first, false, inherit));
-handles.emplace_back(accept_loop.RegisterReadObject(
-io_sp, [fd, inherit, &sock, &AcceptAddr, &error,
-&listen_sock](MainLoopBase &loop) {
-  socklen_t sa_len = AcceptAddr.GetMaxLength();
-  sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len, inherit,
-  error);
-  listen_sock = fd;
-  loop.RequestTermination();
-}, error));
-if (error.Fail())
-  return error;
-  }
+auto io_sp =
+std::make_shared(fd, false, 
this->m_child_processes_inherit);
+auto cb = [this, fd, sock_cb](MainLoopBase &loop) {
+  lldb_private::SocketAddress AcceptAddr;
+  socklen_t sa_len = AcceptAddr.GetMaxLength();
+  Status error;
+  NativeSocket sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len,
+   m_child_processes_inherit, error);

[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)


Changes

The existing function already used the MainLoop class, which allows one to wait 
on multiple events at once. It needed to do this in order to wait for v4 and v6 
connections simultaneously. However, since it was creating its own instance of 
MainLoop, this meant that it was impossible to multiplex these sockets with 
anything else.

This patch simply adds a version of this function which uses an externally 
provided main loop instance, which allows the caller to add any events it deems 
necessary. The previous function becomes a very thin wrapper over the new one.

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


3 Files Affected:

- (modified) lldb/include/lldb/Host/common/TCPSocket.h (+11) 
- (modified) lldb/source/Host/common/TCPSocket.cpp (+45-51) 
- (modified) lldb/unittests/Host/SocketTest.cpp (+35) 


``diff
diff --git a/lldb/include/lldb/Host/common/TCPSocket.h 
b/lldb/include/lldb/Host/common/TCPSocket.h
index b782c9e6096c44..78e80568e39967 100644
--- a/lldb/include/lldb/Host/common/TCPSocket.h
+++ b/lldb/include/lldb/Host/common/TCPSocket.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_HOST_COMMON_TCPSOCKET_H
 #define LLDB_HOST_COMMON_TCPSOCKET_H
 
+#include "lldb/Host/MainLoopBase.h"
 #include "lldb/Host/Socket.h"
 #include "lldb/Host/SocketAddress.h"
 #include 
@@ -40,6 +41,16 @@ class TCPSocket : public Socket {
 
   Status Connect(llvm::StringRef name) override;
   Status Listen(llvm::StringRef name, int backlog) override;
+
+  // Use the provided main loop instance to accept new connections. The 
callback
+  // will be called (from MainLoop::Run) for each new connection. This function
+  // does not block.
+  llvm::Expected>
+  Accept(MainLoopBase &loop,
+ std::function socket)> sock_cb);
+
+  // Accept a single connection and "return" it in the pointer argument. This
+  // function blocks until the connection arrives.
   Status Accept(Socket *&conn_socket) override;
 
   Status CreateSocket(int domain);
diff --git a/lldb/source/Host/common/TCPSocket.cpp 
b/lldb/source/Host/common/TCPSocket.cpp
index ea26d8433c370a..4699e34bff924c 100644
--- a/lldb/source/Host/common/TCPSocket.cpp
+++ b/lldb/source/Host/common/TCPSocket.cpp
@@ -19,6 +19,7 @@
 
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/WindowsError.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -254,67 +255,60 @@ void TCPSocket::CloseListenSockets() {
   m_listen_sockets.clear();
 }
 
-Status TCPSocket::Accept(Socket *&conn_socket) {
-  Status error;
-  if (m_listen_sockets.size() == 0) {
-error = Status::FromErrorString("No open listening sockets!");
-return error;
-  }
+llvm::Expected> TCPSocket::Accept(
+MainLoopBase &loop,
+std::function socket)> sock_cb) {
+  if (m_listen_sockets.size() == 0)
+return llvm::createStringError("No open listening sockets!");
 
-  NativeSocket sock = kInvalidSocketValue;
-  NativeSocket listen_sock = kInvalidSocketValue;
-  lldb_private::SocketAddress AcceptAddr;
-  MainLoop accept_loop;
   std::vector handles;
   for (auto socket : m_listen_sockets) {
 auto fd = socket.first;
-auto inherit = this->m_child_processes_inherit;
-auto io_sp = IOObjectSP(new TCPSocket(socket.first, false, inherit));
-handles.emplace_back(accept_loop.RegisterReadObject(
-io_sp, [fd, inherit, &sock, &AcceptAddr, &error,
-&listen_sock](MainLoopBase &loop) {
-  socklen_t sa_len = AcceptAddr.GetMaxLength();
-  sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len, inherit,
-  error);
-  listen_sock = fd;
-  loop.RequestTermination();
-}, error));
-if (error.Fail())
-  return error;
-  }
+auto io_sp =
+std::make_shared(fd, false, 
this->m_child_processes_inherit);
+auto cb = [this, fd, sock_cb](MainLoopBase &loop) {
+  lldb_private::SocketAddress AcceptAddr;
+  socklen_t sa_len = AcceptAddr.GetMaxLength();
+  Status error;
+  NativeSocket sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len,
+   m_child_processes_inherit, error);
+  Log *log = GetLog(LLDBLog::Host);
+  if (error.Fail())
+LLDB_LOG(log, "AcceptSocket({0}): {1}", fd, error);
+
+  const lldb_private::SocketAddress &AddrIn = m_listen_sockets[fd];
+  if (!AddrIn.IsAnyAddr() && AcceptAddr != AddrIn) {
+CLOSE_SOCKET(sock);
+LLDB_LOG(log, "rejecting incoming connection from {0} (expecting {1})",
+ AcceptAddr.GetIPAddress(), AddrIn.GetIPAddress());
+  }
+  std::unique_ptr sock_up(new TCPSocket(sock, *this));
 
-  bool accept_connection = false;
-  std::unique_ptr accepted_socket;
-  // Loop until we are happy with our connection
-  while (!accept_connection) {
-accept_loop.Run();
+  // Keep our TCP packe

[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)

2024-09-02 Thread Pavel Labath via lldb-commits

labath wrote:

What I meant was something like 
[this](https://github.com/llvm/llvm-project/pull/106955). Basically, keep the 
socket code inside the socket class, but make it asynchronous. This way you can 
listen for as many sockets (and other things) as you like. It shouldn't be 
necessary to do the socket handling stuff externally.

I haven't looked into exactly how this would fit into the Acceptor class in 
lldb-server, but my preferred solutions would be:
- delete it (or at least significantly slim down it's functionality -- it's a 
very thin wrapper over the Socket class, and probably only exists due to 
historic reasons)
- make it callback-based as well

I don't like the idea of making Acceptor responsible for multiple ports for the 
same reason I did not want to do that for TCPSocket -- it's complicated and 
inflexible.

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread David Spickett via lldb-commits


@@ -1641,6 +1641,10 @@ 
NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
 
 Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t 
size,
   size_t &bytes_read) {
+  Log *log = GetLog(POSIXLog::Memory);
+  LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);

DavidSpickett wrote:

Does this include the function name? If not, add something to say it's a read.

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread David Spickett via lldb-commits


@@ -0,0 +1,63 @@
+"""
+Test the memory commands operating on memory regions with holes

DavidSpickett wrote:

I don't mind the terminology but perhaps add ` with holes (inaccessible pages)` 
to help anyone who is skimming through this. So they only have to read the 
header to know whether to care about the rest of the file.

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread David Spickett via lldb-commits


@@ -2526,28 +2526,16 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
   size_t bytes_read = 0;
   Status error = m_current_process->ReadMemoryWithoutTrap(
   read_addr, &buf[0], byte_count, bytes_read);
-  if (error.Fail()) {
-LLDB_LOGF(log,
-  "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
-  " mem 0x%" PRIx64 ": failed to read. Error: %s",
-  __FUNCTION__, m_current_process->GetID(), read_addr,
-  error.AsCString());
+  LLDB_LOG(log, "ReadMemoryWithoutTrap({0}) read {1}/{2} bytes (error: {3})",
+   read_addr, byte_count, bytes_read, error);
+  if (bytes_read == 0)

DavidSpickett wrote:

I would update the x/y bit to 1 be clearer which is which like:
```
requested X bytes read Y
```
(or use the phrasing from the log message you are removing below)

Also what is `error` here, `ReadMemoryWithoutTrap` doesn't seem to modify it.

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread David Spickett via lldb-commits


@@ -0,0 +1,63 @@
+"""
+Test the memory commands operating on memory regions with holes
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+
+
+class MemoryHolesTestCase(TestBase):
+NO_DEBUG_INFO_TESTCASE = True
+
+def setUp(self):
+super().setUp()
+# Find the line number to break inside main().
+self.line = line_number("main.cpp", "// break here")
+
+def _prepare_inferior(self):
+self.build()
+exe = self.getBuildArtifact("a.out")
+self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+# Break in main() after the variables are assigned values.
+lldbutil.run_break_set_by_file_and_line(
+self, "main.cpp", self.line, num_expected_locations=1, 
loc_exact=True
+)
+
+self.runCmd("run", RUN_SUCCEEDED)
+
+# The stop reason of the thread should be breakpoint.
+self.expect(
+"thread list",
+STOPPED_DUE_TO_BREAKPOINT,
+substrs=["stopped", "stop reason = breakpoint"],
+)
+
+# The breakpoint should have a hit count of 1.
+lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1)
+
+# Avoid the expression evaluator, as it can allocate allocate memory
+# inside the holes we've deliberately left empty.
+self.memory = 
self.frame().FindVariable("mem_with_holes").GetValueAsUnsigned()
+self.pagesize = 
self.frame().FindVariable("pagesize").GetValueAsUnsigned()
+positions = self.frame().FindVariable("positions")
+self.positions = [
+positions.GetChildAtIndex(i).GetValueAsUnsigned()
+for i in range(positions.GetNumChildren())
+]
+self.assertEqual(len(self.positions), 5)
+
+@expectedFailureWindows
+def test_memory_read(self):

DavidSpickett wrote:

To be clear, this test is not expecting memory read to skip over a hole. Merely 
handle there being a failure to read, correct?

Later changes (in your other PRs I think) will add memory find, which does have 
to know to jump over the holes.

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


[Lldb-commits] [lldb] [lldb] Fix some tests that fail with system libstdc++ (PR #106885)

2024-09-02 Thread Michael Buch via lldb-commits

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

Let's see what happens. We did this because these tests were failing on macOS 
CI, but I never fully figured out what was happening here. Will keep an eye out 
on the macOS bots

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


[Lldb-commits] [lldb] [lldb] Fix some tests that fail with system libstdc++ (PR #106885)

2024-09-02 Thread Michael Buch via lldb-commits

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


[Lldb-commits] [lldb] [lldb][AIX] Taking Linux Host Info header's base for AIX (PR #106910)

2024-09-02 Thread Pavel Labath via lldb-commits

labath wrote:

I'm not saying we should merge everything. I'm just talking about the classes 
you're introducing in this PR (HostInfo, etc.) What are the linux vs. aix 
differences there? 

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


[Lldb-commits] [lldb] [lldb] gdb rsp file error pass fix (PR #106950)

2024-09-02 Thread via lldb-commits

dlav-sc wrote:

> And this error is what exactly, what did we previously do and what does this 
> PR now make us do?
> 
> I'm of course wondering if this can be tested too but let's be clear what's 
> being fixed first and I'll see whether it can be added to some existing tests.

In my case lldb-server can't open file on a remote machine. Lldb client sends 
vFile:open message on the server, server tries to open a file, but receives 
ETXTBSY error. Lldb-server just checks that errno corresponding to some posix 
error 
(`if (code.category() == std::system_category())`) and if it so sends reply 
message with that posix error code, like it was with ETXTBSY. Then client 
receives this reply message, it tries to map errno on gdb rsp supported 
I/O-File error codes (which are in fact a limited set of posix errors that can 
occur then working with file). The problem is that gdb rsp doesn't has ETXTBSY 
in the list of supported errors 
https://sourceware.org/gdb/current/onlinedocs/gdb.html/Errno-Values.html#Errno-Values,
 so in this cases the error is considered as unknown. 
Currently, I am working on the patch, that in some cases fix ETXTBSY error, and 
at the beginning it was hard for me to understand what the problem is, so I've 
decided try to make error messages more clear.

I have an idea to just add ETXTBSY error code into gdb rsp and then add it 
here, but maybe there is another errors like ETXTBSY that can appear in 
I/O-File messages, so I have decided to handle it in such way.

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


[Lldb-commits] [lldb] [lldb] Fix some tests that fail with system libstdc++ (PR #106885)

2024-09-02 Thread Michael Buch via lldb-commits

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,63 @@
+"""
+Test the memory commands operating on memory regions with holes
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+
+
+class MemoryHolesTestCase(TestBase):
+NO_DEBUG_INFO_TESTCASE = True
+
+def setUp(self):
+super().setUp()
+# Find the line number to break inside main().
+self.line = line_number("main.cpp", "// break here")
+
+def _prepare_inferior(self):
+self.build()
+exe = self.getBuildArtifact("a.out")
+self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+# Break in main() after the variables are assigned values.
+lldbutil.run_break_set_by_file_and_line(
+self, "main.cpp", self.line, num_expected_locations=1, 
loc_exact=True
+)
+
+self.runCmd("run", RUN_SUCCEEDED)
+
+# The stop reason of the thread should be breakpoint.
+self.expect(
+"thread list",
+STOPPED_DUE_TO_BREAKPOINT,
+substrs=["stopped", "stop reason = breakpoint"],
+)
+
+# The breakpoint should have a hit count of 1.
+lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1)
+
+# Avoid the expression evaluator, as it can allocate allocate memory
+# inside the holes we've deliberately left empty.
+self.memory = 
self.frame().FindVariable("mem_with_holes").GetValueAsUnsigned()
+self.pagesize = 
self.frame().FindVariable("pagesize").GetValueAsUnsigned()
+positions = self.frame().FindVariable("positions")
+self.positions = [
+positions.GetChildAtIndex(i).GetValueAsUnsigned()
+for i in range(positions.GetNumChildren())
+]
+self.assertEqual(len(self.positions), 5)
+
+@expectedFailureWindows
+def test_memory_read(self):

labath wrote:

Correct.

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -1641,6 +1641,10 @@ 
NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
 
 Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t 
size,
   size_t &bytes_read) {
+  Log *log = GetLog(POSIXLog::Memory);
+  LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);

labath wrote:

it does (with `log enable -F`)

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -2526,28 +2526,16 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
   size_t bytes_read = 0;
   Status error = m_current_process->ReadMemoryWithoutTrap(
   read_addr, &buf[0], byte_count, bytes_read);
-  if (error.Fail()) {
-LLDB_LOGF(log,
-  "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
-  " mem 0x%" PRIx64 ": failed to read. Error: %s",
-  __FUNCTION__, m_current_process->GetID(), read_addr,
-  error.AsCString());
+  LLDB_LOG(log, "ReadMemoryWithoutTrap({0}) read {1}/{2} bytes (error: {3})",
+   read_addr, byte_count, bytes_read, error);
+  if (bytes_read == 0)

labath wrote:

Expanded the wording. I'm not sure what you meant with the second part. `error` 
is the result of the `ReadMemoryWithoutTrap` call (line 2527).

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,63 @@
+"""
+Test the memory commands operating on memory regions with holes

labath wrote:

Done.

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -0,0 +1,63 @@
+"""
+Test the memory commands operating on memory regions with holes
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+
+
+class MemoryHolesTestCase(TestBase):
+NO_DEBUG_INFO_TESTCASE = True
+
+def setUp(self):
+super().setUp()
+# Find the line number to break inside main().
+self.line = line_number("main.cpp", "// break here")
+
+def _prepare_inferior(self):
+self.build()
+exe = self.getBuildArtifact("a.out")
+self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+# Break in main() after the variables are assigned values.
+lldbutil.run_break_set_by_file_and_line(
+self, "main.cpp", self.line, num_expected_locations=1, 
loc_exact=True
+)
+
+self.runCmd("run", RUN_SUCCEEDED)
+
+# The stop reason of the thread should be breakpoint.
+self.expect(
+"thread list",
+STOPPED_DUE_TO_BREAKPOINT,
+substrs=["stopped", "stop reason = breakpoint"],
+)
+
+# The breakpoint should have a hit count of 1.
+lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1)
+
+# Avoid the expression evaluator, as it can allocate allocate memory
+# inside the holes we've deliberately left empty.
+self.memory = 
self.frame().FindVariable("mem_with_holes").GetValueAsUnsigned()
+self.pagesize = 
self.frame().FindVariable("pagesize").GetValueAsUnsigned()
+positions = self.frame().FindVariable("positions")
+self.positions = [
+positions.GetChildAtIndex(i).GetValueAsUnsigned()
+for i in range(positions.GetNumChildren())
+]
+self.assertEqual(len(self.positions), 5)
+
+@expectedFailureWindows
+def test_memory_read(self):
+self._prepare_inferior()
+
+error = lldb.SBError()
+content = self.process().ReadMemory(self.memory, 2 * self.pagesize, 
error)
+self.assertEqual(len(content), self.pagesize)
+self.assertEqual(content[0:7], b"needle\0")
+self.assertTrue(error.Fail())
+self.assertEqual(
+f"memory read failed for {self.memory+self.pagesize:#x}", 
error.GetCString()
+)

labath wrote:

(Removed the assertion on the exact error message, as windows returns a 
different error)

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread Pavel Labath via lldb-commits

https://github.com/labath updated 
https://github.com/llvm/llvm-project/pull/106532

>From 610757ced98139d3d10451dcca195692b0c2d832 Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Thu, 29 Aug 2024 12:26:01 +0200
Subject: [PATCH 1/3] [lldb/linux] Make truncated reads work

Previously, we were returning an error if we couldn't read the whole
region. This doesn't matter most of the time, because lldb caches memory
reads, and in that process it aligns them to cache line boundaries. As
(LLDB) cache lines are smaller than pages, the reads are unlikely to
cross page boundaries.

Nonetheless, this can cause a problem for large reads (which bypass the
cache), where we're unable to read anything even if just a single byte
of the memory is unreadable. This patch fixes the lldb-server to do
that, and also changes the linux implementation, to reuse any partial
results it got from the process_vm_readv call (to avoid having to
re-read everything again using ptrace, only to find that it stopped at
the same place).

This matches debugserver behavior. It is also consistent with the gdb
remote protocol documentation, but -- notably -- not with actual
gdbserver behavior (which returns errors instead of partial results). We
filed a
[clarification bug](https://sourceware.org/bugzilla/show_bug.cgi?id=24751)
several years ago. Though we did not really reach a conclusion there, I
think this is the most logical behavior.

The associated test does not currently pass on windows, because the
windows memory read APIs don't support partial reads (I have a WIP patch
to work around that).
---
 .../Process/Linux/NativeProcessLinux.cpp  | 41 -
 .../GDBRemoteCommunicationServerLLGS.cpp  | 20 +
 .../API/functionalities/memory/holes/Makefile |  3 +
 .../memory/holes/TestMemoryHoles.py   | 63 ++
 .../API/functionalities/memory/holes/main.cpp | 87 +++
 5 files changed, 176 insertions(+), 38 deletions(-)
 create mode 100644 lldb/test/API/functionalities/memory/holes/Makefile
 create mode 100644 
lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
 create mode 100644 lldb/test/API/functionalities/memory/holes/main.cpp

diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp 
b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index cb95da9fc72363..1e2e3a80b18bf6 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -1641,6 +1641,10 @@ 
NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
 
 Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t 
size,
   size_t &bytes_read) {
+  Log *log = GetLog(POSIXLog::Memory);
+  LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
+
+  bytes_read = 0;
   if (ProcessVmReadvSupported()) {
 // The process_vm_readv path is about 50 times faster than ptrace api. We
 // want to use this syscall if it is supported.
@@ -1651,32 +1655,29 @@ Status NativeProcessLinux::ReadMemory(lldb::addr_t 
addr, void *buf, size_t size,
 remote_iov.iov_base = reinterpret_cast(addr);
 remote_iov.iov_len = size;
 
-bytes_read = process_vm_readv(GetCurrentThreadID(), &local_iov, 1,
-  &remote_iov, 1, 0);
-const bool success = bytes_read == size;
+ssize_t read_result = process_vm_readv(GetCurrentThreadID(), &local_iov, 1,
+   &remote_iov, 1, 0);
+int error = 0;
+if (read_result < 0)
+  error = errno;
+else
+  bytes_read = read_result;
 
-Log *log = GetLog(POSIXLog::Process);
 LLDB_LOG(log,
- "using process_vm_readv to read {0} bytes from inferior "
- "address {1:x}: {2}",
- size, addr, success ? "Success" : llvm::sys::StrError(errno));
-
-if (success)
-  return Status();
-// else the call failed for some reason, let's retry the read using ptrace
-// api.
+ "process_vm_readv({0}, [iovec({1}, {2})], [iovec({3:x}, {2})], 1, 
"
+ "0) => {4} ({5})",
+ GetCurrentThreadID(), buf, size, addr, read_result,
+ error > 0 ? llvm::sys::StrError(errno) : "sucesss");
   }
 
   unsigned char *dst = static_cast(buf);
   size_t remainder;
   long data;
 
-  Log *log = GetLog(POSIXLog::Memory);
-  LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
-
-  for (bytes_read = 0; bytes_read < size; bytes_read += remainder) {
+  for (; bytes_read < size; bytes_read += remainder) {
 Status error = NativeProcessLinux::PtraceWrapper(
-PTRACE_PEEKDATA, GetCurrentThreadID(), (void *)addr, nullptr, 0, 
&data);
+PTRACE_PEEKDATA, GetCurrentThreadID(),
+reinterpret_cast(addr + bytes_read), nullptr, 0, &data);
 if (error.Fail())
   return error;
 
@@ -1684,11 +1685,7 @@ Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, 
void *buf, 

[Lldb-commits] [lldb] [lldb] Fix some tests that fail with system libstdc++ (PR #106885)

2024-09-02 Thread Michael Buch via lldb-commits

Michael137 wrote:

We should probably skip the `USE_LIBCPP` tests in the cases where a libc++ is 
nowhere available. Don't think that'd be easy to do at the Makefile level, but 
possibly lldb-dotest?

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread David Spickett via lldb-commits


@@ -2526,28 +2526,16 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
   size_t bytes_read = 0;
   Status error = m_current_process->ReadMemoryWithoutTrap(
   read_addr, &buf[0], byte_count, bytes_read);
-  if (error.Fail()) {
-LLDB_LOGF(log,
-  "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
-  " mem 0x%" PRIx64 ": failed to read. Error: %s",
-  __FUNCTION__, m_current_process->GetID(), read_addr,
-  error.AsCString());
+  LLDB_LOG(log, "ReadMemoryWithoutTrap({0}) read {1}/{2} bytes (error: {3})",
+   read_addr, byte_count, bytes_read, error);
+  if (bytes_read == 0)

DavidSpickett wrote:

So it is :)

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


[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread David Spickett via lldb-commits

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

LGTM

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

slydiman wrote:

@labath 
> Basically, keep the socket code inside the socket class, but make it 
> asynchronous. This way you can listen for as many sockets (and other things) 
> as you like. It shouldn't be necessary to do the socket handling stuff 
> externally.
> 
> I haven't looked into exactly how this would fit into the Acceptor class in 
> lldb-server, but my preferred solutions would be:
> 
> * delete it (or at least significantly slim down it's functionality -- it's a 
> very thin wrapper over the Socket class, and probably only exists due to 
> historic reasons)
> * make it callback-based as well
>
> I don't like the idea of making Acceptor responsible for multiple ports for 
> the same reason I did not want to do that for TCPSocket -- it's complicated 
> and inflexible.

I don't see any profit of this change. Using an extrernal MainLoop we can break 
the blocking Accept() from an other thread. But we can break it making a dummy 
connection too. 

The main reason to change TCPSocket was to be able to wait for multiple 
connections from different ports in the same blocking Accept() in the single 
thread.
Currently #104238 contains the best implementation of Acceptor.cpp w/o changing 
TCPSocket.

sock_cb parameter is useles here because it will be always the same. 
TCPSocket::m_listen_sockets is still here and it is still inaccesible 
externally. The method Listen() which initializes m_listen_sockets is 
unchanged. 
A callback may be useful (in theory) in Listen() to add a custom listen sockets 
to m_listen_sockets. Probably it is better to just initialize an own 
listen_sockets and just provide it to TCPSocket. But where this code will be 
placed? Acceptor.cpp, lldb-platform.cpp?

If you want to delete Acceptor, the best approach is the following:

Use Listen() from #104797 but w/o changing the connection string:
Status TCPSocket::Listen(llvm::StringRef name, int backlog, std::set 
* extra_ports = nullptr)

The accept MainLoop must be a member of TCPSocket and it is enough to just add 
TCPSocket::BreakAccept() { m_accept_loop.AddPendingCallback([](MainLoopBase 
&loop) { loop.RequestTermination(); }); } 

> I haven't looked into exactly how this would fit into the Acceptor class in 
> lldb-server

This is the problem. I don't see how this PR will help to implement accepting 
for multiple connections from 2 ports. It only complicates TCPSocket.

I'm trying to offer the `completed` solution which has been tested.

BTW, please approve NFC #106640.

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

slydiman wrote:

> I don't like the idea of making Acceptor responsible for multiple ports for 
> the same reason I did not want to do that for TCPSocket -- it's complicated 
> and inflexible.

Note Acceptor is used ONLY in lldb-platform.cpp
We can use the Accept() for the second port in the second thread. Then it is 
enough to add TCPSocket::BreakAccept() or just use a dummy connection and don't 
change TCPSocket and Accptor at all. 
But the common Accept() for both connections in the single thread looks much 
better.

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


[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)

2024-09-02 Thread via lldb-commits

Da-Viper wrote:

@vogelsgesang I am not sure if it possible to use a dict for sourceMaps since a 
source can map to multiple destination see test 

https://github.com/llvm/llvm-project/blob/a9c71d36655bd188521c74ce7834983e8c2a86cc/lldb/test/API/tools/lldb-dap/breakpoint/TestDAP_setBreakpoints.py#L53-L56

Using a source map as a dictionary will invalidate the previous set 
destination. 


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


[Lldb-commits] [clang] [compiler-rt] [libcxx] [lldb] [llvm] Rename Sanitizer Coverage => Coverage Sanitizer (PR #106505)

2024-09-02 Thread via lldb-commits

https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/106505

>From adb4a0eb00972811343ff05eac6977512f01970a Mon Sep 17 00:00:00 2001
From: Corentin Jabot 
Date: Thu, 29 Aug 2024 09:43:56 +0200
Subject: [PATCH 1/2] Rename Sanitizer Coverage => Coverage Sanitizer

This is so that we are consistent with other sanitizers.
Importantly, this makes the docs clearer.

Driver flags are left unchanged. The good thing is that flags
were already consistent with other sanitizers so there
would not be any motivation to change them,
even if we were feeling disruptive.
---
 ...izerCoverage.rst => CoverageSanitizer.rst} |  16 ++--
 clang/docs/SourceBasedCodeCoverage.rst|   2 +-
 clang/docs/UsersManual.rst|   2 +-
 clang/docs/index.rst  |   2 +-
 clang/docs/tools/clang-formatted-files.txt|   2 +-
 clang/include/clang/Basic/AttrDocs.td |   4 +-
 clang/include/clang/Basic/CodeGenOptions.def  |  18 ++--
 clang/include/clang/Basic/CodeGenOptions.h|   2 +-
 .../clang/Basic/DiagnosticDriverKinds.td  |   8 +-
 clang/include/clang/Driver/Options.td |  26 +++---
 clang/lib/CodeGen/BackendUtil.cpp |  10 +--
 clang/lib/Driver/SanitizerArgs.cpp|   4 +-
 clang/test/CodeGen/Inputs/memprof.exe | Bin 1394680 -> 1394680 bytes
 clang/test/CodeGen/sancov-new-pm.c|   2 +-
 clang/test/Driver/sancov.c|   2 +-
 .../include/sanitizer/common_interface_defs.h |   2 +-
 .../include/sanitizer/coverage_interface.h|   2 +-
 compiler-rt/lib/fuzzer/dataflow/DataFlow.cpp  |   4 +-
 .../lib/sanitizer_common/CMakeLists.txt   |  18 ++--
 ...sia.cpp => coverage_sanitizer_fuchsia.cpp} |   6 +-
 ...e.inc => coverage_sanitizer_interface.inc} |   4 +-
 ...cpp => coverage_sanitizer_libcdep_new.cpp} |   8 +-
 ...p => coverage_sanitizer_win_dll_thunk.cpp} |   6 +-
 ...e_sanitizer_win_dynamic_runtime_thunk.cpp} |   8 +-
 ...pp => coverage_sanitizer_win_sections.cpp} |   4 +-
 ...erage_sanitizer_win_weak_interception.cpp} |   6 +-
 .../lib/sanitizer_common/sancov_flags.cpp |   2 +-
 .../lib/sanitizer_common/sancov_flags.h   |   2 +-
 .../lib/sanitizer_common/sancov_flags.inc |   2 +-
 .../Darwin/interface_symbols_darwin.cpp   |   2 +-
 .../Linux/interface_symbols_linux.cpp |   2 +-
 .../asan/TestCases/Posix/coverage-reset.cpp   |  14 +--
 .../test/asan/TestCases/coverage-and-lsan.cpp |   2 +-
 ...verage_sanitizer_allowlist_ignorelist.cpp} |   0
 ...pp => coverage_sanitizer_control_flow.cpp} |   0
 ...coverage_sanitizer_inline8bit_counter.cpp} |   0
 ...tizer_inline8bit_counter_default_impl.cpp} |   0
 ...> coverage_sanitizer_inline_bool_flag.cpp} |   0
 ...ne.cpp => coverage_sanitizer_no_prune.cpp} |   0
 ...cpp => coverage_sanitizer_stack_depth.cpp} |   0
 ...e.cpp => coverage_sanitizer_symbolize.cpp} |   2 +-
 ...coverage_sanitizer_trace_loads_stores.cpp} |   0
 ...coverage_sanitizer_trace_pc_guard-dso.cpp} |  10 +--
 ...overage_sanitizer_trace_pc_guard-init.cpp} |   0
 ... => coverage_sanitizer_trace_pc_guard.cpp} |   8 +-
 libcxx/docs/VendorDocumentation.rst   |   2 +-
 lldb/docs/resources/fuzzing.rst   |   4 +-
 llvm/docs/FuzzingLLVM.rst |   2 +-
 llvm/docs/LangRef.rst |   2 +-
 llvm/docs/LibFuzzer.rst   |  12 +--
 llvm/docs/SymbolizerMarkupFormat.rst  |   2 +-
 .../include/llvm/Transforms/Instrumentation.h |   6 +-
 ...anitizerCoverage.h => CoverageSanitizer.h} |  14 +--
 llvm/lib/Passes/PassBuilder.cpp   |   2 +-
 llvm/lib/Passes/PassRegistry.def  |   2 +-
 .../Transforms/Instrumentation/CMakeLists.txt |   2 +-
 ...izerCoverage.cpp => CoverageSanitizer.cpp} |  82 +-
 .../SanitizerCoverage/crit-edge-sancov.ll |   4 +-
 .../Transforms/PGOProfile/Inputs/memprof.exe  | Bin 1606400 -> 1606400 bytes
 .../PGOProfile/Inputs/memprof.nocolinfo.exe   | Bin 1606168 -> 1606168 bytes
 .../Inputs/memprof_internal_linkage.exe   | Bin 1605160 -> 1605160 bytes
 .../PGOProfile/Inputs/memprof_loop_unroll.exe | Bin 1605960 -> 1605960 bytes
 .../Inputs/memprof_missing_leaf.exe   | Bin 1605072 -> 1605072 bytes
 .../Inputs/basic-histogram.memprofexe | Bin 1611256 -> 1611256 bytes
 .../llvm-profdata/Inputs/basic.memprofexe | Bin 1604896 -> 1604896 bytes
 .../llvm-profdata/Inputs/basic_v3.memprofexe  | Bin 1379856 -> 1379856 bytes
 .../llvm-profdata/Inputs/buildid.memprofexe   | Bin 1604904 -> 1604904 bytes
 .../llvm-profdata/Inputs/inline.memprofexe| Bin 1605480 -> 1605480 bytes
 .../llvm-profdata/Inputs/multi.memprofexe | Bin 1604912 -> 1604912 bytes
 .../Inputs/padding-histogram.memprofexe   | Bin 1606576 -> 1606576 bytes
 .../tools/llvm-profdata/Inputs/pic.memprofexe | Bin 1607856 -> 1607856 bytes
 .../X86/Inputs/elf64-badentrysizes.bin| Bin 469664 -> 469664 bytes
 .../llvm-xray/X86/Inputs/elf64-example.bin 

[Lldb-commits] [clang] [compiler-rt] [libcxx] [lldb] [llvm] Rename Sanitizer Coverage => Coverage Sanitizer (PR #106505)

2024-09-02 Thread via lldb-commits


@@ -257,7 +257,7 @@ General purpose options
 
   A semicolon list of arguments to pass when running the libc++ benchmarks 
using the
   ``check-cxx-benchmarks`` rule. By default we run the benchmarks for a very 
short amount of time,
-  since the primary use of ``check-cxx-benchmarks`` is to get test and 
sanitizer coverage, not to
+  since the primary use of ``check-cxx-benchmarks`` is to get test and 
coverage sanitizer, not to

cor3ntin wrote:

Nice catch! I did another pass on the PR to make sure there wasn't other such 
instances

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


[Lldb-commits] [lldb] [lldb][NFC] Move few static helpers to the class Socket and make them public (PR #106640)

2024-09-02 Thread Pavel Labath via lldb-commits

https://github.com/labath requested changes to this pull request.

I don't think this is a good change.

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


[Lldb-commits] [lldb] [lldb][NFC] Move few static helpers to the class Socket and make them public (PR #106640)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

slydiman wrote:

> I don't think this is a good change.

What exactly is wrong here?

Is that code good duplicated in Socket.cpp and TCPSocket.cpp?
```
#if defined(_WIN32)
  bool success = closesocket(m_socket) == 0;
#else
  bool success = ::close(m_socket) == 0;
#endif
```

SetLastError(Status &error) is placed in Socket, but GetLastError() in 
TCPSocket. Is it ok?

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


[Lldb-commits] [lldb] [lldb] gdb rsp file error pass fix (PR #106950)

2024-09-02 Thread via lldb-commits

https://github.com/dlav-sc updated 
https://github.com/llvm/llvm-project/pull/106950

>From 1480b5554d3d65fc96b7c2cbb628eaec4123d209 Mon Sep 17 00:00:00 2001
From: Daniil Avdeev 
Date: Tue, 23 Jul 2024 11:04:12 +
Subject: [PATCH] [lldb] gdb rsp file error pass fix

This patch fixes a error code parsing of gdb remote protocol response
messages to File-I/O command.
---
 .../GDBRemoteCommunicationClient.cpp  | 33 +++
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git 
a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 0297fe363f69e1..6eac23bba959d5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3064,22 +3064,41 @@ static int gdb_errno_to_system(int err) {
 
 static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
   uint64_t fail_result, Status &error) 
{
+  // The packet is expected to have the following format:
+  // 'F,'
+
   response.SetFilePos(0);
   if (response.GetChar() != 'F')
 return fail_result;
+
   int32_t result = response.GetS32(-2, 16);
   if (result == -2)
 return fail_result;
-  if (response.GetChar() == ',') {
-int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));
-if (result_errno != -1)
-  error = Status(result_errno, eErrorTypePOSIX);
-else
-  error = Status(-1, eErrorTypeGeneric);
-  } else
+
+  if (response.GetChar() != ',') {
 error.Clear();
+return result;
+  }
+
+  // Response packet should contain a error code at the end. This code
+  // corresponds either to the gdb IOFile error code, or to the posix errno.
+  int32_t result_errno = response.GetS32(-1, 16);
+  if (result_errno == -1) {
+error = Status(-1, eErrorTypeGeneric);
+return result;
+  }
+
+  int rsp_errno = gdb_errno_to_system(result_errno);
+  if (rsp_errno != -1) {
+error = Status(rsp_errno, eErrorTypePOSIX);
+return result;
+  }
+
+  // Have received a system error that isn't described in gdb rsp protocol
+  error = Status(result_errno, eErrorTypePOSIX);
   return result;
 }
+
 lldb::user_id_t
 GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
File::OpenOptions flags, mode_t mode,

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


[Lldb-commits] [lldb] 181cc75 - [lldb/linux] Make truncated reads work (#106532)

2024-09-02 Thread via lldb-commits

Author: Pavel Labath
Date: 2024-09-02T14:44:18+02:00
New Revision: 181cc75ea8be70e3fa7145456e1bf2331e0bc5e4

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

LOG: [lldb/linux] Make truncated reads work (#106532)

Previously, we were returning an error if we couldn't read the whole
region. This doesn't matter most of the time, because lldb caches memory
reads, and in that process it aligns them to cache line boundaries. As
(LLDB) cache lines are smaller than pages, the reads are unlikely to
cross page boundaries.

Nonetheless, this can cause a problem for large reads (which bypass the
cache), where we're unable to read anything even if just a single byte
of the memory is unreadable. This patch fixes the lldb-server to do
that, and also changes the linux implementation, to reuse any partial
results it got from the process_vm_readv call (to avoid having to
re-read everything again using ptrace, only to find that it stopped at
the same place).

This matches debugserver behavior. It is also consistent with the gdb
remote protocol documentation, but -- notably -- not with actual
gdbserver behavior (which returns errors instead of partial results). We
filed a
[clarification
bug](https://sourceware.org/bugzilla/show_bug.cgi?id=24751) several
years ago. Though we did not really reach a conclusion there, I think
this is the most logical behavior.

The associated test does not currently pass on windows, because the
windows memory read APIs don't support partial reads (I have a WIP patch
to work around that).

Added: 
lldb/test/API/functionalities/memory/holes/Makefile
lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
lldb/test/API/functionalities/memory/holes/main.cpp

Modified: 
lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp

Removed: 




diff  --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp 
b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index cb95da9fc72363..1e2e3a80b18bf6 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -1641,6 +1641,10 @@ 
NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
 
 Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t 
size,
   size_t &bytes_read) {
+  Log *log = GetLog(POSIXLog::Memory);
+  LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
+
+  bytes_read = 0;
   if (ProcessVmReadvSupported()) {
 // The process_vm_readv path is about 50 times faster than ptrace api. We
 // want to use this syscall if it is supported.
@@ -1651,32 +1655,29 @@ Status NativeProcessLinux::ReadMemory(lldb::addr_t 
addr, void *buf, size_t size,
 remote_iov.iov_base = reinterpret_cast(addr);
 remote_iov.iov_len = size;
 
-bytes_read = process_vm_readv(GetCurrentThreadID(), &local_iov, 1,
-  &remote_iov, 1, 0);
-const bool success = bytes_read == size;
+ssize_t read_result = process_vm_readv(GetCurrentThreadID(), &local_iov, 1,
+   &remote_iov, 1, 0);
+int error = 0;
+if (read_result < 0)
+  error = errno;
+else
+  bytes_read = read_result;
 
-Log *log = GetLog(POSIXLog::Process);
 LLDB_LOG(log,
- "using process_vm_readv to read {0} bytes from inferior "
- "address {1:x}: {2}",
- size, addr, success ? "Success" : llvm::sys::StrError(errno));
-
-if (success)
-  return Status();
-// else the call failed for some reason, let's retry the read using ptrace
-// api.
+ "process_vm_readv({0}, [iovec({1}, {2})], [iovec({3:x}, {2})], 1, 
"
+ "0) => {4} ({5})",
+ GetCurrentThreadID(), buf, size, addr, read_result,
+ error > 0 ? llvm::sys::StrError(errno) : "sucesss");
   }
 
   unsigned char *dst = static_cast(buf);
   size_t remainder;
   long data;
 
-  Log *log = GetLog(POSIXLog::Memory);
-  LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
-
-  for (bytes_read = 0; bytes_read < size; bytes_read += remainder) {
+  for (; bytes_read < size; bytes_read += remainder) {
 Status error = NativeProcessLinux::PtraceWrapper(
-PTRACE_PEEKDATA, GetCurrentThreadID(), (void *)addr, nullptr, 0, 
&data);
+PTRACE_PEEKDATA, GetCurrentThreadID(),
+reinterpret_cast(addr + bytes_read), nullptr, 0, &data);
 if (error.Fail())
   return error;
 
@@ -1684,11 +1685,7 @@ Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, 
void *buf, size_t size,
 remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size

[Lldb-commits] [lldb] [lldb/linux] Make truncated reads work (PR #106532)

2024-09-02 Thread Pavel Labath via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Support partial memory reads on windows (PR #106981)

2024-09-02 Thread Pavel Labath via lldb-commits

https://github.com/labath created 
https://github.com/llvm/llvm-project/pull/106981

ReadProcessMemory will not perform the read if part of the memory is unreadable 
(and even though the API has a `number_of_bytes_read` argument). To make this 
work, I explicitly inspect the memory region being read and only read the 
accessible part.

>From 6287b6daa6a1aecff4f4cd0ce786bda15010f637 Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Thu, 29 Aug 2024 13:56:07 +0200
Subject: [PATCH] [lldb] Support partial memory reads on windows

ReadProcessMemory will not perform the read if part of the memory is
unreadable. To make this work, I explicitly inspect the memory region
being read and only read the accessible part.
---
 .../Windows/Common/ProcessDebugger.cpp| 25 ++-
 .../memory/holes/TestMemoryHoles.py   |  1 -
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
index 04c7c0f826039d..9fc8077851d257 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
@@ -276,16 +276,29 @@ Status ProcessDebugger::ReadMemory(lldb::addr_t vm_addr, 
void *buf, size_t size,
   LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
vm_addr);
 
-  HostProcess process = m_session_data->m_debugger->GetProcess();
+  lldb::process_t handle = m_session_data->m_debugger->GetProcess()
+   .GetNativeProcess()
+   .GetSystemHandle();
   void *addr = reinterpret_cast(vm_addr);
   SIZE_T num_of_bytes_read = 0;
-  if (!::ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
-   buf, size, &num_of_bytes_read)) {
-error = Status(GetLastError(), eErrorTypeWin32);
-LLDB_LOG(log, "reading failed with error: {0}", error);
-  } else {
+  if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
+bytes_read = num_of_bytes_read;
+return Status();
+  }
+  error = Status(GetLastError(), eErrorTypeWin32);
+  MemoryRegionInfo info;
+  if (GetMemoryRegionInfo(vm_addr, info).Fail() ||
+  info.GetMapped() != MemoryRegionInfo::OptionalBool::eYes)
+return error;
+  size = info.GetRange().GetRangeEnd() - vm_addr;
+  LLDB_LOG(log, "retrying the read with size {0:x}", size);
+  if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
+LLDB_LOG(log, "success: read {0:x} bytes", num_of_bytes_read);
 bytes_read = num_of_bytes_read;
+return Status();
   }
+  error = Status(GetLastError(), eErrorTypeWin32);
+  LLDB_LOG(log, "error: {0}", error);
   return error;
 }
 
diff --git a/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py 
b/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
index 6ecb25b2e4db28..1c2c90d483ea3f 100644
--- a/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
+++ b/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
@@ -50,7 +50,6 @@ def _prepare_inferior(self):
 ]
 self.assertEqual(len(self.positions), 5)
 
-@expectedFailureWindows
 def test_memory_read(self):
 self._prepare_inferior()
 

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


[Lldb-commits] [lldb] [lldb] Support partial memory reads on windows (PR #106981)

2024-09-02 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Pavel Labath (labath)


Changes

ReadProcessMemory will not perform the read if part of the memory is unreadable 
(and even though the API has a `number_of_bytes_read` argument). To make this 
work, I explicitly inspect the memory region being read and only read the 
accessible part.

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


2 Files Affected:

- (modified) lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp 
(+19-6) 
- (modified) lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py (-1) 


``diff
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
index 04c7c0f826039d..9fc8077851d257 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp
@@ -276,16 +276,29 @@ Status ProcessDebugger::ReadMemory(lldb::addr_t vm_addr, 
void *buf, size_t size,
   LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
vm_addr);
 
-  HostProcess process = m_session_data->m_debugger->GetProcess();
+  lldb::process_t handle = m_session_data->m_debugger->GetProcess()
+   .GetNativeProcess()
+   .GetSystemHandle();
   void *addr = reinterpret_cast(vm_addr);
   SIZE_T num_of_bytes_read = 0;
-  if (!::ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
-   buf, size, &num_of_bytes_read)) {
-error = Status(GetLastError(), eErrorTypeWin32);
-LLDB_LOG(log, "reading failed with error: {0}", error);
-  } else {
+  if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
+bytes_read = num_of_bytes_read;
+return Status();
+  }
+  error = Status(GetLastError(), eErrorTypeWin32);
+  MemoryRegionInfo info;
+  if (GetMemoryRegionInfo(vm_addr, info).Fail() ||
+  info.GetMapped() != MemoryRegionInfo::OptionalBool::eYes)
+return error;
+  size = info.GetRange().GetRangeEnd() - vm_addr;
+  LLDB_LOG(log, "retrying the read with size {0:x}", size);
+  if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
+LLDB_LOG(log, "success: read {0:x} bytes", num_of_bytes_read);
 bytes_read = num_of_bytes_read;
+return Status();
   }
+  error = Status(GetLastError(), eErrorTypeWin32);
+  LLDB_LOG(log, "error: {0}", error);
   return error;
 }
 
diff --git a/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py 
b/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
index 6ecb25b2e4db28..1c2c90d483ea3f 100644
--- a/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
+++ b/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
@@ -50,7 +50,6 @@ def _prepare_inferior(self):
 ]
 self.assertEqual(len(self.positions), 5)
 
-@expectedFailureWindows
 def test_memory_read(self):
 self._prepare_inferior()
 

``




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


[Lldb-commits] [lldb] [lldb][NFC] Move few static helpers to the class Socket and make them public (PR #106640)

2024-09-02 Thread Pavel Labath via lldb-commits

labath wrote:

Moving the common API (deduplicating) into the `Socket` class is fine. Making 
it public is not. There shouldn't be a reason to make e.g. `GetLastError` 
public, because noone should be making raw socket calls.

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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits

https://github.com/dzhidzhoev updated 
https://github.com/llvm/llvm-project/pull/102185

>From e40ca68a934d0595ebc6c07010a4f6a814fa026f Mon Sep 17 00:00:00 2001
From: Vladislav Dzhidzhoev 
Date: Sat, 27 Jul 2024 02:39:32 +0200
Subject: [PATCH 01/11] [lldb][test] Improve toolchain detection in
 Makefile.rules

This fix is based on a problem with cxx_compiler and cxx_linker macros
on Windows.
There was an issue with compiler detection in paths containing "icc". In
such case, Makefile.rules thought it was provided with icc compiler.

To solve that, utilities detection has been rewritten in Python.
The last element of compiler's path is separated, taking into account
platform path delimiter, and compiler type is extracted, with regard
of possible cross-toolchain prefix.  Paths for additional tools,
like OBJCOPY, are initialized with tools built with LLVM if USE_LLVM_TOOLS
is on, to achieve better portability for Windows.
Quotes from paths are removed in Makefile.rules, that may be added when
arguments are passed from Python to make.
---
 .../Python/lldbsuite/test/builders/builder.py | 114 +-
 .../Python/lldbsuite/test/make/Makefile.rules | 103 +---
 .../breakpoint/breakpoint_ids/Makefile|   2 +-
 .../breakpoint/breakpoint_locations/Makefile  |   2 +-
 .../consecutive_breakpoints/Makefile  |   2 +-
 .../functionalities/breakpoint/cpp/Makefile   |   2 +-
 .../dummy_target_breakpoints/Makefile |   2 +-
 .../require_hw_breakpoints/Makefile   |   2 +-
 .../breakpoint/step_over_breakpoint/Makefile  |   2 +-
 .../thread_plan_user_breakpoint/Makefile  |   2 +-
 .../ObjCDataFormatterTestCase.py  |   4 +-
 .../TestNSDictionarySynthetic.py  |   4 +-
 .../nssetsynth/TestNSSetSynthetic.py  |   4 +-
 .../poarray/TestPrintObjectArray.py   |   4 +-
 .../functionalities/inline-stepping/Makefile  |   2 +-
 .../postmortem/minidump-new/makefile.txt  |   1 +
 .../lang/objc/orderedset/TestOrderedSet.py|   4 +-
 .../TestObjCSingleEntryDictionary.py  |   4 +-
 lldb/test/API/macosx/macCatalyst/Makefile |   1 +
 .../macCatalystAppMacOSFramework/Makefile |   1 +
 .../macosx/simulator/TestSimulatorPlatform.py |   4 +-
 .../API/python_api/frame/inlines/Makefile |   2 +-
 .../lldb-server/TestAppleSimulatorOSType.py   |   4 +-
 23 files changed, 168 insertions(+), 104 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py 
b/lldb/packages/Python/lldbsuite/test/builders/builder.py
index 4ea9a86c1d5fc9..ca91684ca065d6 100644
--- a/lldb/packages/Python/lldbsuite/test/builders/builder.py
+++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py
@@ -1,10 +1,12 @@
 import os
+import pathlib
 import platform
 import subprocess
 import sys
 import itertools
 
 import lldbsuite.test.lldbtest as lldbtest
+import lldbsuite.test.lldbplatformutil as lldbplatformutil
 import lldbsuite.test.lldbutil as lldbutil
 from lldbsuite.test import configuration
 from lldbsuite.test_event import build_exception
@@ -96,16 +98,120 @@ def getArchSpec(self, architecture):
 """
 return ["ARCH=" + architecture] if architecture else []
 
-def getCCSpec(self, compiler):
+def getToolchainSpec(self, compiler):
 """
-Helper function to return the key-value string to specify the compiler
+Helper function to return the key-value strings to specify the 
toolchain
 used for the make system.
 """
 cc = compiler if compiler else None
 if not cc and configuration.compiler:
 cc = configuration.compiler
+
 if cc:
-return ['CC="%s"' % cc]
+exe_ext = ""
+if lldbplatformutil.getHostPlatform() == "windows":
+exe_ext = ".exe"
+
+cc = cc.strip()
+cc_path = pathlib.Path(cc)
+cc = cc_path.as_posix()
+
+# We can get CC compiler string in the following formats:
+#  [] - such as 'xrun clang', 'xrun 
/usr/bin/clang' & etc
+#
+# Where  could contain the following parts:
+#   [.]   - sucn as 
'clang', 'clang.exe' ('clamg-cl.exe'?)
+#   -[.]   - such as 
'armv7-linux-gnueabi-gcc'
+#   /[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+#   /-[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+
+cc_ext = cc_path.suffix
+# Compiler name without extension
+cc_name = cc_path.stem.split(" ")[-1]
+
+# A kind of compiler (canonical name): clang, gcc, cc & etc.
+cc_type = cc_name
+# A triple prefix of compiler name: gcc
+cc_prefix = ""
+if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name:
+cc_name_parts = cc_name.split("-")
+cc_type = cc_name_parts[

[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits


@@ -96,16 +98,119 @@ def getArchSpec(self, architecture):
 """
 return ["ARCH=" + architecture] if architecture else []
 
-def getCCSpec(self, compiler):
+def getToolchainSpec(self, compiler):
 """
-Helper function to return the key-value string to specify the compiler
+Helper function to return the key-value strings to specify the 
toolchain
 used for the make system.
 """
 cc = compiler if compiler else None
 if not cc and configuration.compiler:
 cc = configuration.compiler
+
 if cc:
-return ['CC="%s"' % cc]
+exe_ext = ""
+if lldbplatformutil.getHostPlatform() == "windows":
+exe_ext = ".exe"
+
+cc = cc.strip()
+cc_path = pathlib.Path(cc)
+
+# We can get CC compiler string in the following formats:
+#  [] - such as 'xrun clang', 'xrun 
/usr/bin/clang' & etc
+#
+# Where  could contain the following parts:
+#   [.]   - sucn as 
'clang', 'clang.exe' ('clang-cl.exe'?)
+#   -[.]   - such as 
'armv7-linux-gnueabi-gcc'
+#   /[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+#   /-[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+
+cc_ext = cc_path.suffix
+# Compiler name without extension
+cc_name = cc_path.stem.split(" ")[-1]
+
+# A kind of compiler (canonical name): clang, gcc, cc & etc.
+cc_type = cc_name
+# A triple prefix of compiler name: gcc
+cc_prefix = ""
+if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name:
+cc_name_parts = cc_name.split("-")
+cc_type = cc_name_parts[-1]
+if len(cc_name_parts) > 1:
+cc_prefix = "-".join(cc_name_parts[:-1]) + "-"
+
+# A kind of C++ compiler.
+cxx_types = {
+"icc": "icpc",
+"llvm-gcc": "llvm-g++",
+"gcc": "g++",
+"cc": "c++",
+"clang": "clang++",
+}
+cxx_type = cxx_types.get(cc_type, cc_type)
+
+cc_dir = cc_path.parent
+
+def getLlvmUtil(util_name):
+llvm_tools_dir = os.getenv("LLVM_TOOLS_DIR", cc_dir)
+return os.path.join(llvm_tools_dir, util_name + exe_ext)
+
+def getToolchainUtil(util_name):
+return cc_dir / (cc_prefix + util_name + cc_ext)
+
+cxx = getToolchainUtil(cxx_type)
+
+util_names = {
+"OBJCOPY": "objcopy",
+"STRIP": "objcopy",
+"ARCHIVER": "ar",
+"DWP": "dwp",
+}
+utils = []
+
+# Note: LLVM_AR is currently required by API TestBSDArchives.py 
tests.
+# Assembly a full path to llvm-ar for given LLVM_TOOLS_DIR;

dzhidzhoev wrote:

Fixed

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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits


@@ -96,16 +98,119 @@ def getArchSpec(self, architecture):
 """
 return ["ARCH=" + architecture] if architecture else []
 
-def getCCSpec(self, compiler):
+def getToolchainSpec(self, compiler):
 """
-Helper function to return the key-value string to specify the compiler
+Helper function to return the key-value strings to specify the 
toolchain
 used for the make system.
 """
 cc = compiler if compiler else None
 if not cc and configuration.compiler:
 cc = configuration.compiler
+
 if cc:
-return ['CC="%s"' % cc]
+exe_ext = ""
+if lldbplatformutil.getHostPlatform() == "windows":
+exe_ext = ".exe"
+
+cc = cc.strip()
+cc_path = pathlib.Path(cc)
+
+# We can get CC compiler string in the following formats:
+#  [] - such as 'xrun clang', 'xrun 
/usr/bin/clang' & etc
+#
+# Where  could contain the following parts:
+#   [.]   - sucn as 
'clang', 'clang.exe' ('clang-cl.exe'?)
+#   -[.]   - such as 
'armv7-linux-gnueabi-gcc'
+#   /[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+#   /-[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+
+cc_ext = cc_path.suffix
+# Compiler name without extension
+cc_name = cc_path.stem.split(" ")[-1]
+
+# A kind of compiler (canonical name): clang, gcc, cc & etc.
+cc_type = cc_name
+# A triple prefix of compiler name: gcc
+cc_prefix = ""
+if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name:
+cc_name_parts = cc_name.split("-")
+cc_type = cc_name_parts[-1]
+if len(cc_name_parts) > 1:
+cc_prefix = "-".join(cc_name_parts[:-1]) + "-"
+
+# A kind of C++ compiler.
+cxx_types = {
+"icc": "icpc",
+"llvm-gcc": "llvm-g++",
+"gcc": "g++",
+"cc": "c++",
+"clang": "clang++",
+}
+cxx_type = cxx_types.get(cc_type, cc_type)
+
+cc_dir = cc_path.parent
+
+def getLlvmUtil(util_name):
+llvm_tools_dir = os.getenv("LLVM_TOOLS_DIR", cc_dir)
+return os.path.join(llvm_tools_dir, util_name + exe_ext)
+
+def getToolchainUtil(util_name):
+return cc_dir / (cc_prefix + util_name + cc_ext)
+
+cxx = getToolchainUtil(cxx_type)
+
+util_names = {
+"OBJCOPY": "objcopy",
+"STRIP": "objcopy",

dzhidzhoev wrote:

Sorry, it was just a copy-paste typo.

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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits


@@ -96,16 +98,119 @@ def getArchSpec(self, architecture):
 """
 return ["ARCH=" + architecture] if architecture else []
 
-def getCCSpec(self, compiler):
+def getToolchainSpec(self, compiler):
 """
-Helper function to return the key-value string to specify the compiler
+Helper function to return the key-value strings to specify the 
toolchain
 used for the make system.
 """
 cc = compiler if compiler else None
 if not cc and configuration.compiler:
 cc = configuration.compiler
+
 if cc:

dzhidzhoev wrote:

Done.

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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits


@@ -213,7 +229,7 @@ endif
 LIMIT_DEBUG_INFO_FLAGS =
 NO_LIMIT_DEBUG_INFO_FLAGS =
 MODULE_DEBUG_INFO_FLAGS =
-ifneq (,$(findstring clang,$(CC)))
+ifeq ($(CCC), clang)

dzhidzhoev wrote:

Renamed it

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


[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)

2024-09-02 Thread via lldb-commits

https://github.com/Da-Viper updated 
https://github.com/llvm/llvm-project/pull/106919

>From d2bddca1753b4c960895f51d7eb80b6efa7dc986 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka 
Date: Sun, 1 Sep 2024 17:26:11 +0100
Subject: [PATCH] [lldb-dap] Make environment option an object

---
 .../tools/lldb-dap/launch/TestDAP_launch.py   |  4 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 40 ---
 lldb/tools/lldb-dap/JSONUtils.h   | 22 ++
 lldb/tools/lldb-dap/README.md |  5 ++-
 lldb/tools/lldb-dap/lldb-dap.cpp  |  8 +++-
 lldb/tools/lldb-dap/package.json  | 11 +++--
 6 files changed, 77 insertions(+), 13 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py 
b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index a16f2da3c4df71..6b9993a2548b8d 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -229,7 +229,7 @@ def test_environment(self):
 Tests launch of a simple program with environment variables
 """
 program = self.getBuildArtifact("a.out")
-env = ["NO_VALUE", "WITH_VALUE=BAR", "EMPTY_VALUE=", "SPACE=Hello 
World"]
+env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": 
"Hello World"}
 self.build_and_launch(program, env=env)
 self.continue_to_exit()
 
@@ -242,7 +242,7 @@ def test_environment(self):
 lines.pop(0)
 # Make sure each environment variable in "env" is actually set in the
 # program environment that was printed to STDOUT
-for var in env:
+for var in env.keys():
 found = False
 for program_var in lines:
 if var in program_var:
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 7338e7cf41eb03..29b3ad490af0b6 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -136,6 +136,31 @@ std::vector GetStrings(const 
llvm::json::Object *obj,
   return strs;
 }
 
+std::unordered_map
+GetStringMap(const llvm::json::Object &obj, llvm::StringRef key) {
+  std::unordered_map strs;
+  const auto *const json_object = obj.getObject(key);
+  if (!json_object)
+return strs;
+
+  for (const auto &[key, value] : *json_object) {
+switch (value.kind()) {
+case llvm::json::Value::String:
+  strs.emplace(key.str(), value.getAsString()->str());
+  break;
+case llvm::json::Value::Number:
+case llvm::json::Value::Boolean:
+  strs.emplace(key.str(), llvm::to_string(value));
+  break;
+case llvm::json::Value::Null:
+case llvm::json::Value::Object:
+case llvm::json::Value::Array:
+  break;
+}
+  }
+  return strs;
+}
+
 static bool IsClassStructOrUnionType(lldb::SBType t) {
   return (t.GetTypeClass() & (lldb::eTypeClassUnion | lldb::eTypeClassStruct |
   lldb::eTypeClassArray)) != 0;
@@ -1370,13 +1395,16 @@ CreateRunInTerminalReverseRequest(const 
llvm::json::Object &launch_request,
   if (!cwd.empty())
 run_in_terminal_args.try_emplace("cwd", cwd);
 
-  // We need to convert the input list of environments variables into a
-  // dictionary
-  std::vector envs = GetStrings(launch_request_arguments, "env");
+  std::unordered_map envMap =
+  GetStringMap(*launch_request_arguments, "env");
   llvm::json::Object environment;
-  for (const std::string &env : envs) {
-size_t index = env.find('=');
-environment.try_emplace(env.substr(0, index), env.substr(index + 1));
+  for (const auto &[key, value] : envMap) {
+if (key.empty())
+  g_dap.SendOutput(OutputType::Stderr,
+   "empty environment variable for value: \"" + value +
+   '\"');
+else
+  environment.try_emplace(key, value);
   }
   run_in_terminal_args.try_emplace("env",
llvm::json::Value(std::move(environment)));
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index b6356630b72682..60d5db06560657 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -16,6 +16,7 @@
 #include "llvm/Support/JSON.h"
 #include 
 #include 
+#include 
 
 namespace lldb_dap {
 
@@ -152,6 +153,27 @@ bool ObjectContainsKey(const llvm::json::Object &obj, 
llvm::StringRef key);
 std::vector GetStrings(const llvm::json::Object *obj,
 llvm::StringRef key);
 
+/// Extract an object of key value strings for the specified key from an 
object.
+///
+/// String values in the object will be extracted without any quotes
+/// around them. Numbers and Booleans will be converted into
+/// strings. Any NULL, array or objects values in the array will be
+/// ignored.
+///
+/// \param[in] obj
+/// A JSON object that we will attempt to extract the array from
+///
+/// \param[in] key
+/// The key to use when extracti

[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)

2024-09-02 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 
87d904871fe96a01dfa1f254ca2a7639de67960c...d2bddca1753b4c960895f51d7eb80b6efa7dc986
 lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
``





View the diff from darker here.


``diff
--- TestDAP_launch.py   2024-09-02 13:10:06.00 +
+++ TestDAP_launch.py   2024-09-02 13:15:48.484600 +
@@ -227,11 +227,16 @@
 def test_environment(self):
 """
 Tests launch of a simple program with environment variables
 """
 program = self.getBuildArtifact("a.out")
-env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": 
"Hello World"}
+env = {
+"NO_VALUE": "",
+"WITH_VALUE": "BAR",
+"EMPTY_VALUE": "",
+"SPACE": "Hello World",
+}
 self.build_and_launch(program, env=env)
 self.continue_to_exit()
 
 # Now get the STDOUT and verify our arguments got passed correctly
 output = self.get_stdout()

``




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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits


@@ -96,16 +98,120 @@ def getArchSpec(self, architecture):
 """
 return ["ARCH=" + architecture] if architecture else []
 
-def getCCSpec(self, compiler):
+def getToolchainSpec(self, compiler):
 """
-Helper function to return the key-value string to specify the compiler
+Helper function to return the key-value strings to specify the 
toolchain
 used for the make system.
 """
 cc = compiler if compiler else None
 if not cc and configuration.compiler:
 cc = configuration.compiler
+
 if cc:
-return ['CC="%s"' % cc]
+exe_ext = ""
+if lldbplatformutil.getHostPlatform() == "windows":
+exe_ext = ".exe"
+
+cc = cc.strip()
+cc_path = pathlib.Path(cc)
+cc = cc_path.as_posix()
+
+# We can get CC compiler string in the following formats:
+#  [] - such as 'xrun clang', 'xrun 
/usr/bin/clang' & etc
+#
+# Where  could contain the following parts:
+#   [.]   - sucn as 
'clang', 'clang.exe' ('clamg-cl.exe'?)
+#   -[.]   - such as 
'armv7-linux-gnueabi-gcc'
+#   /[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+#   /-[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+
+cc_ext = cc_path.suffix
+# Compiler name without extension
+cc_name = cc_path.stem.split(" ")[-1]
+
+# A kind of compiler (canonical name): clang, gcc, cc & etc.
+cc_type = cc_name
+# A triple prefix of compiler name: gcc
+cc_prefix = ""
+if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name:
+cc_name_parts = cc_name.split("-")
+cc_type = cc_name_parts[-1]
+if len(cc_name_parts) > 1:
+cc_prefix = "-".join(cc_name_parts[:-1]) + "-"
+
+# A kind of C++ compiler.
+cxx_types = {
+"icc": "icpc",
+"llvm-gcc": "llvm-g++",
+"gcc": "g++",
+"cc": "c++",
+"clang": "clang++",
+}
+cxx_type = cxx_types.get(cc_type, cc_type)
+
+cc_dir = cc_path.parent
+
+def getLlvmUtil(util_name):
+llvm_tools_dir = os.getenv("LLVM_TOOLS_DIR", cc_dir.as_posix())
+return llvm_tools_dir + "/" + util_name + exe_ext
+
+def getToolchainUtil(util_name):
+return (cc_dir / (cc_prefix + util_name + cc_ext)).as_posix()
+
+cxx = getToolchainUtil(cxx_type)
+
+util_names = {
+"OBJCOPY": "objcopy",
+"STRIP": "objcopy",
+"ARCHIVER": "ar",
+"DWP": "dwp",
+}
+utils = []
+
+# Note: LLVM_AR is currently required by API TestBSDArchives.py 
tests.
+# Assembly a full path to llvm-ar for given LLVM_TOOLS_DIR;
+# otherwise assume we have llvm-ar at the same place where is CC 
specified.
+if not os.getenv("LLVM_AR"):
+llvm_ar = getLlvmUtil("llvm-ar")
+utils.extend(['LLVM_AR="%s"' % llvm_ar])
+
+if not lldbplatformutil.platformIsDarwin():
+if os.getenv("USE_LLVM_TOOLS"):

dzhidzhoev wrote:

I got rid of environment variable usage and used dotest.py param instead.

The flag `--use-llvm-tools` flag is added to force usage of LLVM tools passed 
with `--llvm-tools-dir` instead of compiler-provided tools.
We use it while running API tests on Windows x86-host/Ubuntu AArch64-target 
combination with cl.exe. This flag enables switching to the "local" tools usage 
without relying on the PATH/compiler path for utilities lookup, so as not to 
rely on an external toolchain while having all necessary tools built together 
with lldb.

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Pavel Labath via lldb-commits

labath wrote:

> @labath
> 
> > Basically, keep the socket code inside the socket class, but make it 
> > asynchronous. This way you can listen for as many sockets (and other 
> > things) as you like. It shouldn't be necessary to do the socket handling 
> > stuff externally.
> > I haven't looked into exactly how this would fit into the Acceptor class in 
> > lldb-server, but my preferred solutions would be:
> > 
> > * delete it (or at least significantly slim down it's functionality -- it's 
> > a very thin wrapper over the Socket class, and probably only exists due to 
> > historic reasons)
> > * make it callback-based as well
> > 
> > I don't like the idea of making Acceptor responsible for multiple ports for 
> > the same reason I did not want to do that for TCPSocket -- it's complicated 
> > and inflexible.
> 
> I don't see any profit of this change. Using an extrernal MainLoop we can 
> break the blocking Accept() from an other thread. But we can break it making 
> a dummy connection too.

This wasn't my main motivation, but now that you mention it, I actually think 
this may be reason enough to do this. Using a dummy connection to break out of 
a blocking accept is.. clever, but I wouldn't consider it a good practice. I 
also think we have other places in lldb that could use the ability to interrupt 
a blocking operation, and I wouldn't want to start adding dummy connections 
there as well. (And I'm pretty sure I can come up with a (contrived) scenario 
where that dummy connect will actually fail.)

> 
> The main reason to change TCPSocket was to be able to wait for multiple 
> connections from different ports in the same blocking Accept() in the single 
> thread. 

In a single thread -- yes. In the same blocking accept -- not really, at least 
not for me.

> Currently #104238 contains the best implementation of Acceptor.cpp w/o 
> changing TCPSocket.

I guess we'll have to agree to disagree on that.

> 
> sock_cb parameter is useles here because it will be always the same.

I'll have to disagree with that. The reason we have two ports is because we 
want to use them for different things. One of them will be launching a platform 
instance, the other a gdbserver instance. So, even though the logic will be 
roughly similar (both are spawning a new process) each will be doing something 
slightly different. With two sockets, you can pass one callback to the 
gdbserver socket and a different one to the platform socket.

But even if the callback was the same every time, I'd still think this is a 
good separation between "how to accept a connection" and "what to do with the 
accepted connection".

> TCPSocket::m_listen_sockets is still here and it is still inaccesible 
> externally. The method Listen() which initializes m_listen_sockets is 
> unchanged.

Yes, and there's no reason to change that. (I'd definitely like to change that, 
but that's not necessary here)

> A callback may be useful (in theory) in Listen() to add a custom listen 
> sockets to m_listen_sockets. Probably it is better to just initialize an own 
> listen_sockets and just provide it to TCPSocket. But where this code will be 
> placed? Acceptor.cpp, lldb-platform.cpp?

Now I'm just thinking we haven't understood each other about how this could be 
used. There's no reason to pass additional sockets, because there's no reason 
to have a unified socket list (well.. there is, but it's already present in the 
main loop). To listen on two (or however many) ports, you just create however 
many TCPSocket instances you want, and then do a mainloop.Run(). And yeah, I'd 
ideally place the code in lldb-platform.cpp (that's the proper place for a main 
loop).

The code would be something like:
```
MainLoop loop;
platform_socket->Accept(loop, spawn_platform_cb);
server_socket->Accept(loop, spawn_gdbserver_cb);
loop.Run();
```
> 
> If you want to delete Acceptor, the best approach is the following:
I do, but it's not my primary goal. Definitely not at the cost of putting a 
MainLoop member inside TCPSocket.

If it turns out to be easier, I'd be fine with turning `platform_socket` and 
`server_socket` instances from the above snippet into `Acceptor`s.


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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits

https://github.com/dzhidzhoev updated 
https://github.com/llvm/llvm-project/pull/102185

>From e40ca68a934d0595ebc6c07010a4f6a814fa026f Mon Sep 17 00:00:00 2001
From: Vladislav Dzhidzhoev 
Date: Sat, 27 Jul 2024 02:39:32 +0200
Subject: [PATCH 01/12] [lldb][test] Improve toolchain detection in
 Makefile.rules

This fix is based on a problem with cxx_compiler and cxx_linker macros
on Windows.
There was an issue with compiler detection in paths containing "icc". In
such case, Makefile.rules thought it was provided with icc compiler.

To solve that, utilities detection has been rewritten in Python.
The last element of compiler's path is separated, taking into account
platform path delimiter, and compiler type is extracted, with regard
of possible cross-toolchain prefix.  Paths for additional tools,
like OBJCOPY, are initialized with tools built with LLVM if USE_LLVM_TOOLS
is on, to achieve better portability for Windows.
Quotes from paths are removed in Makefile.rules, that may be added when
arguments are passed from Python to make.
---
 .../Python/lldbsuite/test/builders/builder.py | 114 +-
 .../Python/lldbsuite/test/make/Makefile.rules | 103 +---
 .../breakpoint/breakpoint_ids/Makefile|   2 +-
 .../breakpoint/breakpoint_locations/Makefile  |   2 +-
 .../consecutive_breakpoints/Makefile  |   2 +-
 .../functionalities/breakpoint/cpp/Makefile   |   2 +-
 .../dummy_target_breakpoints/Makefile |   2 +-
 .../require_hw_breakpoints/Makefile   |   2 +-
 .../breakpoint/step_over_breakpoint/Makefile  |   2 +-
 .../thread_plan_user_breakpoint/Makefile  |   2 +-
 .../ObjCDataFormatterTestCase.py  |   4 +-
 .../TestNSDictionarySynthetic.py  |   4 +-
 .../nssetsynth/TestNSSetSynthetic.py  |   4 +-
 .../poarray/TestPrintObjectArray.py   |   4 +-
 .../functionalities/inline-stepping/Makefile  |   2 +-
 .../postmortem/minidump-new/makefile.txt  |   1 +
 .../lang/objc/orderedset/TestOrderedSet.py|   4 +-
 .../TestObjCSingleEntryDictionary.py  |   4 +-
 lldb/test/API/macosx/macCatalyst/Makefile |   1 +
 .../macCatalystAppMacOSFramework/Makefile |   1 +
 .../macosx/simulator/TestSimulatorPlatform.py |   4 +-
 .../API/python_api/frame/inlines/Makefile |   2 +-
 .../lldb-server/TestAppleSimulatorOSType.py   |   4 +-
 23 files changed, 168 insertions(+), 104 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py 
b/lldb/packages/Python/lldbsuite/test/builders/builder.py
index 4ea9a86c1d5fc9..ca91684ca065d6 100644
--- a/lldb/packages/Python/lldbsuite/test/builders/builder.py
+++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py
@@ -1,10 +1,12 @@
 import os
+import pathlib
 import platform
 import subprocess
 import sys
 import itertools
 
 import lldbsuite.test.lldbtest as lldbtest
+import lldbsuite.test.lldbplatformutil as lldbplatformutil
 import lldbsuite.test.lldbutil as lldbutil
 from lldbsuite.test import configuration
 from lldbsuite.test_event import build_exception
@@ -96,16 +98,120 @@ def getArchSpec(self, architecture):
 """
 return ["ARCH=" + architecture] if architecture else []
 
-def getCCSpec(self, compiler):
+def getToolchainSpec(self, compiler):
 """
-Helper function to return the key-value string to specify the compiler
+Helper function to return the key-value strings to specify the 
toolchain
 used for the make system.
 """
 cc = compiler if compiler else None
 if not cc and configuration.compiler:
 cc = configuration.compiler
+
 if cc:
-return ['CC="%s"' % cc]
+exe_ext = ""
+if lldbplatformutil.getHostPlatform() == "windows":
+exe_ext = ".exe"
+
+cc = cc.strip()
+cc_path = pathlib.Path(cc)
+cc = cc_path.as_posix()
+
+# We can get CC compiler string in the following formats:
+#  [] - such as 'xrun clang', 'xrun 
/usr/bin/clang' & etc
+#
+# Where  could contain the following parts:
+#   [.]   - sucn as 
'clang', 'clang.exe' ('clamg-cl.exe'?)
+#   -[.]   - such as 
'armv7-linux-gnueabi-gcc'
+#   /[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+#   /-[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+
+cc_ext = cc_path.suffix
+# Compiler name without extension
+cc_name = cc_path.stem.split(" ")[-1]
+
+# A kind of compiler (canonical name): clang, gcc, cc & etc.
+cc_type = cc_name
+# A triple prefix of compiler name: gcc
+cc_prefix = ""
+if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name:
+cc_name_parts = cc_name.split("-")
+cc_type = cc_name_parts[

[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)

2024-09-02 Thread via lldb-commits

https://github.com/Da-Viper updated 
https://github.com/llvm/llvm-project/pull/106919

>From d2bddca1753b4c960895f51d7eb80b6efa7dc986 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka 
Date: Sun, 1 Sep 2024 17:26:11 +0100
Subject: [PATCH 1/2] [lldb-dap] Make environment option an object

---
 .../tools/lldb-dap/launch/TestDAP_launch.py   |  4 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 40 ---
 lldb/tools/lldb-dap/JSONUtils.h   | 22 ++
 lldb/tools/lldb-dap/README.md |  5 ++-
 lldb/tools/lldb-dap/lldb-dap.cpp  |  8 +++-
 lldb/tools/lldb-dap/package.json  | 11 +++--
 6 files changed, 77 insertions(+), 13 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py 
b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index a16f2da3c4df71..6b9993a2548b8d 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -229,7 +229,7 @@ def test_environment(self):
 Tests launch of a simple program with environment variables
 """
 program = self.getBuildArtifact("a.out")
-env = ["NO_VALUE", "WITH_VALUE=BAR", "EMPTY_VALUE=", "SPACE=Hello 
World"]
+env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": 
"Hello World"}
 self.build_and_launch(program, env=env)
 self.continue_to_exit()
 
@@ -242,7 +242,7 @@ def test_environment(self):
 lines.pop(0)
 # Make sure each environment variable in "env" is actually set in the
 # program environment that was printed to STDOUT
-for var in env:
+for var in env.keys():
 found = False
 for program_var in lines:
 if var in program_var:
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 7338e7cf41eb03..29b3ad490af0b6 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -136,6 +136,31 @@ std::vector GetStrings(const 
llvm::json::Object *obj,
   return strs;
 }
 
+std::unordered_map
+GetStringMap(const llvm::json::Object &obj, llvm::StringRef key) {
+  std::unordered_map strs;
+  const auto *const json_object = obj.getObject(key);
+  if (!json_object)
+return strs;
+
+  for (const auto &[key, value] : *json_object) {
+switch (value.kind()) {
+case llvm::json::Value::String:
+  strs.emplace(key.str(), value.getAsString()->str());
+  break;
+case llvm::json::Value::Number:
+case llvm::json::Value::Boolean:
+  strs.emplace(key.str(), llvm::to_string(value));
+  break;
+case llvm::json::Value::Null:
+case llvm::json::Value::Object:
+case llvm::json::Value::Array:
+  break;
+}
+  }
+  return strs;
+}
+
 static bool IsClassStructOrUnionType(lldb::SBType t) {
   return (t.GetTypeClass() & (lldb::eTypeClassUnion | lldb::eTypeClassStruct |
   lldb::eTypeClassArray)) != 0;
@@ -1370,13 +1395,16 @@ CreateRunInTerminalReverseRequest(const 
llvm::json::Object &launch_request,
   if (!cwd.empty())
 run_in_terminal_args.try_emplace("cwd", cwd);
 
-  // We need to convert the input list of environments variables into a
-  // dictionary
-  std::vector envs = GetStrings(launch_request_arguments, "env");
+  std::unordered_map envMap =
+  GetStringMap(*launch_request_arguments, "env");
   llvm::json::Object environment;
-  for (const std::string &env : envs) {
-size_t index = env.find('=');
-environment.try_emplace(env.substr(0, index), env.substr(index + 1));
+  for (const auto &[key, value] : envMap) {
+if (key.empty())
+  g_dap.SendOutput(OutputType::Stderr,
+   "empty environment variable for value: \"" + value +
+   '\"');
+else
+  environment.try_emplace(key, value);
   }
   run_in_terminal_args.try_emplace("env",
llvm::json::Value(std::move(environment)));
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index b6356630b72682..60d5db06560657 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -16,6 +16,7 @@
 #include "llvm/Support/JSON.h"
 #include 
 #include 
+#include 
 
 namespace lldb_dap {
 
@@ -152,6 +153,27 @@ bool ObjectContainsKey(const llvm::json::Object &obj, 
llvm::StringRef key);
 std::vector GetStrings(const llvm::json::Object *obj,
 llvm::StringRef key);
 
+/// Extract an object of key value strings for the specified key from an 
object.
+///
+/// String values in the object will be extracted without any quotes
+/// around them. Numbers and Booleans will be converted into
+/// strings. Any NULL, array or objects values in the array will be
+/// ignored.
+///
+/// \param[in] obj
+/// A JSON object that we will attempt to extract the array from
+///
+/// \param[in] key
+/// The key to use when extr

[Lldb-commits] [lldb] [lldb][NFC] Move few static helpers to the class Socket and make them public (PR #106640)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

slydiman wrote:

It is necesary for Acceptor in #104238.
90% of this Acceptor contains the code from TCPSocket and TCPSocket has only 
cosmetics changes.

m_listen_sockets used in Accept() must be initialized and stored somewhere.
I think the best place for m_listen_sockets is TCPSocket and I proposed #104797 
(note it is better to use `Status TCPSocket::Listen(llvm::StringRef name, int 
backlog, std::set * extra_ports = nullptr)` instead to keep the 
connection string unchanged).

> noone should be making raw socket calls.

Ok, but m_listen_sockets contains native socket. So everything must be inside 
TCPSocket w/o any callbacks.
Then let's complete #104797.

Or how else do you propose to initialize m_listen_sockets to accept connections 
from 2 ports?

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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits

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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Vladislav Dzhidzhoev via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Fix and speedup the `memory find` command (PR #104193)

2024-09-02 Thread Pavel Labath via lldb-commits

https://github.com/labath updated 
https://github.com/llvm/llvm-project/pull/104193

>From ecd84ae96fd59eeb4a2bb47d80980d861dc042d1 Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 14 Aug 2024 19:58:27 +0200
Subject: [PATCH] [lldb] Fix and speedup the `memory find` command

This patch fixes an issue where the `memory find` command would
effectively stop searching after encountering a memory read error (which
could happen due to unreadable memory), without giving any indication
that it has done so (it would just print it could not find the pattern).

To make matters worse, it would not terminate after encountering this
error, but rather proceed to slowly increment the address pointer, which
meant that searching a large region could take a very long time (and
give the appearance that lldb is actually searching for the thing).

The patch fixes this first problem (*) by detecting read errors and
skipping over (using GetMemoryRegionInfo) the unreadable parts of memory
and resuming the search after them. It also reads the memory in bulk (up
to 1MB), which speeds up the search significantly (up to 6x for live
processes, 18x for core files).

(*) The fix does not work on windows yet, because the ReadMemory API
does not return partial results (like it does for other systems). I'm
preparing a separate patch to deal with that.
---
 lldb/source/Target/Process.cpp| 69 ++-
 .../memory/holes/TestMemoryHoles.py   | 12 
 2 files changed, 47 insertions(+), 34 deletions(-)

diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index ae64f6f261bad7..6c5c5162e24686 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -114,33 +114,6 @@ class ProcessOptionValueProperties
   }
 };
 
-class ProcessMemoryIterator {
-public:
-  ProcessMemoryIterator(Process &process, lldb::addr_t base)
-  : m_process(process), m_base_addr(base) {}
-
-  bool IsValid() { return m_is_valid; }
-
-  uint8_t operator[](lldb::addr_t offset) {
-if (!IsValid())
-  return 0;
-
-uint8_t retval = 0;
-Status error;
-if (0 == m_process.ReadMemory(m_base_addr + offset, &retval, 1, error)) {
-  m_is_valid = false;
-  return 0;
-}
-
-return retval;
-  }
-
-private:
-  Process &m_process;
-  const lldb::addr_t m_base_addr;
-  bool m_is_valid = true;
-};
-
 static constexpr OptionEnumValueElement g_follow_fork_mode_values[] = {
 {
 eFollowParent,
@@ -3379,21 +3352,49 @@ lldb::addr_t Process::FindInMemory(lldb::addr_t low, 
lldb::addr_t high,
   if (region_size < size)
 return LLDB_INVALID_ADDRESS;
 
+  // See "Boyer-Moore string search algorithm".
   std::vector bad_char_heuristic(256, size);
-  ProcessMemoryIterator iterator(*this, low);
-
   for (size_t idx = 0; idx < size - 1; idx++) {
 decltype(bad_char_heuristic)::size_type bcu_idx = buf[idx];
 bad_char_heuristic[bcu_idx] = size - idx - 1;
   }
-  for (size_t s = 0; s <= (region_size - size);) {
+
+  // Memory we're currently searching through.
+  llvm::SmallVector mem;
+  // Position of the memory buffer.
+  addr_t mem_pos = low;
+  // Maximum number of bytes read (and buffered). We need to read at least
+  // `size` bytes for a successful match.
+  const size_t max_read_size = std::max(size, 0x1);
+
+  for (addr_t cur_addr = low; cur_addr <= (high - size);) {
+if (cur_addr + size > mem_pos + mem.size()) {
+  // We need to read more data. We don't attempt to reuse the data we've
+  // already read (up to `size-1` bytes from `cur_addr` to
+  // `mem_pos+mem.size()`).  This is fine for patterns much smaller than
+  // max_read_size. For very
+  // long patterns we may need to do something more elaborate.
+  mem.resize_for_overwrite(max_read_size);
+  Status error;
+  mem.resize(ReadMemory(cur_addr, mem.data(),
+std::min(mem.size(), high - cur_addr), error));
+  mem_pos = cur_addr;
+  if (size > mem.size()) {
+// We didn't read enough data. Skip to the next memory region.
+MemoryRegionInfo info;
+error = GetMemoryRegionInfo(mem_pos + mem.size(), info);
+if (error.Fail())
+  break;
+cur_addr = info.GetRange().GetRangeEnd();
+continue;
+  }
+}
 int64_t j = size - 1;
-while (j >= 0 && buf[j] == iterator[s + j])
+while (j >= 0 && buf[j] == mem[cur_addr + j - mem_pos])
   j--;
 if (j < 0)
-  return low + s;
-else
-  s += bad_char_heuristic[iterator[s + size - 1]];
+  return cur_addr; // We have a match.
+cur_addr += bad_char_heuristic[mem[cur_addr + size - 1 - mem_pos]];
   }
 
   return LLDB_INVALID_ADDRESS;
diff --git a/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py 
b/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
index 6ecb25b2e4db28..bb19eceba6b546 100644
--- a/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
+++ b/lldb/test/API/

[Lldb-commits] [lldb] [lldb] Fix and speedup the `memory find` command (PR #104193)

2024-09-02 Thread Pavel Labath via lldb-commits

labath wrote:

Rebased on top of #106532. The test should pass reliably now (the windows part 
depends on #106981).

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


[Lldb-commits] [lldb] [lldb] Fix and speedup the `memory find` command (PR #104193)

2024-09-02 Thread Pavel Labath via lldb-commits

https://github.com/labath updated 
https://github.com/llvm/llvm-project/pull/104193

>From ecd84ae96fd59eeb4a2bb47d80980d861dc042d1 Mon Sep 17 00:00:00 2001
From: Pavel Labath 
Date: Wed, 14 Aug 2024 19:58:27 +0200
Subject: [PATCH 1/2] [lldb] Fix and speedup the `memory find` command

This patch fixes an issue where the `memory find` command would
effectively stop searching after encountering a memory read error (which
could happen due to unreadable memory), without giving any indication
that it has done so (it would just print it could not find the pattern).

To make matters worse, it would not terminate after encountering this
error, but rather proceed to slowly increment the address pointer, which
meant that searching a large region could take a very long time (and
give the appearance that lldb is actually searching for the thing).

The patch fixes this first problem (*) by detecting read errors and
skipping over (using GetMemoryRegionInfo) the unreadable parts of memory
and resuming the search after them. It also reads the memory in bulk (up
to 1MB), which speeds up the search significantly (up to 6x for live
processes, 18x for core files).

(*) The fix does not work on windows yet, because the ReadMemory API
does not return partial results (like it does for other systems). I'm
preparing a separate patch to deal with that.
---
 lldb/source/Target/Process.cpp| 69 ++-
 .../memory/holes/TestMemoryHoles.py   | 12 
 2 files changed, 47 insertions(+), 34 deletions(-)

diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index ae64f6f261bad7..6c5c5162e24686 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -114,33 +114,6 @@ class ProcessOptionValueProperties
   }
 };
 
-class ProcessMemoryIterator {
-public:
-  ProcessMemoryIterator(Process &process, lldb::addr_t base)
-  : m_process(process), m_base_addr(base) {}
-
-  bool IsValid() { return m_is_valid; }
-
-  uint8_t operator[](lldb::addr_t offset) {
-if (!IsValid())
-  return 0;
-
-uint8_t retval = 0;
-Status error;
-if (0 == m_process.ReadMemory(m_base_addr + offset, &retval, 1, error)) {
-  m_is_valid = false;
-  return 0;
-}
-
-return retval;
-  }
-
-private:
-  Process &m_process;
-  const lldb::addr_t m_base_addr;
-  bool m_is_valid = true;
-};
-
 static constexpr OptionEnumValueElement g_follow_fork_mode_values[] = {
 {
 eFollowParent,
@@ -3379,21 +3352,49 @@ lldb::addr_t Process::FindInMemory(lldb::addr_t low, 
lldb::addr_t high,
   if (region_size < size)
 return LLDB_INVALID_ADDRESS;
 
+  // See "Boyer-Moore string search algorithm".
   std::vector bad_char_heuristic(256, size);
-  ProcessMemoryIterator iterator(*this, low);
-
   for (size_t idx = 0; idx < size - 1; idx++) {
 decltype(bad_char_heuristic)::size_type bcu_idx = buf[idx];
 bad_char_heuristic[bcu_idx] = size - idx - 1;
   }
-  for (size_t s = 0; s <= (region_size - size);) {
+
+  // Memory we're currently searching through.
+  llvm::SmallVector mem;
+  // Position of the memory buffer.
+  addr_t mem_pos = low;
+  // Maximum number of bytes read (and buffered). We need to read at least
+  // `size` bytes for a successful match.
+  const size_t max_read_size = std::max(size, 0x1);
+
+  for (addr_t cur_addr = low; cur_addr <= (high - size);) {
+if (cur_addr + size > mem_pos + mem.size()) {
+  // We need to read more data. We don't attempt to reuse the data we've
+  // already read (up to `size-1` bytes from `cur_addr` to
+  // `mem_pos+mem.size()`).  This is fine for patterns much smaller than
+  // max_read_size. For very
+  // long patterns we may need to do something more elaborate.
+  mem.resize_for_overwrite(max_read_size);
+  Status error;
+  mem.resize(ReadMemory(cur_addr, mem.data(),
+std::min(mem.size(), high - cur_addr), error));
+  mem_pos = cur_addr;
+  if (size > mem.size()) {
+// We didn't read enough data. Skip to the next memory region.
+MemoryRegionInfo info;
+error = GetMemoryRegionInfo(mem_pos + mem.size(), info);
+if (error.Fail())
+  break;
+cur_addr = info.GetRange().GetRangeEnd();
+continue;
+  }
+}
 int64_t j = size - 1;
-while (j >= 0 && buf[j] == iterator[s + j])
+while (j >= 0 && buf[j] == mem[cur_addr + j - mem_pos])
   j--;
 if (j < 0)
-  return low + s;
-else
-  s += bad_char_heuristic[iterator[s + size - 1]];
+  return cur_addr; // We have a match.
+cur_addr += bad_char_heuristic[mem[cur_addr + size - 1 - mem_pos]];
   }
 
   return LLDB_INVALID_ADDRESS;
diff --git a/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py 
b/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
index 6ecb25b2e4db28..bb19eceba6b546 100644
--- a/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py
+++ b/lldb/test/

[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits


@@ -95,6 +96,40 @@ TEST_P(SocketTest, TCPListen0ConnectAccept) {
 &socket_b_up);
 }
 
+TEST_P(SocketTest, TCPMainLoopAccept) {
+  const bool child_processes_inherit = false;
+  auto listen_socket_up =
+  std::make_unique(true, child_processes_inherit);
+  Status error = listen_socket_up->Listen(
+  llvm::formatv("[{0}]:0", GetParam().localhost_ip).str(), 5);

slydiman wrote:

It seems extra brackets cause the failure in case of IPv6.

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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

Ok, let's move on this way.
But fix the test.

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Support partial memory reads on windows (PR #106981)

2024-09-02 Thread David Spickett via lldb-commits


@@ -276,16 +276,29 @@ Status ProcessDebugger::ReadMemory(lldb::addr_t vm_addr, 
void *buf, size_t size,
   LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
vm_addr);
 
-  HostProcess process = m_session_data->m_debugger->GetProcess();
+  lldb::process_t handle = m_session_data->m_debugger->GetProcess()
+   .GetNativeProcess()
+   .GetSystemHandle();
   void *addr = reinterpret_cast(vm_addr);
   SIZE_T num_of_bytes_read = 0;
-  if (!::ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
-   buf, size, &num_of_bytes_read)) {
-error = Status(GetLastError(), eErrorTypeWin32);
-LLDB_LOG(log, "reading failed with error: {0}", error);
-  } else {
+  if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
+bytes_read = num_of_bytes_read;
+return Status();
+  }
+  error = Status(GetLastError(), eErrorTypeWin32);
+  MemoryRegionInfo info;
+  if (GetMemoryRegionInfo(vm_addr, info).Fail() ||

DavidSpickett wrote:

I'm wondering what happens if the read goes across multiple memory regions then 
fails. For example:
```
region 1
region 2
 <<< want to read into this region.
```
We will read region 1, 2 and then fail. vm_addr still points to the start of 
region 1 so we'll return only the contents of region 1, but we could have read 
region 2 as well.

I had to do something like this for memory tagging in 
`MemoryTagManagerAArch64MTE::MakeTaggedRange` which checks that all the memory 
regions in a range are memory tagged.

Or perhaps you:
1. Want to avoid the complication of that at this time
2. Know that memory reads here won't span a memory region so you don't need to 
bother


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


[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)

2024-09-02 Thread via lldb-commits

https://github.com/Da-Viper updated 
https://github.com/llvm/llvm-project/pull/106919

>From d2bddca1753b4c960895f51d7eb80b6efa7dc986 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka 
Date: Sun, 1 Sep 2024 17:26:11 +0100
Subject: [PATCH 1/3] [lldb-dap] Make environment option an object

---
 .../tools/lldb-dap/launch/TestDAP_launch.py   |  4 +-
 lldb/tools/lldb-dap/JSONUtils.cpp | 40 ---
 lldb/tools/lldb-dap/JSONUtils.h   | 22 ++
 lldb/tools/lldb-dap/README.md |  5 ++-
 lldb/tools/lldb-dap/lldb-dap.cpp  |  8 +++-
 lldb/tools/lldb-dap/package.json  | 11 +++--
 6 files changed, 77 insertions(+), 13 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py 
b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index a16f2da3c4df71..6b9993a2548b8d 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -229,7 +229,7 @@ def test_environment(self):
 Tests launch of a simple program with environment variables
 """
 program = self.getBuildArtifact("a.out")
-env = ["NO_VALUE", "WITH_VALUE=BAR", "EMPTY_VALUE=", "SPACE=Hello 
World"]
+env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": 
"Hello World"}
 self.build_and_launch(program, env=env)
 self.continue_to_exit()
 
@@ -242,7 +242,7 @@ def test_environment(self):
 lines.pop(0)
 # Make sure each environment variable in "env" is actually set in the
 # program environment that was printed to STDOUT
-for var in env:
+for var in env.keys():
 found = False
 for program_var in lines:
 if var in program_var:
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 7338e7cf41eb03..29b3ad490af0b6 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -136,6 +136,31 @@ std::vector GetStrings(const 
llvm::json::Object *obj,
   return strs;
 }
 
+std::unordered_map
+GetStringMap(const llvm::json::Object &obj, llvm::StringRef key) {
+  std::unordered_map strs;
+  const auto *const json_object = obj.getObject(key);
+  if (!json_object)
+return strs;
+
+  for (const auto &[key, value] : *json_object) {
+switch (value.kind()) {
+case llvm::json::Value::String:
+  strs.emplace(key.str(), value.getAsString()->str());
+  break;
+case llvm::json::Value::Number:
+case llvm::json::Value::Boolean:
+  strs.emplace(key.str(), llvm::to_string(value));
+  break;
+case llvm::json::Value::Null:
+case llvm::json::Value::Object:
+case llvm::json::Value::Array:
+  break;
+}
+  }
+  return strs;
+}
+
 static bool IsClassStructOrUnionType(lldb::SBType t) {
   return (t.GetTypeClass() & (lldb::eTypeClassUnion | lldb::eTypeClassStruct |
   lldb::eTypeClassArray)) != 0;
@@ -1370,13 +1395,16 @@ CreateRunInTerminalReverseRequest(const 
llvm::json::Object &launch_request,
   if (!cwd.empty())
 run_in_terminal_args.try_emplace("cwd", cwd);
 
-  // We need to convert the input list of environments variables into a
-  // dictionary
-  std::vector envs = GetStrings(launch_request_arguments, "env");
+  std::unordered_map envMap =
+  GetStringMap(*launch_request_arguments, "env");
   llvm::json::Object environment;
-  for (const std::string &env : envs) {
-size_t index = env.find('=');
-environment.try_emplace(env.substr(0, index), env.substr(index + 1));
+  for (const auto &[key, value] : envMap) {
+if (key.empty())
+  g_dap.SendOutput(OutputType::Stderr,
+   "empty environment variable for value: \"" + value +
+   '\"');
+else
+  environment.try_emplace(key, value);
   }
   run_in_terminal_args.try_emplace("env",
llvm::json::Value(std::move(environment)));
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index b6356630b72682..60d5db06560657 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -16,6 +16,7 @@
 #include "llvm/Support/JSON.h"
 #include 
 #include 
+#include 
 
 namespace lldb_dap {
 
@@ -152,6 +153,27 @@ bool ObjectContainsKey(const llvm::json::Object &obj, 
llvm::StringRef key);
 std::vector GetStrings(const llvm::json::Object *obj,
 llvm::StringRef key);
 
+/// Extract an object of key value strings for the specified key from an 
object.
+///
+/// String values in the object will be extracted without any quotes
+/// around them. Numbers and Booleans will be converted into
+/// strings. Any NULL, array or objects values in the array will be
+/// ignored.
+///
+/// \param[in] obj
+/// A JSON object that we will attempt to extract the array from
+///
+/// \param[in] key
+/// The key to use when extr

[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits


@@ -254,67 +255,60 @@ void TCPSocket::CloseListenSockets() {
   m_listen_sockets.clear();
 }
 
-Status TCPSocket::Accept(Socket *&conn_socket) {
-  Status error;
-  if (m_listen_sockets.size() == 0) {
-error = Status::FromErrorString("No open listening sockets!");
-return error;
-  }
+llvm::Expected> TCPSocket::Accept(
+MainLoopBase &loop,
+std::function socket)> sock_cb) {
+  if (m_listen_sockets.size() == 0)
+return llvm::createStringError("No open listening sockets!");
 
-  NativeSocket sock = kInvalidSocketValue;
-  NativeSocket listen_sock = kInvalidSocketValue;
-  lldb_private::SocketAddress AcceptAddr;
-  MainLoop accept_loop;
   std::vector handles;
   for (auto socket : m_listen_sockets) {
 auto fd = socket.first;
-auto inherit = this->m_child_processes_inherit;
-auto io_sp = IOObjectSP(new TCPSocket(socket.first, false, inherit));
-handles.emplace_back(accept_loop.RegisterReadObject(
-io_sp, [fd, inherit, &sock, &AcceptAddr, &error,
-&listen_sock](MainLoopBase &loop) {
-  socklen_t sa_len = AcceptAddr.GetMaxLength();
-  sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len, inherit,
-  error);
-  listen_sock = fd;
-  loop.RequestTermination();
-}, error));
-if (error.Fail())
-  return error;
-  }
+auto io_sp =
+std::make_shared(fd, false, 
this->m_child_processes_inherit);
+auto cb = [this, fd, sock_cb](MainLoopBase &loop) {
+  lldb_private::SocketAddress AcceptAddr;
+  socklen_t sa_len = AcceptAddr.GetMaxLength();
+  Status error;
+  NativeSocket sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len,
+   m_child_processes_inherit, error);
+  Log *log = GetLog(LLDBLog::Host);
+  if (error.Fail())
+LLDB_LOG(log, "AcceptSocket({0}): {1}", fd, error);
+
+  const lldb_private::SocketAddress &AddrIn = m_listen_sockets[fd];
+  if (!AddrIn.IsAnyAddr() && AcceptAddr != AddrIn) {
+CLOSE_SOCKET(sock);
+LLDB_LOG(log, "rejecting incoming connection from {0} (expecting {1})",
+ AcceptAddr.GetIPAddress(), AddrIn.GetIPAddress());
+  }
+  std::unique_ptr sock_up(new TCPSocket(sock, *this));
 
-  bool accept_connection = false;
-  std::unique_ptr accepted_socket;
-  // Loop until we are happy with our connection
-  while (!accept_connection) {
-accept_loop.Run();
+  // Keep our TCP packets coming without any delays.
+  sock_up->SetOptionNoDelay();
 
+  sock_cb(std::move(sock_up));

slydiman wrote:

Avoid to close or create the instance of TCPSocket with invalid sock
```
  if (error.Fail())
LLDB_LOG(log, "AcceptSocket({0}): {1}", fd, error);
  else {
const lldb_private::SocketAddress &AddrIn = m_listen_sockets[fd];
if (!AddrIn.IsAnyAddr() && AcceptAddr != AddrIn) {
  CLOSE_SOCKET(sock);
  LLDB_LOG(log,
   "rejecting incoming connection from {0} (expecting {1})",
   AcceptAddr.GetIPAddress(), AddrIn.GetIPAddress());
} else {
  std::unique_ptr sock_up(new TCPSocket(sock, *this));
  // Keep our TCP packets coming without any delays.
  sock_up->SetOptionNoDelay();
  sock_cb(std::move(sock_up));
}
  }
```

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

https://github.com/slydiman requested changes to this pull request.

BTW, I have figured out a side effect. MainLoopWindows uses events created by 
WSACreateEvent(). WSACreateEvent() creates the `manual-reset` event. But 
WSAResetEvent() is used only for m_trigger_event. All other events (READ, 
ACCEPT, CLOSE) are never reset. I have no idea how it worked before. But I got 
thousands of error messages using this patch with lldb-server after first 
connection:
```
AcceptSocket(): A non-blocking socket operation could not be completed 
immediately
```
I have added `WSAResetEvent(KV.second.event);` before 
`ProcessReadObject(KV.first);` in MainLoopWindows.cpp to fix it. It seems this 
issue must be fixed before or with this patch, otherwise it will break the 
Windows build.

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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


[Lldb-commits] [lldb] [lldb-dap][test] Fix: Typo in unresolved test (PR #107030)

2024-09-02 Thread via lldb-commits

https://github.com/Da-Viper created 
https://github.com/llvm/llvm-project/pull/107030

There is a typo in an assertion that causes the  instruction break-point test 
to be unresolved 

>From 988aab74b0438724f06106453f0c0730ca4068f4 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka 
Date: Tue, 3 Sep 2024 00:37:07 +0100
Subject: [PATCH] [lldb-dap][test] Fix: typo in unresolved test

---
 .../instruction-breakpoint/TestDAP_instruction_breakpoint.py| 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
 
b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
index 3862be7bfa34c2..53b7df9e54af22 100644
--- 
a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
+++ 
b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
@@ -35,7 +35,7 @@ def instruction_breakpoint_test(self):
 # Set source breakpoint 1
 response = self.dap_server.request_setBreakpoints(self.main_path, 
[main_line])
 breakpoints = response["body"]["breakpoints"]
-self.assertEquals(len(breakpoints), 1)
+self.assertEqual(len(breakpoints), 1)
 breakpoint = breakpoints[0]
 self.assertEqual(
 breakpoint["line"], main_line, "incorrect breakpoint source line"

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


[Lldb-commits] [lldb] [lldb-dap][test] Fix: Typo in unresolved test (PR #107030)

2024-09-02 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: None (Da-Viper)


Changes

There is a typo in an assertion that causes the  instruction break-point test 
to be unresolved 

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


1 Files Affected:

- (modified) 
lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
 (+1-1) 


``diff
diff --git 
a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
 
b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
index 3862be7bfa34c2..53b7df9e54af22 100644
--- 
a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
+++ 
b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
@@ -35,7 +35,7 @@ def instruction_breakpoint_test(self):
 # Set source breakpoint 1
 response = self.dap_server.request_setBreakpoints(self.main_path, 
[main_line])
 breakpoints = response["body"]["breakpoints"]
-self.assertEquals(len(breakpoints), 1)
+self.assertEqual(len(breakpoints), 1)
 breakpoint = breakpoints[0]
 self.assertEqual(
 breakpoint["line"], main_line, "incorrect breakpoint source line"

``




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


[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)

2024-09-02 Thread Adrian Vogelsgesang via lldb-commits


@@ -1831,7 +1831,13 @@ lldb::SBError LaunchProcess(const llvm::json::Object 
&request) {
 launch_info.SetArguments(MakeArgv(args).data(), true);
 
   // Pass any environment variables along that the user specified.
-  auto envs = GetStrings(arguments, "env");
+  auto envMap = GetStringMap(*arguments, "env");
+  std::vector envs;
+  envs.reserve(envMap.size());
+  for (const auto &[key, value] : envMap) {
+envs.emplace_back(key + '=' + value);
+  }
+
   if (!envs.empty())
 launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);

vogelsgesang wrote:

instead of setting concatenated strings, I think we should use 
`SBLaunchInfo::SetEnvironment` and `SBEnvironment::Set`

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


[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)

2024-09-02 Thread Adrian Vogelsgesang via lldb-commits

vogelsgesang wrote:

> I am not sure if it possible to use a dict for sourceMaps since a source can 
> map to multiple destination see test

Interestingly, CodeLLDB also uses an object, see 
https://github.com/vadimcn/codelldb/blob/v1.10.0/MANUAL.md#source-path-remapping.
 Probably they just don't support mapping a path to multiple source paths.

I guess we want to stay with the "array-of-array" configuration, then. What do 
you think, @JDevlieghere 

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


[Lldb-commits] [lldb] [lldb] Add a callback version of TCPSocket::Accept (PR #106955)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Updated TCPSocket to listen multiple ports on the same single thread (PR #104797)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)

2024-09-02 Thread Dmitry Vasilyev via lldb-commits

slydiman wrote:

I have updated this patch based on #106955 to see how it will look and work.

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


[Lldb-commits] [lldb] [lldb-dap][test] Fix: Typo in unresolved test (PR #107030)

2024-09-02 Thread Pavel Labath via lldb-commits

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


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


[Lldb-commits] [lldb] [lldb-dap][test] Fix: Typo in unresolved test (PR #107030)

2024-09-02 Thread Pavel Labath via lldb-commits

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


[Lldb-commits] [lldb] 7d7d2d2 - [lldb-dap][test] Fix: Typo in unresolved test (#107030)

2024-09-02 Thread via lldb-commits

Author: Da-Viper
Date: 2024-09-03T08:37:59+02:00
New Revision: 7d7d2d2b54172f97300c02ec80bb568d35403cce

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

LOG: [lldb-dap][test] Fix: Typo in unresolved test (#107030)

There is a typo in an assertion that causes the instruction break-point
test to be unresolved

Added: 


Modified: 

lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py

Removed: 




diff  --git 
a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
 
b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
index 3862be7bfa34c2..53b7df9e54af22 100644
--- 
a/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
+++ 
b/lldb/test/API/tools/lldb-dap/instruction-breakpoint/TestDAP_instruction_breakpoint.py
@@ -35,7 +35,7 @@ def instruction_breakpoint_test(self):
 # Set source breakpoint 1
 response = self.dap_server.request_setBreakpoints(self.main_path, 
[main_line])
 breakpoints = response["body"]["breakpoints"]
-self.assertEquals(len(breakpoints), 1)
+self.assertEqual(len(breakpoints), 1)
 breakpoint = breakpoints[0]
 self.assertEqual(
 breakpoint["line"], main_line, "incorrect breakpoint source line"



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


[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)

2024-09-02 Thread Pavel Labath via lldb-commits


@@ -96,16 +98,120 @@ def getArchSpec(self, architecture):
 """
 return ["ARCH=" + architecture] if architecture else []
 
-def getCCSpec(self, compiler):
+def getToolchainSpec(self, compiler):
 """
-Helper function to return the key-value string to specify the compiler
+Helper function to return the key-value strings to specify the 
toolchain
 used for the make system.
 """
 cc = compiler if compiler else None
 if not cc and configuration.compiler:
 cc = configuration.compiler
+
 if cc:
-return ['CC="%s"' % cc]
+exe_ext = ""
+if lldbplatformutil.getHostPlatform() == "windows":
+exe_ext = ".exe"
+
+cc = cc.strip()
+cc_path = pathlib.Path(cc)
+cc = cc_path.as_posix()
+
+# We can get CC compiler string in the following formats:
+#  [] - such as 'xrun clang', 'xrun 
/usr/bin/clang' & etc
+#
+# Where  could contain the following parts:
+#   [.]   - sucn as 
'clang', 'clang.exe' ('clamg-cl.exe'?)
+#   -[.]   - such as 
'armv7-linux-gnueabi-gcc'
+#   /[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+#   /-[.]- such as 
'/usr/bin/clang', 'c:\path\to\compiler\clang,exe'
+
+cc_ext = cc_path.suffix
+# Compiler name without extension
+cc_name = cc_path.stem.split(" ")[-1]
+
+# A kind of compiler (canonical name): clang, gcc, cc & etc.
+cc_type = cc_name
+# A triple prefix of compiler name: gcc
+cc_prefix = ""
+if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name:
+cc_name_parts = cc_name.split("-")
+cc_type = cc_name_parts[-1]
+if len(cc_name_parts) > 1:
+cc_prefix = "-".join(cc_name_parts[:-1]) + "-"
+
+# A kind of C++ compiler.
+cxx_types = {
+"icc": "icpc",
+"llvm-gcc": "llvm-g++",
+"gcc": "g++",
+"cc": "c++",
+"clang": "clang++",
+}
+cxx_type = cxx_types.get(cc_type, cc_type)
+
+cc_dir = cc_path.parent
+
+def getLlvmUtil(util_name):
+llvm_tools_dir = os.getenv("LLVM_TOOLS_DIR", cc_dir.as_posix())
+return llvm_tools_dir + "/" + util_name + exe_ext
+
+def getToolchainUtil(util_name):
+return (cc_dir / (cc_prefix + util_name + cc_ext)).as_posix()
+
+cxx = getToolchainUtil(cxx_type)
+
+util_names = {
+"OBJCOPY": "objcopy",
+"STRIP": "objcopy",
+"ARCHIVER": "ar",
+"DWP": "dwp",
+}
+utils = []
+
+# Note: LLVM_AR is currently required by API TestBSDArchives.py 
tests.
+# Assembly a full path to llvm-ar for given LLVM_TOOLS_DIR;
+# otherwise assume we have llvm-ar at the same place where is CC 
specified.
+if not os.getenv("LLVM_AR"):
+llvm_ar = getLlvmUtil("llvm-ar")
+utils.extend(['LLVM_AR="%s"' % llvm_ar])
+
+if not lldbplatformutil.platformIsDarwin():
+if os.getenv("USE_LLVM_TOOLS"):

labath wrote:

Ok, I see now. This is new functionality added in this patch. Could we put that 
in a separate PR and keep this one as a NFC-ish refactoring/cleanup patch? I'd 
like to discuss this concept further, but I think it would be easier to do it 
in isolation.

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


  1   2   >