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 7b974e548a581..1296d513b9171 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 ca96a9a837b93..5460b21382ec4 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 1ce5779e78979..e70ad5f570a7f 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 6535ce40475d6..7daae871caf69 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 b253254c78edc..560da9d414292 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 a11167b87c25b..f26b62043613d 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 a36b4ae781ada..63a8995c67295 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 3b008249f5570..31d53bed2593d 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 a7938795b9bf5..d55416569ac41 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 cce484451de47..b2b54e3f03942 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 579e99d6d774c..335d96c2b074f 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 aec040c50569a..c01cc7a172505 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 9035237b982a4..6894d1ceacc68 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 2b2b0e82379b3..bda93155d27e1 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 113e01e36ba7a..d63ddbe399989 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 d13433252e12e..8bd00a3f1b216 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 6618d8f75fc95..949b00b0f614c 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 c0ea841e2a03e..0c73bed9ea0a5 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 b50a030154628..5c28d288db53b 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 795a8c6652d0b..9f594b7df73c9 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) |