Skip to content

Commit

Permalink
Merge pull request #179 from PRUNERS/issue174-incremental-output
Browse files Browse the repository at this point in the history
Issue174 incremental output, fixes #174
  • Loading branch information
mikebentley15 authored Jul 20, 2018
2 parents ba203ca + 1b2614c commit 50f54a1
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
40 changes: 35 additions & 5 deletions scripts/flitcli/flit_bisect.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ def extract_symbols(file_or_filelist, objdir):

return symbol_tuples

def bisect_search(is_bad, elements):
def bisect_search(is_bad, elements, found_callback=None):
'''
Performs the bisect search, attempting to minimize the bad list. We could
go through the list one at a time, but that would cause us to call is_bad()
Expand Down Expand Up @@ -440,7 +440,7 @@ def bisect_search(is_bad, elements):
>>> def is_bad(x,y):
... global call_count
... call_count += 1
... return min(x) < 0
... return min(x) < 0 if x else False
>>> x = bisect_search(is_bad, [1, 3, 4, 5, -1, 10, 0, -15, 3])
>>> sorted(x)
[-15, -1]
Expand All @@ -450,16 +450,32 @@ def bisect_search(is_bad, elements):
>>> call_count
9
Test out the found_callback() functionality.
>>> s = set()
>>> y = bisect_search(is_bad, [-1, -2, -3, -4], found_callback=s.add)
>>> sorted(y)
[-4, -3, -2, -1]
>>> sorted(s)
[-4, -3, -2, -1]
See what happens when it has a pair that only show up together and not
alone. Only if -6 and 5 are in the list, then is_bad returns true.
The assumption of this algorithm is that bad elements are independent,
so this should throw an exception.
>>> def is_bad(x,y):
... return max(x) - min(x) > 10
>>> x = bisect_search(is_bad, [-6, 2, 3, -3, -1, 0, 0, -5, 5])
>>> bisect_search(is_bad, [-6, 2, 3, -3, -1, 0, 0, -5, 5])
Traceback (most recent call last):
...
AssertionError: Assumption that bad elements are independent was wrong
Check that the found_callback is not called on false positives. Here I
expect no output since no single element can be found.
>>> try:
... bisect_search(is_bad, [-6, 2, 3, -3, -1, 0, 0, -5, 5],
... found_callback=print)
... except AssertionError:
... pass
'''
# copy the incoming list so that we don't modify it
quest_list = list(elements)
Expand Down Expand Up @@ -499,10 +515,14 @@ def bisect_search(is_bad, elements):
# double check that we found a bad element before declaring it bad
if last_result or is_bad([bad_element], known_list + quest_list):
bad_list.append(bad_element)
# inform caller that a bad element was found
if found_callback != None:
found_callback(bad_element)

# add to the known list to not search it again
known_list.append(bad_element)


# Perform a sanity check. If we have found all of the bad items, then
# compiling with all but these bad items will cause a good build.
# This will fail if our hypothesis class is wrong
Expand Down Expand Up @@ -762,7 +782,12 @@ def bisect_build_and_check(trouble_src, gt_src):
print('Searching for bad source files:')
logging.info('Searching for bad source files under the trouble'
' compilation')
bad_sources = bisect_search(bisect_build_and_check, sources)

bas_source_msg = 'Found bad source file {}'
bad_source_callback = lambda filename : \
util.printlog(bad_source_msg.format(filename))
bad_sources = bisect_search(bisect_build_and_check, sources,
bad_source_callback)
return bad_sources

def search_for_symbol_problems(args, bisect_path, replacements, sources,
Expand Down Expand Up @@ -859,7 +884,12 @@ def bisect_symbol_build_and_check(trouble_symbols, gt_symbols):
logging.warning('%s', message_2)
return []

bad_symbols = bisect_search(bisect_symbol_build_and_check, symbol_tuples)
bad_symbol_msg = ('Found bad symbol '
'{sym.fname}:{sym.lineno} {sym.symbol} -- {sym.demangled}')
bad_symbol_callback = lambda sym : \
util.printlog(bad_symbol_msg.format(sym=sym))
bad_symbols = bisect_search(bisect_symbol_build_and_check, symbol_tuples,
bad_symbol_callback)
return bad_symbols

def compile_trouble(directory, compiler, optl, switches, verbose=False,
Expand Down
18 changes: 18 additions & 0 deletions scripts/flitcli/flitutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
import flitconfig as conf

import copy
import logging
import os
import socket
import sqlite3
Expand Down Expand Up @@ -349,3 +350,20 @@ def extract_make_var(var, makefile='Makefile', directory='.'):
var_values = output.split('=', maxsplit=1)[1].split()
return var_values

def printlog(message):
'''
Prints the message to stdout and then logs the message at the info level.
It is expected that the logging module has already been configured using
the root logger.
>>> logger = logging.getLogger()
>>> for handler in logger.handlers[:]:
... logger.removeHandler(handler)
>>> import sys
>>> logging.basicConfig(stream=sys.stdout, level=logging.INFO)
>>> printlog('Danger Will Robinson!')
Danger Will Robinson!
INFO:root:Danger Will Robinson!
'''
print(message)
logging.info(message)

0 comments on commit 50f54a1

Please sign in to comment.