Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | #! /usr/bin/python |
michael@0 | 2 | |
michael@0 | 3 | """This script takes the file produced by DMD's test mode and checks its |
michael@0 | 4 | correctness. |
michael@0 | 5 | |
michael@0 | 6 | It produces the following output files: $TMP/test-{fixed,filtered,diff}.dmd. |
michael@0 | 7 | |
michael@0 | 8 | It runs the appropriate fix* script to get nice stack traces. It also |
michael@0 | 9 | filters out platform-specific details from the test output file. |
michael@0 | 10 | |
michael@0 | 11 | Note: you must run this from the same directory that you invoked DMD's test |
michael@0 | 12 | mode, otherwise the fix* script will not work properly, because some of the |
michael@0 | 13 | paths in the test output are relative. |
michael@0 | 14 | |
michael@0 | 15 | """ |
michael@0 | 16 | |
michael@0 | 17 | from __future__ import print_function |
michael@0 | 18 | |
michael@0 | 19 | import os |
michael@0 | 20 | import platform |
michael@0 | 21 | import re |
michael@0 | 22 | import subprocess |
michael@0 | 23 | import sys |
michael@0 | 24 | import tempfile |
michael@0 | 25 | |
michael@0 | 26 | |
michael@0 | 27 | def main(): |
michael@0 | 28 | |
michael@0 | 29 | # Arguments |
michael@0 | 30 | |
michael@0 | 31 | if (len(sys.argv) != 3): |
michael@0 | 32 | print("usage:", sys.argv[0], "<topsrcdir> <test.dmd>") |
michael@0 | 33 | sys.exit(1) |
michael@0 | 34 | |
michael@0 | 35 | srcdir = sys.argv[1] |
michael@0 | 36 | |
michael@0 | 37 | # Filenames |
michael@0 | 38 | |
michael@0 | 39 | tempdir = tempfile.gettempdir() |
michael@0 | 40 | in_name = sys.argv[2] |
michael@0 | 41 | fixed_name = tempdir + os.sep + "test-fixed.dmd" |
michael@0 | 42 | filtered_name = tempdir + os.sep + "test-filtered.dmd" |
michael@0 | 43 | diff_name = tempdir + os.sep + "test-diff.dmd" |
michael@0 | 44 | expected_name = srcdir + os.sep + \ |
michael@0 | 45 | "memory/replace/dmd/test-expected.dmd" |
michael@0 | 46 | |
michael@0 | 47 | # Fix stack traces |
michael@0 | 48 | |
michael@0 | 49 | print("fixing output to", fixed_name) |
michael@0 | 50 | |
michael@0 | 51 | sysname = platform.system() |
michael@0 | 52 | if sysname == "Linux": |
michael@0 | 53 | fix = srcdir + os.sep + "tools/rb/fix-linux-stack.pl" |
michael@0 | 54 | elif sysname == "Darwin": |
michael@0 | 55 | fix = srcdir + os.sep + "tools/rb/fix_macosx_stack.py" |
michael@0 | 56 | else: |
michael@0 | 57 | print("unhandled platform: " + sysname, file=sys.stderr) |
michael@0 | 58 | sys.exit(1) |
michael@0 | 59 | |
michael@0 | 60 | subprocess.call(fix, stdin=open(in_name, "r"), |
michael@0 | 61 | stdout=open(fixed_name, "w")) |
michael@0 | 62 | |
michael@0 | 63 | # Filter output |
michael@0 | 64 | |
michael@0 | 65 | # In stack trace records we filter out most stack frames. The only thing |
michael@0 | 66 | # we leave behind is a "DMD.cpp" entry if we see one or more frames that |
michael@0 | 67 | # have DMD.cpp in them. There is simply too much variation to do anything |
michael@0 | 68 | # better than that. |
michael@0 | 69 | # |
michael@0 | 70 | # As for stack frame records, alas, we filter them out entirely because |
michael@0 | 71 | # they have even more variation. |
michael@0 | 72 | |
michael@0 | 73 | print("filtering output to", filtered_name) |
michael@0 | 74 | |
michael@0 | 75 | with open(fixed_name, "r") as fin, \ |
michael@0 | 76 | open(filtered_name, "w") as fout: |
michael@0 | 77 | |
michael@0 | 78 | test_frame_re = re.compile(r".*(DMD.cpp)") |
michael@0 | 79 | |
michael@0 | 80 | for line in fin: |
michael@0 | 81 | if re.match(r" (Allocated at|Reported( again)? at)", line): |
michael@0 | 82 | # It's a stack trace record. |
michael@0 | 83 | print(line, end='', file=fout) |
michael@0 | 84 | |
michael@0 | 85 | # Filter the stack trace -- print a single line if we see one |
michael@0 | 86 | # or more frames involving DMD.cpp. |
michael@0 | 87 | seen_DMD_frame = False |
michael@0 | 88 | for frame in fin: |
michael@0 | 89 | if re.match(r" ", frame): |
michael@0 | 90 | m = test_frame_re.match(frame) |
michael@0 | 91 | if m: |
michael@0 | 92 | seen_DMD_frame = True |
michael@0 | 93 | else: |
michael@0 | 94 | # We're past the stack trace. |
michael@0 | 95 | if seen_DMD_frame: |
michael@0 | 96 | print(" ... DMD.cpp", file=fout) |
michael@0 | 97 | print(frame, end='', file=fout) |
michael@0 | 98 | break |
michael@0 | 99 | |
michael@0 | 100 | elif re.search("in stack frame record", line): |
michael@0 | 101 | # Stack frame record. Get the whole thing (we know how many |
michael@0 | 102 | # lines it has). |
michael@0 | 103 | line2 = fin.next() |
michael@0 | 104 | line3 = fin.next() |
michael@0 | 105 | line4 = fin.next() |
michael@0 | 106 | line5 = fin.next() |
michael@0 | 107 | line6 = fin.next() |
michael@0 | 108 | |
michael@0 | 109 | else: |
michael@0 | 110 | # A line that needs no special handling. Copy it through. |
michael@0 | 111 | print(line, end='', file=fout) |
michael@0 | 112 | |
michael@0 | 113 | # Compare with expected output |
michael@0 | 114 | |
michael@0 | 115 | print("diffing output to", diff_name) |
michael@0 | 116 | |
michael@0 | 117 | ret = subprocess.call(["diff", "-u", expected_name, filtered_name], |
michael@0 | 118 | stdout=open(diff_name, "w")) |
michael@0 | 119 | |
michael@0 | 120 | if ret == 0: |
michael@0 | 121 | print("test PASSED") |
michael@0 | 122 | else: |
michael@0 | 123 | print("test FAILED (did you remember to run this script and Firefox " |
michael@0 | 124 | "in the same directory?)") |
michael@0 | 125 | |
michael@0 | 126 | |
michael@0 | 127 | if __name__ == "__main__": |
michael@0 | 128 | main() |