Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python2 | |
| 2 import argparse | |
| 3 import os | |
| 4 import signal | |
| 5 import subprocess | |
|
John
2016/07/20 14:50:08
add an empty line
manasijm
2016/07/20 21:15:24
Done.
| |
| 6 num_tries = 0 # Counts no. of iterations | |
| 7 find_all = True | |
| 8 def build_command(input_cmd, include_ranges): | |
|
John
2016/07/20 16:11:58
why not have build command return an object:
def
manasijm
2016/07/20 21:15:24
Done. Thanks!
| |
| 9 result = input_cmd | |
| 10 for i in include_ranges: | |
| 11 result = result + " -i " + str(i[0])+":"+str(i[1] + 1) | |
|
Jim Stichnoth
2016/07/20 18:32:02
For more awesomeness, I would really like it if on
manasijm
2016/07/20 21:49:31
Done.
| |
| 12 return result | |
| 13 | |
| 14 def run(cmd, include_ranges, timeout): | |
| 15 #TODO(manasijm): Figure out how to parallelize, not sure how important. | |
| 16 run_str = build_command(cmd, include_ranges) | |
| 17 print run_str | |
| 18 global num_tries | |
| 19 num_tries = num_tries + 1 | |
| 20 | |
| 21 class Timeout(Exception): | |
|
John
2016/07/20 14:50:08
No need for this class, just
raise Exception("tim
manasijm
2016/07/20 21:15:24
Done.
| |
| 22 pass | |
| 23 def timeout_handler(signum, frame): | |
| 24 raise Timeout | |
| 25 p = subprocess.Popen(run_str, shell = True, cwd = None, | |
| 26 stdout = subprocess.PIPE, stderr = subprocess.PIPE, env = None) | |
| 27 if timeout != -1: | |
| 28 signal.signal(signal.SIGALRM, timeout_handler) | |
| 29 signal.alarm(timeout) | |
| 30 try: | |
| 31 stdout, stderr = p.communicate() | |
| 32 if timeout != -1: | |
| 33 signal.alarm(0) | |
| 34 except Timeout: | |
| 35 try: | |
| 36 os.kill(p.pid, signal.SIGKILL) | |
| 37 except OSError: | |
| 38 pass | |
| 39 print "Timeout" | |
| 40 return -9 | |
| 41 print p.returncode | |
|
John
2016/07/20 14:50:08
remove this print, it will get lost in the script'
manasijm
2016/07/20 21:15:24
It seems helpful to determine how close the script
John
2016/07/20 22:23:05
Maybe add a string describing what's going on, the
| |
| 42 return p.returncode | |
| 43 | |
| 44 def find_crashes(cmd, include_ranges, timeout) : | |
| 45 main_range = include_ranges[0] | |
| 46 if main_range[0] == main_range[1]: | |
|
John
2016/07/20 14:50:08
Are you sure this is what you want to do here? I w
manasijm
2016/07/20 21:15:24
Acknowledged.
| |
| 47 return [main_range[0]] | |
| 48 mid = (main_range[0] + main_range[1])/2 | |
| 49 | |
| 50 first_half = (main_range[0], mid) | |
| 51 second_half = (mid + 1, main_range[1]) | |
| 52 | |
| 53 exit_code_2 = 0 | |
| 54 exit_code_1 = run(cmd, [first_half] + include_ranges[1:], timeout) | |
|
John
2016/07/20 14:50:08
I personally would discourage using recursion for
| |
| 55 if find_all or exit_code_1 == 0 : | |
| 56 exit_code_2 = run(cmd, [second_half]+ include_ranges[1:], timeout) | |
| 57 | |
| 58 if exit_code_1 == 0 and exit_code_2 == 0: | |
|
John
2016/07/20 14:50:08
I understand what you're trying to accomplish, but
John
2016/07/20 16:11:58
Now I understand...
This method's signature is to
| |
| 59 # Whole range fails but both halves pass | |
| 60 # So, some conjunction of funtions cause a failure, but none individually. | |
| 61 partial_1 = find_crashes(cmd, [first_half] + [second_half] + include_ranges[ 1:], timeout) | |
|
John
2016/07/20 14:50:08
80-col, as per the Google python style guide.
manasijm
2016/07/20 21:49:31
Done.
| |
| 62 # Heavy list concatenation, but this is insignificant compared to the proces s run times | |
| 63 if isinstance(partial_1[0], list) : | |
|
John
2016/07/20 14:50:08
This is python. You should be careful about the va
manasijm
2016/07/20 21:49:30
Done.
| |
| 64 partial_1 = partial_1[0] # Hack to convert [[x]] to [x] ! | |
| 65 partial_2 = find_crashes(cmd, [second_half] + [first_half] + include_ranges[ 1:], timeout) | |
|
John
2016/07/20 14:50:08
80-col
manasijm
2016/07/20 21:15:24
Done.
| |
| 66 if isinstance(partial_2[0], list) : | |
| 67 partial_2 = partial_2[0] | |
| 68 return [partial_1 + partial_2] | |
| 69 else : | |
| 70 result = [] | |
| 71 if exit_code_1 != 0 : | |
| 72 result = find_crashes(cmd, [first_half] + include_ranges[1:], timeout) | |
| 73 if exit_code_2 != 0 : | |
| 74 result = result + find_crashes(cmd, [second_half] + include_ranges[1:], ti meout) | |
|
John
2016/07/20 14:50:08
80-col
manasijm
2016/07/20 21:15:24
Done.
| |
| 75 return result | |
| 76 | |
| 77 def main(): | |
| 78 desc = 'Bisection debugging helper script' | |
| 79 argparser = argparse.ArgumentParser(description=desc) | |
| 80 argparser.add_argument('--cmd', required=True, | |
| 81 dest='cmd', | |
| 82 help='Runnable command') | |
| 83 argparser.add_argument('--start', dest='start', default=0, | |
| 84 help='Start of initial range') | |
| 85 argparser.add_argument('--end', dest='end', default=50000, | |
| 86 help='End of initial range') | |
| 87 argparser.add_argument('--timeout', dest='timeout', default=60, | |
| 88 help='Timeout for each invocation of the input comman d') | |
|
John
2016/07/20 14:50:08
80-col
manasijm
2016/07/20 21:15:24
Done.
| |
| 89 | |
| 90 argparser.add_argument('--all', dest='all', action='store_true') | |
| 91 argparser.add_argument('--no-all', dest='all', action='store_false') | |
| 92 argparser.set_defaults(all=True) | |
| 93 | |
| 94 args = argparser.parse_args() | |
| 95 | |
| 96 global find_all | |
| 97 find_all = args.all | |
|
John
2016/07/20 16:11:58
this is only ever use in find_crashes. I strongly
manasijm
2016/07/20 21:15:24
Done.
| |
| 98 | |
| 99 fail_list = [] | |
| 100 | |
| 101 initial_range = (int(args.start), int(args.end)) | |
| 102 timeout = int(args.timeout) | |
| 103 | |
| 104 if run(args.cmd, [initial_range], timeout) != 0 : | |
| 105 fail_list = find_crashes(args.cmd, [initial_range], timeout) | |
| 106 else : | |
| 107 print "Pass" # The whole range works, maybe check subzero build flags? | |
| 108 | |
| 109 if len(fail_list) > 0 : | |
|
John
2016/07/20 14:50:08
this is python. you can just
if fail_list:
prin
manasijm
2016/07/20 21:15:24
Done.
| |
| 110 print "Failing Functions:" | |
| 111 for fail in fail_list: | |
| 112 print fail | |
| 113 print "Number of tries : " + str(num_tries) | |
| 114 #TODO(manasijm) : Pretty print, assocoiate these numbers with filenames | |
|
John
2016/07/20 14:50:08
# TODO - note the space
Also, add an empty line b
manasijm
2016/07/20 21:15:24
Done.
| |
| 115 if __name__ == '__main__': | |
| 116 main() | |
| OLD | NEW |