diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/tools/lldb-server')
20 files changed, 244 insertions, 104 deletions
| diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py index 7b974e548a58..1296d513b917 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGDBRemoteMemoryRead.py @@ -6,18 +6,21 @@ from __future__ import print_function +import binascii  import os +  import lldb +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * -import lldbsuite.test.lldbutil as lldbutil -import binascii +from lldbsuite.test import lldbutil +from lldbsuite.test import lldbplatformutil  class MemoryReadTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @skipUnlessPlatform(getDarwinOSTriples()+["linux"]) +    @skipUnlessPlatform(lldbplatformutil.getDarwinOSTriples()+["linux"])      def test_memory_read(self):          self.build()          exe = os.path.join (os.getcwd(), "a.out") @@ -34,7 +37,8 @@ class MemoryReadTestCase(TestBase):              error = lldb.SBError()              memory = process.ReadMemory(pc, size, error)              self.assertTrue(error.Success()) -            self.match("process plugin packet send x%x,%x" % (pc, size), ["response:", memory]) +            # Results in trying to write non-printable characters to the session log. +            # self.match("process plugin packet send x%x,%x" % (pc, size), ["response:", memory])              self.match("process plugin packet send m%x,%x" % (pc, size), ["response:", binascii.hexlify(memory)])          process.Continue() diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py index ca96a9a837b9..5460b21382ec 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAttach.py @@ -4,8 +4,9 @@ from __future__ import print_function  import gdbremote_testcase  import lldbgdbserverutils - +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteAttach(gdbremote_testcase.GdbRemoteTestCaseBase): diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py index 1ce5779e7897..e70ad5f570a7 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteAuxvSupport.py @@ -3,7 +3,9 @@ from __future__ import print_function  import gdbremote_testcase +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteAuxvSupport(gdbremote_testcase.GdbRemoteTestCaseBase): @@ -23,7 +25,7 @@ class TestGdbRemoteAuxvSupport(gdbremote_testcase.GdbRemoteTestCaseBase):              # Start the inferior...              "read packet: $c#63",              # ... match output.... -            { "type":"output_match", "regex":r"^message:main entered\r\n$" }, +            { "type":"output_match", "regex":self.maybe_strict_output_regex(r"message:main entered\r\n") },              ], True)          # ... then interrupt.          self.add_interrupt_packets() diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py index 6535ce40475d..7daae871caf6 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteExpeditedRegisters.py @@ -3,7 +3,9 @@ from __future__ import print_function  import gdbremote_testcase +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteExpeditedRegisters(gdbremote_testcase.GdbRemoteTestCaseBase): diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py index b253254c78ed..560da9d41429 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteKill.py @@ -4,8 +4,9 @@ from __future__ import print_function  import gdbremote_testcase  import lldbgdbserverutils - +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteKill(gdbremote_testcase.GdbRemoteTestCaseBase): diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py index a11167b87c25..f26b62043613 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteProcessInfo.py @@ -1,12 +1,13 @@  from __future__ import print_function +import sys  import gdbremote_testcase  import lldbgdbserverutils -import sys - +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteProcessInfo(gdbremote_testcase.GdbRemoteTestCaseBase): @@ -51,7 +52,7 @@ class TestGdbRemoteProcessInfo(gdbremote_testcase.GdbRemoteTestCaseBase):          self.add_process_info_collection_packets()          # Run the stream -        context = self.expect_gdbremote_sequence() +        context = self.expect_gdbremote_sequence(timeout_seconds = 8)          self.assertIsNotNone(context)          # Gather process info response diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py index a36b4ae781ad..63a8995c6729 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py @@ -3,7 +3,9 @@ from __future__ import print_function  import gdbremote_testcase +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):      """Test QSaveRegisterState/QRestoreRegisterState support.""" @@ -24,7 +26,7 @@ class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):              # Start the inferior...              "read packet: $c#63",              # ... match output.... -            { "type":"output_match", "regex":r"^message:main entered\r\n$" }, +            { "type":"output_match", "regex":self.maybe_strict_output_regex(r"message:main entered\r\n") },              ], True)          # ... then interrupt.          self.add_interrupt_packets() diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py index 3b008249f557..31d53bed2593 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteSingleStep.py @@ -3,7 +3,9 @@ from __future__ import print_function  import gdbremote_testcase +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteSingleStep(gdbremote_testcase.GdbRemoteTestCaseBase): @@ -17,7 +19,8 @@ class TestGdbRemoteSingleStep(gdbremote_testcase.GdbRemoteTestCaseBase):          self.single_step_only_steps_one_instruction(use_Hc_packet=True, step_instruction="s")      @llgs_test -    @expectedFailureAndroid(bugnumber="llvm.com/pr24739", archs=["arm", "aarch64"]) +    @expectedFailureAndroid(bugnumber="llvm.org/pr24739", archs=["arm", "aarch64"]) +    @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr24739")      def test_single_step_only_steps_one_instruction_with_s_llgs(self):          self.init_llgs_test()          self.build() diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py index a7938795b9bf..d55416569ac4 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py @@ -1,9 +1,9 @@  from __future__ import print_function - -  import gdbremote_testcase +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteThreadsInStopReply(gdbremote_testcase.GdbRemoteTestCaseBase): diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py index cce484451de4..b2b54e3f0394 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py @@ -6,7 +6,9 @@ import sys  import unittest2  import gdbremote_testcase +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemote_qThreadStopInfo(gdbremote_testcase.GdbRemoteTestCaseBase): diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py index 579e99d6d774..335d96c2b074 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_vCont.py @@ -1,9 +1,9 @@  from __future__ import print_function - -  import gdbremote_testcase +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemote_vCont(gdbremote_testcase.GdbRemoteTestCaseBase): @@ -93,7 +93,8 @@ class TestGdbRemote_vCont(gdbremote_testcase.GdbRemoteTestCaseBase):          self.single_step_only_steps_one_instruction(use_Hc_packet=True, step_instruction="vCont;s")      @llgs_test -    @expectedFailureAndroid(bugnumber="llvm.com/pr24739", archs=["arm", "aarch64"]) +    @expectedFailureAndroid(bugnumber="llvm.org/pr24739", archs=["arm", "aarch64"]) +    @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr24739")      def test_single_step_only_steps_one_instruction_with_Hc_vCont_s_llgs(self):          self.init_llgs_test()          self.build() @@ -108,7 +109,8 @@ class TestGdbRemote_vCont(gdbremote_testcase.GdbRemoteTestCaseBase):          self.single_step_only_steps_one_instruction(use_Hc_packet=False, step_instruction="vCont;s:{thread}")      @llgs_test -    @expectedFailureAndroid(bugnumber="llvm.com/pr24739", archs=["arm", "aarch64"]) +    @expectedFailureAndroid(bugnumber="llvm.org/pr24739", archs=["arm", "aarch64"]) +    @expectedFailureAll(oslist=["linux"], archs=["arm", "aarch64"], bugnumber="llvm.org/pr24739")      def test_single_step_only_steps_one_instruction_with_vCont_s_thread_llgs(self):          self.init_llgs_test()          self.build() diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py index aec040c50569..c01cc7a17250 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py @@ -19,7 +19,9 @@ import gdbremote_testcase  import lldbgdbserverutils  import platform  import signal +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase): @@ -230,7 +232,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):          self.add_verified_launch_packets(launch_args)          self.test_sequence.add_log_lines(              ["read packet: $vCont;c#a8", -             {"type":"output_match", "regex":r"^hello, world\r\n$" }, +             {"type":"output_match", "regex": self.maybe_strict_output_regex(r"hello, world\r\n")},               "send packet: $W00#00"],              True) @@ -244,6 +246,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):          self.inferior_print_exit()      @llgs_test +    @expectedFlakeyLinux("llvm.org/pr25652")      def test_inferior_print_exit_llgs(self):          self.init_llgs_test()          self.build() @@ -865,7 +868,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):               "read packet: $c#63",               # Match output line that prints the memory address of the message buffer within the inferior.                # Note we require launch-only testing so we can get inferior otuput. -             { "type":"output_match", "regex":r"^data address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"message_address"} }, +             { "type":"output_match", "regex":self.maybe_strict_output_regex(r"data address: 0x([0-9a-fA-F]+)\r\n"), +               "capture":{ 1:"message_address"} },               # Now stop the inferior.               "read packet: {}".format(chr(3)),               # And wait for the stop notification. @@ -947,7 +951,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):               "read packet: $c#63",               # Match output line that prints the memory address of the message buffer within the inferior.                # Note we require launch-only testing so we can get inferior otuput. -             { "type":"output_match", "regex":r"^code address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"code_address"} }, +             { "type":"output_match", "regex":self.maybe_strict_output_regex(r"code address: 0x([0-9a-fA-F]+)\r\n"), +               "capture":{ 1:"code_address"} },               # Now stop the inferior.               "read packet: {}".format(chr(3)),               # And wait for the stop notification. @@ -1008,7 +1013,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):               "read packet: $c#63",               # Match output line that prints the memory address of the message buffer within the inferior.                # Note we require launch-only testing so we can get inferior otuput. -             { "type":"output_match", "regex":r"^stack address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"stack_address"} }, +             { "type":"output_match", "regex":self.maybe_strict_output_regex(r"stack address: 0x([0-9a-fA-F]+)\r\n"), +               "capture":{ 1:"stack_address"} },               # Now stop the inferior.               "read packet: {}".format(chr(3)),               # And wait for the stop notification. @@ -1069,7 +1075,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):               "read packet: $c#63",               # Match output line that prints the memory address of the message buffer within the inferior.                # Note we require launch-only testing so we can get inferior otuput. -             { "type":"output_match", "regex":r"^heap address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"heap_address"} }, +             { "type":"output_match", "regex":self.maybe_strict_output_regex(r"heap address: 0x([0-9a-fA-F]+)\r\n"), +               "capture":{ 1:"heap_address"} },               # Now stop the inferior.               "read packet: {}".format(chr(3)),               # And wait for the stop notification. @@ -1132,7 +1139,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):               "read packet: $c#63",               # Match output line that prints the memory address of the function call entry point.               # Note we require launch-only testing so we can get inferior otuput. -             { "type":"output_match", "regex":r"^code address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"function_address"} }, +             { "type":"output_match", "regex":self.maybe_strict_output_regex(r"code address: 0x([0-9a-fA-F]+)\r\n"), +               "capture":{ 1:"function_address"} },               # Now stop the inferior.               "read packet: {}".format(chr(3)),               # And wait for the stop notification. @@ -1230,6 +1238,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):          self.software_breakpoint_set_and_remove_work()      @llgs_test +    @expectedFlakeyLinux("llvm.org/pr25652")      def test_software_breakpoint_set_and_remove_work_llgs(self):          self.init_llgs_test()          self.build() @@ -1275,7 +1284,8 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):               "read packet: $c#63",               # Match output line that prints the memory address of the message buffer within the inferior.                # Note we require launch-only testing so we can get inferior otuput. -             { "type":"output_match", "regex":r"^data address: 0x([0-9a-fA-F]+)\r\n$", "capture":{ 1:"message_address"} }, +             { "type":"output_match", "regex":self.maybe_strict_output_regex(r"data address: 0x([0-9a-fA-F]+)\r\n"), +               "capture":{ 1:"message_address"} },               # Now stop the inferior.               "read packet: {}".format(chr(3)),               # And wait for the stop notification. @@ -1316,6 +1326,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):          self.written_M_content_reads_back_correctly()      @llgs_test +    @expectedFlakeyLinux("llvm.org/pr25652")      def test_written_M_content_reads_back_correctly_llgs(self):          self.init_llgs_test()          self.build() diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py b/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py index 9035237b982a..6894d1ceacc6 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubReverseConnect.py @@ -6,7 +6,9 @@ import re  import select  import socket  import time +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestStubReverseConnect(gdbremote_testcase.GdbRemoteTestCaseBase): diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py b/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py index 2b2b0e82379b..bda93155d27e 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/commandline/TestStubSetSID.py @@ -8,7 +8,9 @@ import os  import select  import tempfile  import time +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestStubSetSIDTestCase(gdbremote_testcase.GdbRemoteTestCaseBase): @@ -47,7 +49,7 @@ class TestStubSetSIDTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):      @llgs_test      @skipIfRemote # --setsid not used on remote platform and currently it is also impossible to get the sid of lldb-platform running on a remote target -    @expectedFailureFreeBSD() +    @expectedFailureAll(oslist=['freebsd'])      def test_sid_is_same_without_setsid_llgs(self):          self.init_llgs_test()          self.set_inferior_startup_launch() diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py index 113e01e36ba7..d63ddbe39998 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -24,14 +24,16 @@ from lldbsuite.test.lldbtest import *  from lldbgdbserverutils import *  import logging +class _ConnectionRefused(IOError): +    pass +  class GdbRemoteTestCaseBase(TestBase): -    _TIMEOUT_SECONDS = 5 +    NO_DEBUG_INFO_TESTCASE = True -    _GDBREMOTE_KILL_PACKET = "$k#6b" +    _TIMEOUT_SECONDS = 7 -    _LOGGING_LEVEL = logging.WARNING -    # _LOGGING_LEVEL = logging.DEBUG +    _GDBREMOTE_KILL_PACKET = "$k#6b"      # Start the inferior separately, attach to the inferior on the stub command line.      _STARTUP_ATTACH = "attach" @@ -48,12 +50,44 @@ class GdbRemoteTestCaseBase(TestBase):      TARGET_EXC_SOFTWARE        = 0x95      TARGET_EXC_BREAKPOINT      = 0x96 +    _verbose_log_handler = None +    _log_formatter = logging.Formatter(fmt='%(asctime)-15s %(levelname)-8s %(message)s') + +    def setUpBaseLogging(self): +        self.logger = logging.getLogger(__name__) + +        if len(self.logger.handlers) > 0: +            return # We have set up this handler already + +        self.logger.propagate = False +        self.logger.setLevel(logging.DEBUG) + +        # log all warnings to stderr +        handler = logging.StreamHandler() +        handler.setLevel(logging.WARNING) +        handler.setFormatter(self._log_formatter) +        self.logger.addHandler(handler) + + +    def isVerboseLoggingRequested(self): +        # We will report our detailed logs if the user requested that the "gdb-remote" channel is +        # logged. +        return any(("gdb-remote" in channel) for channel in lldbtest_config.channels) +      def setUp(self):          TestBase.setUp(self) -        FORMAT = '%(asctime)-15s %(levelname)-8s %(message)s' -        logging.basicConfig(format=FORMAT) -        self.logger = logging.getLogger(__name__) -        self.logger.setLevel(self._LOGGING_LEVEL) + +        self.setUpBaseLogging() +        self.debug_monitor_extra_args = [] +        self._pump_queues = socket_packet_pump.PumpQueues() + +        if self.isVerboseLoggingRequested(): +            # If requested, full logs go to a log file +            self._verbose_log_handler = logging.FileHandler(self.log_basename + "-host.log") +            self._verbose_log_handler.setFormatter(self._log_formatter) +            self._verbose_log_handler.setLevel(logging.DEBUG) +            self.logger.addHandler(self._verbose_log_handler) +          self.test_sequence = GdbRemoteTestSequence(self.logger)          self.set_inferior_startup_launch()          self.port = self.get_next_port() @@ -76,6 +110,31 @@ class GdbRemoteTestCaseBase(TestBase):          else:              self.stub_hostname = "localhost" +    def tearDown(self): +        self._pump_queues.verify_queues_empty() + +        self.logger.removeHandler(self._verbose_log_handler) +        self._verbose_log_handler = None +        TestBase.tearDown(self) + +    def getLocalServerLogFile(self): +        return self.log_basename + "-server.log" + +    def setUpServerLogging(self, is_llgs): +        if len(lldbtest_config.channels) == 0: +            return # No logging requested + +        if lldb.remote_platform: +            log_file = lldbutil.join_remote_paths(lldb.remote_platform.GetWorkingDirectory(), "server.log") +        else: +            log_file = self.getLocalServerLogFile() + +        if is_llgs: +            self.debug_monitor_extra_args.append("--log-file=" + log_file) +            self.debug_monitor_extra_args.append("--log-channels={}".format(":".join(lldbtest_config.channels))) +        else: +            self.debug_monitor_extra_args = ["--log-file=" + self.log_file, "--log-flags=0x800000"] +      def get_next_port(self):          return 12000 + random.randint(0,3999) @@ -147,30 +206,21 @@ class GdbRemoteTestCaseBase(TestBase):          return stub_port -    def run_shell_cmd(self, cmd): -        platform = self.dbg.GetSelectedPlatform() -        shell_cmd = lldb.SBPlatformShellCommand(cmd) -        err = platform.Run(shell_cmd) -        if err.Fail() or shell_cmd.GetStatus(): -            m = "remote_platform.RunShellCommand('%s') failed:\n" % cmd -            m += ">>> return code: %d\n" % shell_cmd.GetStatus() -            if err.Fail(): -                m += ">>> %s\n" % str(err).strip() -            m += ">>> %s\n" % (shell_cmd.GetOutput() or -                               "Command generated no output.") -            raise Exception(m) -        return shell_cmd.GetOutput().strip() -      def init_llgs_test(self, use_named_pipe=True):          if lldb.remote_platform:              # Remote platforms don't support named pipe based port negotiation              use_named_pipe = False              # Grab the ppid from /proc/[shell pid]/stat -            shell_stat = self.run_shell_cmd("cat /proc/$$/stat") +            err, retcode, shell_stat = self.run_platform_command("cat /proc/$$/stat") +            self.assertTrue(err.Success() and retcode == 0, +                    "Failed to read file /proc/$$/stat: %s, retcode: %d" % (err.GetCString(), retcode)) +              # [pid] ([executable]) [state] [*ppid*]              pid = re.match(r"^\d+ \(.+\) . (\d+)", shell_stat).group(1) -            ls_output = self.run_shell_cmd("ls -l /proc/%s/exe" % pid) +            err, retcode, ls_output = self.run_platform_command("ls -l /proc/%s/exe" % pid) +            self.assertTrue(err.Success() and retcode == 0, +                    "Failed to read file /proc/%s/exe: %s, retcode: %d" % (pid, err.GetCString(), retcode))              exe = ls_output.split()[-1]              # If the binary has been deleted, the link name has " (deleted)" appended. @@ -182,10 +232,7 @@ class GdbRemoteTestCaseBase(TestBase):                  self.skipTest("lldb-server exe not found")          self.debug_monitor_extra_args = ["gdbserver"] - -        if len(lldbtest_config.channels) > 0: -            self.debug_monitor_extra_args.append("--log-file={}-server.log".format(self.log_basename)) -            self.debug_monitor_extra_args.append("--log-channels={}".format(":".join(lldbtest_config.channels))) +        self.setUpServerLogging(is_llgs=True)          if use_named_pipe:              (self.named_pipe_path, self.named_pipe, self.named_pipe_fd) = self.create_named_pipe() @@ -194,7 +241,7 @@ class GdbRemoteTestCaseBase(TestBase):          self.debug_monitor_exe = get_debugserver_exe()          if not self.debug_monitor_exe:              self.skipTest("debugserver exe not found") -        self.debug_monitor_extra_args = ["--log-file={}-server.log".format(self.log_basename), "--log-flags=0x800000"] +        self.setUpServerLogging(is_llgs=False)          if use_named_pipe:              (self.named_pipe_path, self.named_pipe, self.named_pipe_fd) = self.create_named_pipe()          # The debugserver stub has a race on handling the 'k' command, so it sends an X09 right away, then sends the real X notification @@ -209,6 +256,22 @@ class GdbRemoteTestCaseBase(TestBase):          subprocess.call(adb + [ "tcp:%d" % source, "tcp:%d" % target])          self.addTearDownHook(remove_port_forward) +    def _verify_socket(self, sock): +        # Normally, when the remote stub is not ready, we will get ECONNREFUSED during the +        # connect() attempt. However, due to the way how ADB forwarding works, on android targets +        # the connect() will always be successful, but the connection will be immediately dropped +        # if ADB could not connect on the remote side. This function tries to detect this +        # situation, and report it as "connection refused" so that the upper layers attempt the +        # connection again. +        triple = self.dbg.GetSelectedPlatform().GetTriple() +        if not re.match(".*-.*-.*-android", triple): +            return # Not android. +        can_read, _, _ = select.select([sock], [], [], 0.1) +        if sock not in can_read: +            return # Data is not available, but the connection is alive. +        if len(sock.recv(1, socket.MSG_PEEK)) == 0: +            raise _ConnectionRefused() # Got EOF, connection dropped. +      def create_socket(self):          sock = socket.socket()          logger = self.logger @@ -217,8 +280,14 @@ class GdbRemoteTestCaseBase(TestBase):          if re.match(".*-.*-.*-android", triple):              self.forward_adb_port(self.port, self.port, "forward", self.stub_device) +        logger.info("Connecting to debug monitor on %s:%d", self.stub_hostname, self.port)          connect_info = (self.stub_hostname, self.port) -        sock.connect(connect_info) +        try: +            sock.connect(connect_info) +        except socket.error as serr: +            if serr.errno == errno.ECONNREFUSED: +                raise _ConnectionRefused() +            raise serr          def shutdown_socket():              if sock: @@ -235,6 +304,8 @@ class GdbRemoteTestCaseBase(TestBase):          self.addTearDownHook(shutdown_socket) +        self._verify_socket(sock) +          return sock      def set_inferior_startup_launch(self): @@ -258,12 +329,6 @@ class GdbRemoteTestCaseBase(TestBase):              commandline_args += ["--named-pipe", self.named_pipe_path]          return commandline_args -    def run_platform_command(self, cmd): -        platform = self.dbg.GetSelectedPlatform() -        shell_command = lldb.SBPlatformShellCommand(cmd) -        err = platform.Run(shell_command) -        return (err, shell_command.GetOutput()) -      def launch_debug_monitor(self, attach_pid=None, logfile=None):          # Create the command line.          commandline_args = self.get_debug_monitor_command_line_args(attach_pid=attach_pid) @@ -322,12 +387,12 @@ class GdbRemoteTestCaseBase(TestBase):              while connect_attemps < MAX_CONNECT_ATTEMPTS:                  # Create a socket to talk to the server                  try: +                    logger.info("Connect attempt %d", connect_attemps+1)                      self.sock = self.create_socket()                      return server -                except socket.error as serr: -                    # We're only trying to handle connection refused. -                    if serr.errno != errno.ECONNREFUSED: -                        raise serr +                except _ConnectionRefused as serr: +                    # Ignore, and try again. +                    pass                  time.sleep(0.5)                  connect_attemps += 1 @@ -546,7 +611,8 @@ class GdbRemoteTestCaseBase(TestBase):      def expect_gdbremote_sequence(self, timeout_seconds=None):          if not timeout_seconds:              timeout_seconds = self._TIMEOUT_SECONDS -        return expect_lldb_gdbserver_replay(self, self.sock, self.test_sequence, timeout_seconds, self.logger) +        return expect_lldb_gdbserver_replay(self, self.sock, self.test_sequence, +                self._pump_queues, timeout_seconds, self.logger)      _KNOWN_REGINFO_KEYS = [          "name", @@ -556,6 +622,7 @@ class GdbRemoteTestCaseBase(TestBase):          "encoding",          "format",          "set", +        "gcc",          "ehframe",          "dwarf",          "generic", @@ -1281,6 +1348,9 @@ class GdbRemoteTestCaseBase(TestBase):          #MIPS required "3" (ADDIU, SB, LD) machine instructions for updation of variable value          if re.match("mips",arch):             expected_step_count = 3 +        #S390X requires "2" (LARL, MVI) machine instructions for updation of variable value +        if re.match("s390x",arch): +           expected_step_count = 2          self.assertEqual(step_count, expected_step_count)          # Verify we hit the next state. @@ -1297,3 +1367,6 @@ class GdbRemoteTestCaseBase(TestBase):          self.assertTrue(state_reached)          self.assertEqual(step_count, expected_step_count) +    def maybe_strict_output_regex(self, regex): +        return '.*'+regex+'.*' if lldbplatformutil.hasChattyStderr(self) else '^'+regex+'$' + diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py b/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py index d13433252e12..8bd00a3f1b21 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteAbort.py @@ -4,7 +4,9 @@ from __future__ import print_function  import gdbremote_testcase  import signal +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteAbort(gdbremote_testcase.GdbRemoteTestCaseBase):      mydir = TestBase.compute_mydir(__file__) diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py b/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py index 6618d8f75fc9..949b00b0f614 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/inferior-crash/TestGdbRemoteSegFault.py @@ -4,7 +4,9 @@ from __future__ import print_function  import gdbremote_testcase  import signal +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil  class TestGdbRemoteSegFault(gdbremote_testcase.GdbRemoteTestCaseBase):      mydir = TestBase.compute_mydir(__file__) diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py b/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py index c0ea841e2a03..0c73bed9ea0a 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py @@ -154,6 +154,7 @@ def expect_lldb_gdbserver_replay(      asserter,      sock,      test_sequence, +    pump_queues,      timeout_seconds,      logger=None):      """Replay socket communication with lldb-gdbserver and verify responses. @@ -193,7 +194,7 @@ def expect_lldb_gdbserver_replay(          return {}      context = {"O_count":0, "O_content":""} -    with socket_packet_pump.SocketPacketPump(sock, logger) as pump: +    with socket_packet_pump.SocketPacketPump(sock, pump_queues, logger) as pump:          # Grab the first sequence entry.          sequence_entry = test_sequence.entries.pop(0) @@ -220,14 +221,14 @@ def expect_lldb_gdbserver_replay(                  if sequence_entry.is_output_matcher():                      try:                          # Grab next entry from the output queue. -                        content = pump.output_queue().get(True, timeout_seconds) +                        content = pump_queues.output_queue().get(True, timeout_seconds)                      except queue.Empty:                          if logger:                              logger.warning("timeout waiting for stub output (accumulated output:{})".format(pump.get_accumulated_output()))                          raise Exception("timed out while waiting for output match (accumulated output: {})".format(pump.get_accumulated_output()))                  else:                      try: -                        content = pump.packet_queue().get(True, timeout_seconds) +                        content = pump_queues.packet_queue().get(True, timeout_seconds)                      except queue.Empty:                          if logger:                              logger.warning("timeout waiting for packet match (receive buffer: {})".format(pump.get_receive_buffer())) @@ -386,7 +387,10 @@ def pack_register_hex(endian, value, byte_size=None):          return retval      elif endian == 'big': -        retval = value.encode("hex") +        retval = "" +        while value != 0: +            retval = "{:02x}".format(value & 0xff) + retval +            value = value >> 8          if byte_size:              # Add zero-fill to the left/front (MSB side) of the value.              retval = ("00" * (byte_size - len(retval)/2)) + retval @@ -783,7 +787,7 @@ class GdbRemoteTestSequence(object):                      regex = line.get("regex", None)                      # Compile the regex.                      if regex and (type(regex) == str): -                        regex = re.compile(regex) +                        regex = re.compile(regex, re.DOTALL)                      regex_mode = line.get("regex_mode", "match")                      capture = line.get("capture", None) diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py b/packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py index b50a03015462..5c28d288db53 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py @@ -1,8 +1,11 @@  from __future__ import print_function +import time +  import gdbremote_testcase +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * -import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test import lldbutil  class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase):      mydir = TestBase.compute_mydir(__file__) @@ -21,11 +24,22 @@ class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase):          if err.Fail():              raise RuntimeError("Unable copy '%s' to '%s'.\n>>> %s" % (f, wd, err.GetCString())) +        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) +            listen_url = "%s://%s" % (p.group(1), os.path.join(working_dir, "platform-%d.sock" % int(time.time()))) +        else: +            listen_url = "*:0" +          port_file = "%s/port" % working_dir -        commandline_args = ["platform", "--listen", "*:0", "--socket-file", port_file, "--", "%s/a.out" % working_dir, "foo"] +        commandline_args = ["platform", "--listen", listen_url, "--socket-file", port_file, "--", "%s/a.out" % working_dir, "foo"]          self.spawnSubprocess(self.debug_monitor_exe, commandline_args, install_remote=False)          self.addTearDownHook(self.cleanupSubprocesses) -        new_port = self.run_shell_cmd("while [ ! -f %s ]; do sleep 0.25; done && cat %s" % (port_file, port_file)) + +        socket_id = lldbutil.wait_for_file_on_target(self, port_file)          new_debugger = lldb.SBDebugger.Create()          new_debugger.SetAsync(False) @@ -37,8 +51,12 @@ class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase):          new_debugger.SetSelectedPlatform(new_platform)          new_interpreter = new_debugger.GetCommandInterpreter() -        m = re.search("(.*):[0-9]+", configuration.lldb_platform_url) -        command = "platform connect %s:%s" % (m.group(1), new_port) +        if unix_protocol: +            connect_url = "%s://%s%s" % (protocol, hostname, socket_id) +        else: +            connect_url = "%s://%s:%s" % (protocol, hostname, socket_id) + +        command = "platform connect %s" % (connect_url)          result = lldb.SBCommandReturnObject()          new_interpreter.HandleCommand(command, result)          self.assertTrue(result.Succeeded(), "platform process connect failed: %s" % result.GetOutput()) diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py b/packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py index 795a8c6652d0..9f594b7df73c 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/socket_packet_pump.py @@ -26,6 +26,33 @@ def _dump_queue(the_queue):          print(codecs.encode(the_queue.get(True), "string_escape"))          print("\n") +class PumpQueues(object): +    def __init__(self): +        self._output_queue = queue.Queue() +        self._packet_queue = queue.Queue() + +    def output_queue(self): +        return self._output_queue + +    def packet_queue(self): +        return self._packet_queue + +    def verify_queues_empty(self): +        # Warn if there is any content left in any of the queues. +        # That would represent unmatched packets. +        if not self.output_queue().empty(): +            print("warning: output queue entries still exist:") +            _dump_queue(self.output_queue()) +            print("from here:") +            traceback.print_stack() + +        if not self.packet_queue().empty(): +            print("warning: packet queue entries still exist:") +            _dump_queue(self.packet_queue()) +            print("from here:") +            traceback.print_stack() + +  class SocketPacketPump(object):      """A threaded packet reader that partitions packets into two streams. @@ -40,18 +67,17 @@ class SocketPacketPump(object):      _GDB_REMOTE_PACKET_REGEX = re.compile(r'^\$([^\#]*)#[0-9a-fA-F]{2}') -    def __init__(self, pump_socket, logger=None): +    def __init__(self, pump_socket, pump_queues, logger=None):          if not pump_socket:              raise Exception("pump_socket cannot be None") -        self._output_queue = queue.Queue() -        self._packet_queue = queue.Queue()          self._thread = None          self._stop_thread = False          self._socket = pump_socket          self._logger = logger          self._receive_buffer = ""          self._accumulated_output = "" +        self._pump_queues = pump_queues      def __enter__(self):          """Support the python 'with' statement. @@ -66,20 +92,6 @@ class SocketPacketPump(object):          Shut down the pump thread."""          self.stop_pump_thread() -        # Warn if there is any content left in any of the queues. -        # That would represent unmatched packets. -        if not self.output_queue().empty(): -            print("warning: output queue entries still exist:") -            _dump_queue(self.output_queue()) -            print("from here:") -            traceback.print_stack() - -        if not self.packet_queue().empty(): -            print("warning: packet queue entries still exist:") -            _dump_queue(self.packet_queue()) -            print("from here:") -            traceback.print_stack() -      def start_pump_thread(self):          if self._thread:              raise Exception("pump thread is already running") @@ -92,12 +104,6 @@ class SocketPacketPump(object):          if self._thread:              self._thread.join() -    def output_queue(self): -        return self._output_queue - -    def packet_queue(self): -        return self._packet_queue -      def _process_new_bytes(self, new_bytes):          if not new_bytes:              return @@ -114,7 +120,7 @@ class SocketPacketPump(object):                  has_more = False              # handle '+' ack              elif self._receive_buffer[0] == "+": -                self._packet_queue.put("+") +                self._pump_queues.packet_queue().put("+")                  self._receive_buffer = self._receive_buffer[1:]                  if self._logger:                      self._logger.debug( @@ -132,10 +138,10 @@ class SocketPacketPump(object):                      if new_output_content:                          # This was an $O packet with new content.                          self._accumulated_output += new_output_content -                        self._output_queue.put(self._accumulated_output) +                        self._pump_queues.output_queue().put(self._accumulated_output)                      else:                          # Any packet other than $O. -                        self._packet_queue.put(packet_match.group(0)) +                        self._pump_queues.packet_queue().put(packet_match.group(0))                      # Remove the parsed packet from the receive                      # buffer. @@ -173,7 +179,7 @@ class SocketPacketPump(object):                      # Likely a closed socket.  Done with the pump thread.                      if self._logger:                          self._logger.debug( -                            "socket read failed, stopping pump read thread") +                            "socket read failed, stopping pump read thread\n" + traceback.format_exc(3))                      break                  self._process_new_bytes(new_bytes) | 
