Author: Jonas Devlieghere Date: 2019-10-29T16:56:59-07:00 New Revision: 8a82000e486afe472519d288f2206399ada95aca
URL: https://github.com/llvm/llvm-project/commit/8a82000e486afe472519d288f2206399ada95aca DIFF: https://github.com/llvm/llvm-project/commit/8a82000e486afe472519d288f2206399ada95aca.diff LOG: [lldbsuite] Remove pre_kill_hook package This package was only used by dosep.py which has since been removed. Added: Modified: Removed: lldb/packages/Python/lldbsuite/pre_kill_hook/README.md lldb/packages/Python/lldbsuite/pre_kill_hook/__init__.py lldb/packages/Python/lldbsuite/pre_kill_hook/darwin.py lldb/packages/Python/lldbsuite/pre_kill_hook/linux.py lldb/packages/Python/lldbsuite/pre_kill_hook/tests/__init__.py lldb/packages/Python/lldbsuite/pre_kill_hook/tests/test_darwin.py lldb/packages/Python/lldbsuite/pre_kill_hook/tests/test_linux.py ################################################################################ diff --git a/lldb/packages/Python/lldbsuite/pre_kill_hook/README.md b/lldb/packages/Python/lldbsuite/pre_kill_hook/README.md deleted file mode 100644 index 921eedb4a869..000000000000 --- a/lldb/packages/Python/lldbsuite/pre_kill_hook/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# pre\_kill\_hook package - -## Overview - -The pre\_kill\_hook package provides a per-platform method for running code -after a test process times out but before the concurrent test runner kills the -timed-out process. - -## Detailed Description of Usage - -If a platform defines the hook, then the hook gets called right after a timeout -is detected in a test run, but before the process is killed. - -The pre-kill-hook mechanism works as follows: - -* When a timeout is detected in the process_control.ProcessDriver class that - runs the per-test lldb process, a new overridable on\_timeout\_pre\_kill() method - is called on the ProcessDriver instance. - -* The concurrent test driver's derived ProcessDriver overrides this method. It - looks to see if a module called - "lldbsuite.pre\_kill\_hook.{platform-system-name}" module exists, where - platform-system-name is replaced with platform.system().lower(). (e.g. - "Darwin" becomes the darwin.py module). - - * If that module doesn't exist, the rest of the new behavior is skipped. - - * If that module does exist, it is loaded, and the method - "do\_pre\_kill(process\_id, context\_dict, output\_stream)" is called. If - that method throws an exception, we log it and we ignore further processing - of the pre-killed process. - - * The process\_id argument of the do\_pre\_kill function is the process id as - returned by the ProcessDriver.pid property. - - * The output\_stream argument of the do\_pre\_kill function takes a file-like - object. Output to be collected from doing any processing on the - process-to-be-killed should be written into the file-like object. The - current impl uses a six.StringIO and then writes this output to - {TestFilename}-{pid}.sample in the session directory. - -* Platforms where platform.system() is "Darwin" will get a pre-kill action that - runs the 'sample' program on the lldb that has timed out. That data will be - collected on CI and analyzed to determine what is happening during timeouts. - (This has an advantage over a core in that it is much smaller and that it - clearly demonstrates any liveness of the process, if there is any). - -## Running the tests - -To run the tests in the pre\_kill\_hook package, open a console, change into -this directory and run the following: - -``` -python -m unittest discover -``` diff --git a/lldb/packages/Python/lldbsuite/pre_kill_hook/__init__.py b/lldb/packages/Python/lldbsuite/pre_kill_hook/__init__.py deleted file mode 100644 index c3a852ea1bfe..000000000000 --- a/lldb/packages/Python/lldbsuite/pre_kill_hook/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Initialize the package.""" diff --git a/lldb/packages/Python/lldbsuite/pre_kill_hook/darwin.py b/lldb/packages/Python/lldbsuite/pre_kill_hook/darwin.py deleted file mode 100644 index 2bee65a01e3f..000000000000 --- a/lldb/packages/Python/lldbsuite/pre_kill_hook/darwin.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Provides a pre-kill method to run on macOS.""" -from __future__ import print_function - -# system imports -import subprocess -import sys - -# third-party module imports -import six - - -def do_pre_kill(process_id, runner_context, output_stream, sample_time=3): - """Samples the given process id, and puts the output to output_stream. - - @param process_id the local process to sample. - - @param runner_context a dictionary of details about the architectures - and platform on which the given process is running. Expected keys are - archs (array of architectures), platform_name, platform_url, and - platform_working_dir. - - @param output_stream file-like object that should be used to write the - results of sampling. - - @param sample_time specifies the time in seconds that should be captured. - """ - - # Validate args. - if runner_context is None: - raise Exception("runner_context argument is required") - if not isinstance(runner_context, dict): - raise Exception("runner_context argument must be a dictionary") - - # We will try to run sample on the local host only if there is no URL - # to a remote. - if "platform_url" in runner_context and ( - runner_context["platform_url"] is not None): - import pprint - sys.stderr.write( - "warning: skipping timeout pre-kill sample invocation because we " - "don't know how to run on a remote yet. runner_context={}\n" - .format(pprint.pformat(runner_context))) - - output = subprocess.check_output(['sample', six.text_type(process_id), - str(sample_time)]) - output_stream.write(output) diff --git a/lldb/packages/Python/lldbsuite/pre_kill_hook/linux.py b/lldb/packages/Python/lldbsuite/pre_kill_hook/linux.py deleted file mode 100644 index d4cd9be27c82..000000000000 --- a/lldb/packages/Python/lldbsuite/pre_kill_hook/linux.py +++ /dev/null @@ -1,76 +0,0 @@ -"""Provides a pre-kill method to run on Linux. - -This timeout pre-kill method relies on the Linux perf-tools -distribution. The appropriate way to obtain this set of tools -will depend on the Linux distribution. - -For Ubuntu 16.04, the invoke the following command: -sudo apt-get install perf-tools-unstable -""" -from __future__ import print_function - -# system imports -import os -import subprocess -import sys -import tempfile - - -def do_pre_kill(process_id, runner_context, output_stream, sample_time=3): - """Samples the given process id, and puts the output to output_stream. - - @param process_id the local process to sample. - - @param runner_context a dictionary of details about the architectures - and platform on which the given process is running. Expected keys are - archs (array of architectures), platform_name, platform_url, and - platform_working_dir. - - @param output_stream file-like object that should be used to write the - results of sampling. - - @param sample_time specifies the time in seconds that should be captured. - """ - - # Validate args. - if runner_context is None: - raise Exception("runner_context argument is required") - if not isinstance(runner_context, dict): - raise Exception("runner_context argument must be a dictionary") - - # We will try to run sample on the local host only if there is no URL - # to a remote. - if "platform_url" in runner_context and ( - runner_context["platform_url"] is not None): - import pprint - sys.stderr.write( - "warning: skipping timeout pre-kill sample invocation because we " - "don't know how to run on a remote yet. runner_context={}\n" - .format(pprint.pformat(runner_context))) - - # We're going to create a temp file, and immediately overwrite it with the - # following command. This just ensures we don't have any races in - # creation of the temporary sample file. - fileno, filename = tempfile.mkstemp(suffix='perfdata') - os.close(fileno) - fileno = None - - try: - with open(os.devnull, 'w') as devnull: - returncode = subprocess.call(['timeout', str(sample_time), 'perf', - 'record', '-g', '-o', filename, '-p', str(process_id)], - stdout=devnull, stderr=devnull) - if returncode == 0 or returncode == 124: - # This is okay - this is the timeout return code, which is totally - # expected. - pass - else: - raise Exception("failed to call 'perf record .., error: {}".format( - returncode)) - - with open(os.devnull, 'w') as devnull: - output = subprocess.check_output(['perf', 'report', '--call-graph', - '--stdio', '-i', filename], stderr=devnull) - output_stream.write(output) - finally: - os.remove(filename) diff --git a/lldb/packages/Python/lldbsuite/pre_kill_hook/tests/__init__.py b/lldb/packages/Python/lldbsuite/pre_kill_hook/tests/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/lldb/packages/Python/lldbsuite/pre_kill_hook/tests/test_darwin.py b/lldb/packages/Python/lldbsuite/pre_kill_hook/tests/test_darwin.py deleted file mode 100644 index 810b364b07c3..000000000000 --- a/lldb/packages/Python/lldbsuite/pre_kill_hook/tests/test_darwin.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Test the pre-kill hook on Darwin.""" -from __future__ import print_function - -# system imports -from multiprocessing import Process, Queue -import platform -import re -from unittest import main, TestCase - -# third party -from six import StringIO - - -def do_child_process(child_work_queue, parent_work_queue, verbose): - import os - - pid = os.getpid() - if verbose: - print("child: pid {} started, sending to parent".format(pid)) - parent_work_queue.put(pid) - if verbose: - print("child: waiting for shut-down request from parent") - child_work_queue.get() - if verbose: - print("child: received shut-down request. Child exiting.") - - -class DarwinPreKillTestCase(TestCase): - - def __init__(self, methodName): - super(DarwinPreKillTestCase, self).__init__(methodName) - self.process = None - self.child_work_queue = None - self.verbose = False - - def tearDown(self): - if self.verbose: - print("parent: sending shut-down request to child") - if self.process: - self.child_work_queue.put("hello, child") - self.process.join() - if self.verbose: - print("parent: child is fully shut down") - - def test_sample(self): - # Ensure we're Darwin. - if platform.system() != 'Darwin': - self.skipTest("requires a Darwin-based OS") - - # Start the child process. - self.child_work_queue = Queue() - parent_work_queue = Queue() - self.process = Process(target=do_child_process, - args=(self.child_work_queue, parent_work_queue, - self.verbose)) - if self.verbose: - print("parent: starting child") - self.process.start() - - # Wait for the child to report its pid. Then we know we're running. - if self.verbose: - print("parent: waiting for child to start") - child_pid = parent_work_queue.get() - - # Sample the child process. - from darwin import do_pre_kill - context_dict = { - "archs": [platform.machine()], - "platform_name": None, - "platform_url": None, - "platform_working_dir": None - } - - if self.verbose: - print("parent: running pre-kill action on child") - output_io = StringIO() - do_pre_kill(child_pid, context_dict, output_io) - output = output_io.getvalue() - - if self.verbose: - print("parent: do_pre_kill() wrote the following output:", output) - self.assertIsNotNone(output) - - # We should have a line with: - # Process: .* [{pid}] - process_re = re.compile(r"Process:[^[]+\[([^]]+)\]") - match = process_re.search(output) - self.assertIsNotNone(match, "should have found process id for " - "sampled process") - self.assertEqual(1, len(match.groups())) - self.assertEqual(child_pid, int(match.group(1))) - - # We should see a Call graph: section. - callgraph_re = re.compile(r"Call graph:") - match = callgraph_re.search(output) - self.assertIsNotNone(match, "should have found the Call graph section" - "in sample output") - - # We should see a Binary Images: section. - binary_images_re = re.compile(r"Binary Images:") - match = binary_images_re.search(output) - self.assertIsNotNone(match, "should have found the Binary Images " - "section in sample output") - - -if __name__ == "__main__": - main() diff --git a/lldb/packages/Python/lldbsuite/pre_kill_hook/tests/test_linux.py b/lldb/packages/Python/lldbsuite/pre_kill_hook/tests/test_linux.py deleted file mode 100644 index ab989df0d203..000000000000 --- a/lldb/packages/Python/lldbsuite/pre_kill_hook/tests/test_linux.py +++ /dev/null @@ -1,133 +0,0 @@ -"""Test the pre-kill hook on Linux.""" -from __future__ import print_function - -# system imports -from multiprocessing import Process, Queue -import platform -import re -import subprocess -from unittest import main, TestCase - -# third party -from six import StringIO - - -def do_child_thread(): - import os - x = 0 - while True: - x = x + 42 * os.getpid() - return x - - -def do_child_process(child_work_queue, parent_work_queue, verbose): - import os - - pid = os.getpid() - if verbose: - print("child: pid {} started, sending to parent".format(pid)) - parent_work_queue.put(pid) - - # Spin up a daemon thread to do some "work", which will show - # up in a sample of this process. - import threading - worker = threading.Thread(target=do_child_thread) - worker.daemon = True - worker.start() - - if verbose: - print("child: waiting for shut-down request from parent") - child_work_queue.get() - if verbose: - print("child: received shut-down request. Child exiting.") - - -class LinuxPreKillTestCase(TestCase): - - def __init__(self, methodName): - super(LinuxPreKillTestCase, self).__init__(methodName) - self.process = None - self.child_work_queue = None - self.verbose = False - # self.verbose = True - - def tearDown(self): - if self.verbose: - print("parent: sending shut-down request to child") - if self.process: - self.child_work_queue.put("hello, child") - self.process.join() - if self.verbose: - print("parent: child is fully shut down") - - def test_sample(self): - # Ensure we're Darwin. - if platform.system() != 'Linux': - self.skipTest("requires a Linux-based OS") - - # Ensure we have the 'perf' tool. If not, skip the test. - try: - perf_version = subprocess.check_output(["perf", "version"]) - if perf_version is None or not ( - perf_version.startswith("perf version")): - raise Exception("The perf executable doesn't appear" - " to be the Linux perf tools perf") - except Exception: - self.skipTest("requires the Linux perf tools 'perf' command") - - # Start the child process. - self.child_work_queue = Queue() - parent_work_queue = Queue() - self.process = Process(target=do_child_process, - args=(self.child_work_queue, parent_work_queue, - self.verbose)) - if self.verbose: - print("parent: starting child") - self.process.start() - - # Wait for the child to report its pid. Then we know we're running. - if self.verbose: - print("parent: waiting for child to start") - child_pid = parent_work_queue.get() - - # Sample the child process. - from linux import do_pre_kill - context_dict = { - "archs": [platform.machine()], - "platform_name": None, - "platform_url": None, - "platform_working_dir": None - } - - if self.verbose: - print("parent: running pre-kill action on child") - output_io = StringIO() - do_pre_kill(child_pid, context_dict, output_io) - output = output_io.getvalue() - - if self.verbose: - print("parent: do_pre_kill() wrote the following output:", output) - self.assertIsNotNone(output) - - # We should have a samples count entry. - # Samples: - self.assertTrue("Samples:" in output, "should have found a 'Samples:' " - "field in the sampled process output") - - # We should see an event count entry - event_count_re = re.compile(r"Event count[^:]+:\s+(\d+)") - match = event_count_re.search(output) - self.assertIsNotNone(match, "should have found the event count entry " - "in sample output") - if self.verbose: - print("cpu-clock events:", match.group(1)) - - # We should see some percentages in the file. - percentage_re = re.compile(r"\d+\.\d+%") - match = percentage_re.search(output) - self.assertIsNotNone(match, "should have found at least one percentage " - "in the sample output") - - -if __name__ == "__main__": - main() _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits