[Lldb-commits] [lldb] [LLDB] Finish implementing support for DW_FORM_data16 (PR #106799)
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)
@@ -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)
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)
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)
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)
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)
@@ -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)
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)
@@ -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)
@@ -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)
@@ -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)
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)
@@ -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)
@@ -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)
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)
@@ -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)
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)
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)
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)
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)
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)
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)
@@ -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)
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)
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)
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)
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)
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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
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)
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)
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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
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)
@@ -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)
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)
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)
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)
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)
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)
@@ -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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
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)
@@ -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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
@@ -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)
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)
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)
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)
@@ -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)
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)
@@ -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)
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)
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)
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)
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)
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)
@@ -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)
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)
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)
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)
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)
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)
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)
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)
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)
@@ -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