Last active
May 17, 2026 17:21
-
-
Save FrostyX/73379ff510cd7acf897925199575299e to your computer and use it in GitHub Desktop.
Resalloc subprocess timeout reproducer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 -u | |
| import time | |
| print("LINE1") | |
| print("LINE2") | |
| time.sleep(99999) | |
| print("LINE3") | |
| print("LINE4") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 | |
| print("PREFIX LINE1") | |
| print("PREFIX LINE2") | |
| print("PREFIX LINE3") | |
| print("PREFIX LINE4") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 | |
| import time | |
| time.sleep(99999) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 -u | |
| import sys | |
| sys.stdout.write("No newline at the end") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 | |
| print("LINE1") | |
| print("LINE2") | |
| print("LINE3") | |
| print("LINE4") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python3 -u | |
| import sys | |
| sys.stdout.write("LINE1\n") | |
| sys.stderr.write("LINE2\n") | |
| sys.stdout.write("LINE3\n") | |
| sys.stderr.write("LINE4\n") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import select | |
| import subprocess | |
| import time | |
| def run_command(): | |
| timeout=5 | |
| stdout_written = 0 | |
| stdout_stopped = False | |
| catch_stdout_bytes = 5120 | |
| catch_stdout_lines_securely = True | |
| command = ["./resalloc-timeout-reproducer-ok"] | |
| command = ["./resalloc-timeout-reproducer-no-bytes"] | |
| command = ["./resalloc-timeout-reproducer-no-eof"] | |
| command = ["./resalloc-timeout-reproducer-no-bytes-hang-forever"] | |
| command = ["./resalloc-timeout-reproducer-hang-after-output"] | |
| command = ["./resalloc-timeout-reproducer-multiple-words"] | |
| command = ["./resalloc-timeout-reproducer-stderr"] | |
| with subprocess.Popen(command, stdout=subprocess.PIPE) as sp: | |
| captured_string = b"" | |
| deadline = time.monotonic() + timeout | |
| buffer = b"" | |
| while True: | |
| # How many seconds are left before we want to timeout | |
| remaining = deadline - time.monotonic() | |
| if remaining <= 0: | |
| sp.kill() | |
| break | |
| # Either we get a readable file descriptors back or we get nothing | |
| # because the `select` timeouted on `read` | |
| ready, _, _ = select.select([sp.stdout], [], [], remaining) | |
| if not ready: | |
| sp.kill() | |
| break | |
| chunk = os.read(sp.stdout.fileno(), 4096) | |
| eof = chunk == b'' | |
| # We successfully read a chunk of data | |
| if not eof: | |
| buffer += chunk | |
| # We encountered EOF but we still have unprocessed bytes | |
| elif buffer: | |
| # Treat partial line as a complete line | |
| # TODO do we want this or rather discard the incomplete line? | |
| buffer += b'\n' | |
| # We encountered EOF and we already processed everything | |
| else: | |
| break | |
| # Process all complete lines from buffer | |
| while b'\n' in buffer: | |
| line, buffer = buffer.split(b'\n', 1) | |
| line += b'\n' | |
| # Write to the log. | |
| # logfile.write(line) | |
| # logfile.flush() | |
| if stdout_stopped: | |
| continue | |
| if stdout_written + len(line) > catch_stdout_bytes: | |
| if stdout_written == 0 and not catch_stdout_lines_securely: | |
| # Even the first line is too long for this buffer. Catch at | |
| # least part of it. | |
| line = line[:catch_stdout_bytes] | |
| captured_string += line | |
| stdout_stopped = True | |
| if not catch_stdout_lines_securely: | |
| captured_string += b"<< trimmed >>\n" | |
| continue | |
| stdout_written += len(line) | |
| captured_string += line | |
| # This is to handle EOF after processing a partial line | |
| if eof: | |
| break | |
| return { | |
| 'status': sp.wait(), | |
| 'stdout': captured_string, | |
| } | |
| if __name__ == "__main__": | |
| result = run_command() | |
| print(f"STATUS: {result["status"]}") | |
| print(f"STDOUT: {result["stdout"]}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment