From ff5e896425577f445ed080d88b582aab0896fba0 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Wed, 13 Jan 2021 22:52:40 -0800 Subject: [PATCH 1/6] Fix unused variable in CoroFrame.cpp when building Release with GCC 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building with GCC 10, the following warning is reported: ``` /llvm-project/llvm/lib/Transforms/Coroutines/CoroFrame.cpp:1527:28: warning: unused variable ‘CS’ [-Wunused-variable] 1527 | if (CatchSwitchInst *CS = ``` This change adds a cast to `void` to avoid the warning. Reviewed By: lxfind Differential Revision: https://reviews.llvm.org/D94456 --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index 84b78fce3f448d..16e7e2c2ceaf90 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1535,6 +1535,7 @@ static void rewritePHIs(BasicBlock &BB) { for (BasicBlock *Pred : Preds) { if (CatchSwitchInst *CS = dyn_cast(Pred->getTerminator())) { + (void)CS; // CleanupPad with a CatchSwitch predecessor: therefore this is an // unwind destination that needs to be handle specially. assert(CS->getUnwindDest() == &BB); From 885eae9d85de4b1b1907ac9b3ecba26565932069 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 13 Jan 2021 23:39:32 -0800 Subject: [PATCH 2/6] Add func call so we don't instruction-step into the builtin_trap The way this test is structured right now, I set a breakpoint on the instruction before the __builtin_trap. It hits the breakpoint, disables the breakpoint, and instruction steps. This hits the builtin_trap instruction which debugserver (on arm64) now advances to the next instruction and reports that address to lldb. lldb doesn't recognize this as a proper response to the instruction step and continues executing until the next trap, and the test fails. --- lldb/test/API/macosx/builtin-debugtrap/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/API/macosx/builtin-debugtrap/main.cpp b/lldb/test/API/macosx/builtin-debugtrap/main.cpp index 2cbe2a48b50347..84332d800148f1 100644 --- a/lldb/test/API/macosx/builtin-debugtrap/main.cpp +++ b/lldb/test/API/macosx/builtin-debugtrap/main.cpp @@ -3,6 +3,7 @@ int global = 0; int main() { global = 5; // Set a breakpoint here + puts(""); __builtin_debugtrap(); global = 10; __builtin_trap(); From 7ad54d193871ce69968565ea46372e81c9f1ce62 Mon Sep 17 00:00:00 2001 From: Philip Pfaffe Date: Thu, 14 Jan 2021 08:44:47 +0100 Subject: [PATCH 3/6] [lldb][wasm] Parse DWO section names Mirror ELF section parsing to support DWARF section names for debug fission. Reviewed By: labath Differential Revision: https://reviews.llvm.org/D93621 --- .../ObjectFile/wasm/ObjectFileWasm.cpp | 61 +++++++---- .../wasm/embedded-debug-sections.yaml | 100 ++++++++++++++++++ 2 files changed, 138 insertions(+), 23 deletions(-) diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp index 91150fa02ebcad..6c29c2326212ea 100644 --- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp +++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp @@ -253,6 +253,43 @@ bool ObjectFileWasm::ParseHeader() { Symtab *ObjectFileWasm::GetSymtab() { return nullptr; } +static SectionType GetSectionTypeFromName(llvm::StringRef Name) { + if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) { + return llvm::StringSwitch(Name) + .Case("abbrev", eSectionTypeDWARFDebugAbbrev) + .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) + .Case("addr", eSectionTypeDWARFDebugAddr) + .Case("aranges", eSectionTypeDWARFDebugAranges) + .Case("cu_index", eSectionTypeDWARFDebugCuIndex) + .Case("frame", eSectionTypeDWARFDebugFrame) + .Case("info", eSectionTypeDWARFDebugInfo) + .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo) + .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine) + .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr) + .Case("loc", eSectionTypeDWARFDebugLoc) + .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo) + .Case("loclists", eSectionTypeDWARFDebugLocLists) + .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo) + .Case("macinfo", eSectionTypeDWARFDebugMacInfo) + .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro) + .Case("names", eSectionTypeDWARFDebugNames) + .Case("pubnames", eSectionTypeDWARFDebugPubNames) + .Case("pubtypes", eSectionTypeDWARFDebugPubTypes) + .Case("ranges", eSectionTypeDWARFDebugRanges) + .Case("rnglists", eSectionTypeDWARFDebugRngLists) + .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo) + .Case("str", eSectionTypeDWARFDebugStr) + .Case("str.dwo", eSectionTypeDWARFDebugStrDwo) + .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets) + .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) + .Case("tu_index", eSectionTypeDWARFDebugTuIndex) + .Case("types", eSectionTypeDWARFDebugTypes) + .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo) + .Default(eSectionTypeOther); + } + return eSectionTypeOther; +} + void ObjectFileWasm::CreateSections(SectionList &unified_section_list) { if (m_sections_up) return; @@ -280,29 +317,7 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) { // Code section. vm_addr = 0; } else { - section_type = - llvm::StringSwitch(sect_info.name.GetStringRef()) - .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev) - .Case(".debug_addr", eSectionTypeDWARFDebugAddr) - .Case(".debug_aranges", eSectionTypeDWARFDebugAranges) - .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex) - .Case(".debug_frame", eSectionTypeDWARFDebugFrame) - .Case(".debug_info", eSectionTypeDWARFDebugInfo) - .Case(".debug_line", eSectionTypeDWARFDebugLine) - .Case(".debug_line_str", eSectionTypeDWARFDebugLineStr) - .Case(".debug_loc", eSectionTypeDWARFDebugLoc) - .Case(".debug_loclists", eSectionTypeDWARFDebugLocLists) - .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo) - .Case(".debug_macro", eSectionTypeDWARFDebugMacro) - .Case(".debug_names", eSectionTypeDWARFDebugNames) - .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames) - .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes) - .Case(".debug_ranges", eSectionTypeDWARFDebugRanges) - .Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists) - .Case(".debug_str", eSectionTypeDWARFDebugStr) - .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets) - .Case(".debug_types", eSectionTypeDWARFDebugTypes) - .Default(eSectionTypeOther); + section_type = GetSectionTypeFromName(sect_info.name.GetStringRef()); if (section_type == eSectionTypeOther) continue; section_name = sect_info.name; diff --git a/lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml b/lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml index f3edf18770b1fe..0773dc0016565f 100644 --- a/lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml +++ b/lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml @@ -40,6 +40,73 @@ # CHECK: VM size: 0 # CHECK: File size: 3 +# CHECK: Name: .debug_abbrev.dwo +# CHECK: Type: dwarf-abbrev-dwo +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_info.dwo +# CHECK: Type: dwarf-info-dwo +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_line.dwo +# CHECK: Type: dwarf-line +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_line_str.dwo +# CHECK: Type: dwarf-line-str +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_loc.dwo +# CHECK: Type: dwarf-loc-dwo +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_loclists.dwo +# CHECK: Type: dwarf-loclists-dwo +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_macro.dwo +# CHECK: Type: dwarf-macro +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_rnglists.dwo +# CHECK: Type: dwarf-rnglists-dwo +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_str.dwo +# CHECK: Type: dwarf-str-dwo +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_str_offsets.dwo +# CHECK: Type: dwarf-str-offsets-dwo +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + +# CHECK: Name: .debug_types.dwo +# CHECK: Type: dwarf-types-dwo +# CHECK: VM address: 0x0 +# CHECK: VM size: 0 +# CHECK: File size: 4 + + --- !WASM FileHeader: Version: 0x00000001 @@ -64,4 +131,37 @@ Sections: - Type: CUSTOM Name: .debug_str Payload: 636CFF + - Type: CUSTOM + Name: .debug_abbrev.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_info.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_line.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_line_str.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_loc.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_loclists.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_macro.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_rnglists.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_str.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_str_offsets.dwo + Payload: DEADBEEF + - Type: CUSTOM + Name: .debug_types.dwo + Payload: DEADBEEF ... From 2bbf724feea9824f9b9e4d20d34828023dbec2af Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Thu, 14 Jan 2021 09:24:31 +0100 Subject: [PATCH 4/6] Implement vAttachWait in lldb-server This commit vAttachWait in lldb-server, so --waitfor can be used on Linux Reviewed By: labath, clayborg Differential Revision: https://reviews.llvm.org/D93895 --- .../GDBRemoteCommunicationServerLLGS.cpp | 98 +++++++++++++++++++ .../GDBRemoteCommunicationServerLLGS.h | 13 +++ .../lldb-server/TestGdbRemoteAttachWait.py | 75 ++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 lldb/test/API/tools/lldb-server/TestGdbRemoteAttachWait.py diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index c202fc9d339fbc..2c8bcf477f5077 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -159,6 +159,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_vAttach, &GDBRemoteCommunicationServerLLGS::Handle_vAttach); + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vAttachWait, + &GDBRemoteCommunicationServerLLGS::Handle_vAttachWait); RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_vCont, &GDBRemoteCommunicationServerLLGS::Handle_vCont); @@ -334,6 +337,71 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { return Status(); } +Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess( + llvm::StringRef process_name) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + + std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1); + + // Create the matcher used to search the process list. + ProcessInstanceInfoList exclusion_list; + ProcessInstanceInfoMatch match_info; + match_info.GetProcessInfo().GetExecutableFile().SetFile( + process_name, llvm::sys::path::Style::posix); + match_info.SetNameMatchType(NameMatch::EndsWith); + + // Create the excluded process list before polling begins. + Host::FindProcesses(match_info, exclusion_list); + LLDB_LOG(log, "placed '{0}' processes in the exclusion list.", + exclusion_list.size()); + + LLDB_LOG(log, "waiting for '{0}' to appear", process_name); + + auto is_in_exclusion_list = + [&exclusion_list](const ProcessInstanceInfo &info) { + for (auto &excluded : exclusion_list) { + if (excluded.GetProcessID() == info.GetProcessID()) + return true; + } + return false; + }; + + ProcessInstanceInfoList loop_process_list; + while (true) { + loop_process_list.clear(); + if (Host::FindProcesses(match_info, loop_process_list)) { + // Remove all the elements that are in the exclusion list. + llvm::erase_if(loop_process_list, is_in_exclusion_list); + + // One match! We found the desired process. + if (loop_process_list.size() == 1) { + auto matching_process_pid = loop_process_list[0].GetProcessID(); + LLDB_LOG(log, "found pid {0}", matching_process_pid); + return AttachToProcess(matching_process_pid); + } + + // Multiple matches! Return an error reporting the PIDs we found. + if (loop_process_list.size() > 1) { + StreamString error_stream; + error_stream.Format( + "Multiple executables with name: '{0}' found. Pids: ", + process_name); + for (size_t i = 0; i < loop_process_list.size() - 1; ++i) { + error_stream.Format("{0}, ", loop_process_list[i].GetProcessID()); + } + error_stream.Format("{0}.", loop_process_list.back().GetProcessID()); + + Status error; + error.SetErrorString(error_stream.GetString()); + return error; + } + } + // No matches, we have not found the process. Sleep until next poll. + LLDB_LOG(log, "sleep {0} seconds", polling_interval); + std::this_thread::sleep_for(polling_interval); + } +} + void GDBRemoteCommunicationServerLLGS::InitializeDelegate( NativeProcessProtocol *process) { assert(process && "process cannot be NULL"); @@ -3188,6 +3256,36 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach( return SendStopReasonForState(m_debugged_process_up->GetState()); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_vAttachWait( + StringExtractorGDBRemote &packet) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + + // Consume the ';' after the identifier. + packet.SetFilePos(strlen("vAttachWait")); + + if (!packet.GetBytesLeft() || packet.GetChar() != ';') + return SendIllFormedResponse(packet, "vAttachWait missing expected ';'"); + + // Allocate the buffer for the process name from vAttachWait. + std::string process_name; + if (!packet.GetHexByteString(process_name)) + return SendIllFormedResponse(packet, + "vAttachWait failed to parse process name"); + + LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name); + + Status error = AttachWaitProcess(process_name); + if (error.Fail()) { + LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name, + error); + return SendErrorResponse(error); + } + + // Notify we attached by sending a stop packet. + return SendStopReasonForState(m_debugged_process_up->GetState()); +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index ae8928c5d244b4..cdeba95b46ee81 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -59,6 +59,17 @@ class GDBRemoteCommunicationServerLLGS /// attach operation. Status AttachToProcess(lldb::pid_t pid); + /// Wait to attach to a process with a given name. + /// + /// This method supports waiting for the next instance of a process + /// with a given name and attaching llgs to that via the configured + /// Platform. + /// + /// \return + /// An Status object indicating the success or failure of the + /// attach operation. + Status AttachWaitProcess(llvm::StringRef process_name); + // NativeProcessProtocol::NativeDelegate overrides void InitializeDelegate(NativeProcessProtocol *process) override; @@ -170,6 +181,8 @@ class GDBRemoteCommunicationServerLLGS PacketResult Handle_vAttach(StringExtractorGDBRemote &packet); + PacketResult Handle_vAttachWait(StringExtractorGDBRemote &packet); + PacketResult Handle_D(StringExtractorGDBRemote &packet); PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet); diff --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteAttachWait.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteAttachWait.py new file mode 100644 index 00000000000000..d2ba674a8be6b2 --- /dev/null +++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteAttachWait.py @@ -0,0 +1,75 @@ + +import os +from time import sleep + +import gdbremote_testcase +import lldbgdbserverutils +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestGdbRemoteAttachWait(gdbremote_testcase.GdbRemoteTestCaseBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_attach_with_vAttachWait(self): + exe = '%s_%d' % (self.testMethodName, os.getpid()) + + def launch_inferior(): + inferior = self.launch_process_for_attach( + inferior_args=["sleep:60"], + exe_path=self.getBuildArtifact(exe)) + self.assertIsNotNone(inferior) + self.assertTrue(inferior.pid > 0) + self.assertTrue( + lldbgdbserverutils.process_is_running( + inferior.pid, True)) + return inferior + + self.build(dictionary={'EXE': exe}) + self.set_inferior_startup_attach_manually() + + server = self.connect_to_debug_monitor() + self.assertIsNotNone(server) + + # Launch the first inferior (we shouldn't attach to this one). + launch_inferior() + + self.add_no_ack_remote_stream() + self.test_sequence.add_log_lines([ + # Do the attach. + "read packet: $vAttachWait;{}#00".format(lldbgdbserverutils.gdbremote_hex_encode_string(exe)), + ], True) + # Run the stream until attachWait. + context = self.expect_gdbremote_sequence() + self.assertIsNotNone(context) + + # Sleep so we're sure that the inferior is launched after we ask for the attach. + sleep(1) + + # Launch the second inferior (we SHOULD attach to this one). + inferior_to_attach = launch_inferior() + + # Make sure the attach succeeded. + self.test_sequence.add_log_lines([ + {"direction": "send", + "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$", + "capture": {1: "stop_signal_hex"}}, + ], True) + self.add_process_info_collection_packets() + + + # Run the stream sending the response.. + context = self.expect_gdbremote_sequence() + self.assertIsNotNone(context) + + # Gather process info response. + process_info = self.parse_process_info_response(context) + self.assertIsNotNone(process_info) + + # Ensure the process id matches what we expected. + pid_text = process_info.get('pid', None) + self.assertIsNotNone(pid_text) + reported_pid = int(pid_text, base=16) + self.assertEqual(reported_pid, inferior_to_attach.pid) From ed205f63b4a288ccbffc9af58333d09a7cec40dc Mon Sep 17 00:00:00 2001 From: lewuathe Date: Thu, 14 Jan 2021 09:28:08 +0100 Subject: [PATCH 5/6] [mlir] Update doc to omit the usage of LLVMIntegerType Since [[ https://reviews.llvm.org/D94178 | the LLVMIntegerType was replaced with build-in integer type ]], the usage in the tutorial should be also updated accordingly. We need to update chapter 6 for Toy tutorial specifically. See: https://reviews.llvm.org/D94178 Reviewed By: rriddle Differential Revision: https://reviews.llvm.org/D94651 --- mlir/docs/Tutorials/Toy/Ch-6.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/docs/Tutorials/Toy/Ch-6.md b/mlir/docs/Tutorials/Toy/Ch-6.md index 1093ae9fe2babd..bddd93688ddb8b 100644 --- a/mlir/docs/Tutorials/Toy/Ch-6.md +++ b/mlir/docs/Tutorials/Toy/Ch-6.md @@ -37,9 +37,9 @@ static FlatSymbolRefAttr getOrInsertPrintf(PatternRewriter &rewriter, // Create a function declaration for printf, the signature is: // * `i32 (i8*, ...)` - auto llvmI32Ty = LLVM::LLVMIntegerType::get(context, 32); + auto llvmI32Ty = IntegerType::get(context, 32); auto llvmI8PtrTy = - LLVM::LLVMPointerType::get(LLVM::LLVMIntegerType::get(context, 8)); + LLVM::LLVMPointerType::get(IntegerType::get(context, 8)); auto llvmFnType = LLVM::LLVMFunctionType::get(llvmI32Ty, llvmI8PtrTy, /*isVarArg=*/true); From 4b284b9ca8098e284b8d965a633b71bd283043d6 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 6 Jan 2021 17:05:27 +0100 Subject: [PATCH 6/6] [lldb] Fix TestPlatformProcessConnect.py The test was marked as remote-only, which means it was run ~never, and accumulated various problems. This commit modifies the test to run locally and includes a couple of other fixes necessary to make it run: - moves the "invoke" method into the "Base" test class - adds []'s around the IP address in a couple more places to make things work with IPv6 The test is now marked as skipped when running the remote test suite. It would be possible to make it run both locally and remotely, but this would require writing a lot special logic for the remote case, and that is not worth it. --- .../Python/lldbsuite/test/lldbtest.py | 26 +++++----- .../gdb-server/PlatformRemoteGDBServer.cpp | 2 +- .../GDBRemoteCommunicationServerPlatform.cpp | 2 +- .../TestPlatformProcessConnect.py | 52 +++++-------------- 4 files changed, 27 insertions(+), 55 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index d240050cc4c623..c377b64e9b9ea3 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -1765,6 +1765,19 @@ def cleanup(self, dictionary=None): "Don't know how to do cleanup with dictionary: " + dictionary) + def invoke(self, obj, name, trace=False): + """Use reflection to call a method dynamically with no argument.""" + trace = (True if traceAlways else trace) + + method = getattr(obj, name) + import inspect + self.assertTrue(inspect.ismethod(method), + name + "is a method name of object: " + str(obj)) + result = method() + with recording(self, trace) as sbuf: + print(str(method) + ":", result, file=sbuf) + return result + def getLLDBLibraryEnvVal(self): """ Returns the path that the OS-specific library search environment variable (self.dylibPath) should be set to in order for a program to find the LLDB @@ -2624,19 +2637,6 @@ def expect_var_path( value_check.check_value(self, eval_result, str(eval_result)) return eval_result - def invoke(self, obj, name, trace=False): - """Use reflection to call a method dynamically with no argument.""" - trace = (True if traceAlways else trace) - - method = getattr(obj, name) - import inspect - self.assertTrue(inspect.ismethod(method), - name + "is a method name of object: " + str(obj)) - result = method() - with recording(self, trace) as sbuf: - print(str(method) + ":", result, file=sbuf) - return result - def build( self, architecture=None, diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index a64ee2634e2b7d..6a4275d249f6ec 100644 --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -825,7 +825,7 @@ std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme, const char *hostname, uint16_t port, const char *path) { StreamString result; - result.Printf("%s://%s", scheme, hostname); + result.Printf("%s://[%s]", scheme, hostname); if (port != 0) result.Printf(":%u", port); if (path) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 4aa15346094159..3462fb7ec8b979 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -205,7 +205,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( platform_port, platform_path); UNUSED_IF_ASSERT_DISABLED(ok); assert(ok); - url << platform_ip.str() << ":" << *port; + url << '[' << platform_ip.str() << "]:" << *port; } else { socket_name = GetDomainSocketPath("gdbserver").GetPath(); url << socket_name; diff --git a/lldb/test/API/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py b/lldb/test/API/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py index 177388fad5fc58..95a210059b6d54 100644 --- a/lldb/test/API/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py +++ b/lldb/test/API/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py @@ -1,44 +1,22 @@ - -import time - +import socket import gdbremote_testcase +import lldbgdbserverutils from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil - class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase): mydir = TestBase.compute_mydir(__file__) - @llgs_test - @no_debug_info_test - @skipIf(remote=False) + @skipIfRemote @expectedFailureAll(hostoslist=["windows"], triple='.*-android') def test_platform_process_connect(self): self.build() - working_dir = lldb.remote_platform.GetWorkingDirectory() - src = lldb.SBFileSpec(self.getBuildArtifact("a.out")) - dest = lldb.SBFileSpec(os.path.join(working_dir, "a.out")) - err = lldb.remote_platform.Put(src, dest) - if err.Fail(): - raise RuntimeError( - "Unable copy '%s' to '%s'.\n>>> %s" % - (f, wd, err.GetCString())) + hostname = socket.getaddrinfo("localhost", 0, proto=socket.IPPROTO_TCP)[0][4][0] + listen_url = "[%s]:0"%hostname - m = re.search("^(.*)://([^:/]*)", configuration.lldb_platform_url) - protocol = m.group(1) - hostname = m.group(2) - unix_protocol = protocol.startswith("unix-") - if unix_protocol: - p = re.search("^(.*)-connect", protocol) - path = lldbutil.join_remote_paths(configuration.lldb_platform_working_dir, - self.getBuildDirBasename(), "platform-%d.sock" % int(time.time())) - listen_url = "%s://%s" % (p.group(1), path) - else: - listen_url = "*:0" - - port_file = "%s/port" % working_dir + port_file = self.getBuildArtifact("port") commandline_args = [ "platform", "--listen", @@ -46,25 +24,19 @@ def test_platform_process_connect(self): "--socket-file", port_file, "--", - "%s/a.out" % - working_dir, + self.getBuildArtifact("a.out"), "foo"] self.spawnSubprocess( - self.debug_monitor_exe, - commandline_args, - install_remote=False) + lldbgdbserverutils.get_lldb_server_exe(), + commandline_args) socket_id = lldbutil.wait_for_file_on_target(self, port_file) self.dbg.SetAsync(False) - - new_platform = lldb.SBPlatform(lldb.remote_platform.GetName()) + new_platform = lldb.SBPlatform("remote-" + self.getPlatform()) self.dbg.SetSelectedPlatform(new_platform) - if unix_protocol: - connect_url = "%s://%s%s" % (protocol, hostname, socket_id) - else: - connect_url = "%s://%s:%s" % (protocol, hostname, socket_id) + connect_url = "connect://[%s]:%s" % (hostname, socket_id) command = "platform connect %s" % (connect_url) result = lldb.SBCommandReturnObject() @@ -72,7 +44,7 @@ def test_platform_process_connect(self): self.assertTrue( result.Succeeded(), "platform process connect failed: %s" % - result.GetOutput()) + result.GetError()) target = self.dbg.GetSelectedTarget() process = target.GetProcess()