Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/extract/src/memento.py @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 #!/usr/bin/env python3 | |
| 2 | |
| 3 ''' | |
| 4 Post-processor for Memento. | |
| 5 | |
| 6 Usage: | |
| 7 memento.py <args> [<command> ...] | |
| 8 | |
| 9 Args: | |
| 10 -q <quiet> | |
| 11 Controls how often we output 'Memory squeezing @ ...' lines. E.g. '-q | |
| 12 10' outputs for multiples of 10. | |
| 13 | |
| 14 If <command> is specified we run it and look at the output. Otherwise we assume | |
| 15 that Memento output is available on our stdin. | |
| 16 ''' | |
| 17 | |
| 18 import os | |
| 19 import re | |
| 20 import subprocess | |
| 21 import sys | |
| 22 | |
| 23 | |
| 24 def main(): | |
| 25 quiet = 1 | |
| 26 quiet_next = 0 | |
| 27 out_raw = None | |
| 28 command = None | |
| 29 args = iter(sys.argv[1:]) | |
| 30 while 1: | |
| 31 try: | |
| 32 arg = next(args) | |
| 33 except StopIteration: | |
| 34 break | |
| 35 if arg == '-h': | |
| 36 print(__doc__) | |
| 37 elif arg == '-o': | |
| 38 out_raw = open(next(args), 'w') | |
| 39 elif arg == '-q': | |
| 40 quiet = int(next(args)) | |
| 41 elif arg.startswith('-'): | |
| 42 raise Exception(f'unrecognised arg: {arg}') | |
| 43 else: | |
| 44 command = arg | |
| 45 for a in args: | |
| 46 command += f' {a}' | |
| 47 | |
| 48 if command: | |
| 49 print(f'Running: {command}') | |
| 50 child = subprocess.Popen( | |
| 51 command, | |
| 52 stdout=subprocess.PIPE, | |
| 53 stderr=subprocess.STDOUT, | |
| 54 shell=True, | |
| 55 text=True, | |
| 56 ) | |
| 57 stdin = child.stdout | |
| 58 else: | |
| 59 stdin = sys.stdin | |
| 60 | |
| 61 openbsd = os.uname()[0] == 'OpenBSD' | |
| 62 n = None | |
| 63 segv = 0 | |
| 64 leaks = 0 | |
| 65 lines = [] | |
| 66 for line in stdin: | |
| 67 if out_raw: | |
| 68 out_raw.write(line) | |
| 69 m = re.match('^Memory squeezing @ ([0-9]+)( complete)?', line) | |
| 70 if m: | |
| 71 if not m.group(2): | |
| 72 # Start of squeeze. | |
| 73 | |
| 74 if 0 and not openbsd: | |
| 75 # Looks like memento's forked processes might terminate | |
| 76 # before they get to output the 'Memory squeezing @ <N> | |
| 77 # complete' line. | |
| 78 # | |
| 79 assert n is None, f'n={n} line={line!r}' | |
| 80 | |
| 81 n = int(m.group(1)) | |
| 82 if n >= quiet_next: | |
| 83 sys.stdout.write(f'quiet_next={quiet_next!r} n={n!r}: {line}') | |
| 84 sys.stdout.flush() | |
| 85 quiet_next = (n + quiet) // quiet * quiet | |
| 86 else: | |
| 87 # End of squeeze. | |
| 88 assert n == int(m.group(1)) | |
| 89 # Output info about any failure: | |
| 90 if segv or leaks: | |
| 91 print(f'Failure at squeeze {n}: segv={segv} leaks={leaks}:') | |
| 92 for l in lines: | |
| 93 if l.endswith('\n'): | |
| 94 l = l[:-1] | |
| 95 print(f' {l}') | |
| 96 if command: | |
| 97 print(f'Examine with: MEMENTO_FAILAT={n} {command}') | |
| 98 lines = [] | |
| 99 segv = 0 | |
| 100 leaks = 0 | |
| 101 n = None | |
| 102 else: | |
| 103 if n is not None: | |
| 104 lines.append(line) | |
| 105 if line.startswith('SEGV at:'): | |
| 106 segv = 1 | |
| 107 if line.startswith('Allocated blocks'): | |
| 108 leaks = 1 | |
| 109 | |
| 110 | |
| 111 if __name__ == '__main__': | |
| 112 main() |
