1import imp
2import pkg_resources
3import os
4import sys
5import datetime
6import gc
7import ctypes
8
9have_gitpython = False
10try:
11    from git import Repo, InvalidGitRepositoryError
12    have_gitpython = True
13except ImportError:
14    print("If you install gitpython (`pip install gitpython`), I can give you git info too!")
15
16angr_modules = ['angr', 'ailment', 'cle', 'pyvex', 'claripy', 'archinfo', 'z3', 'unicorn']
17native_modules = {'angr': 'angr.state_plugins.unicorn_engine._UC_NATIVE',
18                  'unicorn': 'unicorn.unicorn._uc',
19                  'pyvex': 'pyvex.pvc',
20                  'z3': "[x for x in gc.get_objects() if type(x) is ctypes.CDLL and 'z3' in str(x)][0]"} # YIKES FOREVER
21python_packages = {'z3': 'z3-solver'}
22
23
24def get_venv():
25    if 'VIRTUAL_ENV' in os.environ:
26        return os.environ['VIRTUAL_ENV']
27    return None
28
29
30def import_module(module):
31    try:
32        # because we want to import using a variable, do it this way
33        module_obj = __import__(module)
34        # create a global object containging our module
35        globals()[module] = module_obj
36    except ImportError:
37        sys.stderr.write("ERROR: missing python module: " + module + "\n")
38        sys.exit(1)
39
40def print_versions():
41    for m in angr_modules:
42        print("######## %s #########" % m)
43        try:
44            _, python_filename, _ = imp.find_module(m)
45        except ImportError:
46            print("Python could not find " + m)
47            continue
48        except Exception as e:
49            print("An error occurred importing %s: %s" % (m, e))
50        print("Python found it in %s" % (python_filename))
51        try:
52            pip_package = python_packages.get(m, m)
53            pip_version = pkg_resources.get_distribution(pip_package)
54            print("Pip version %s" % pip_version)
55        except:
56            print("Pip version not found!")
57        print_git_info(python_filename)
58
59
60def print_git_info(dirname):
61    if not have_gitpython:
62        return
63    try:
64        repo = Repo(dirname, search_parent_directories=True)
65    except InvalidGitRepositoryError:
66        print("Couldn't find git info")
67        return
68    cur_commit = repo.commit()
69    cur_branch = repo.active_branch
70    print("Git info:")
71    print("\tCurrent commit %s from branch %s" % (cur_commit.hexsha, cur_branch.name))
72    try:
73        # EDG: Git is insane, but this should work 99% of the time
74        cur_tb = cur_branch.tracking_branch()
75        if cur_tb.is_remote():
76            remote_name = cur_tb.remote_name
77            remote_url = repo.remotes[remote_name].url
78            print("\tChecked out from remote %s: %s" % (remote_name, remote_url))
79        else:
80            print("Tracking local branch %s" % cur_tb.name)
81    except:
82        print("Could not resolve tracking branch or remote info!")
83
84def print_system_info():
85    print("Platform: " + pkg_resources.get_build_platform())
86    print("Python version: " + str(sys.version))
87
88
89def print_native_info():
90    print("######### Native Module Info ##########")
91    for module, path in native_modules.items():
92        try:
93            import_module(module)
94            print("%s: %s" % (module, str(eval(path))))
95        except:
96            print("%s: NOT FOUND" % (module))
97
98
99def bug_report():
100    print("angr environment report")
101    print("=============================")
102    print("Date: " + str(datetime.datetime.today()))
103    if get_venv():
104        print("Running in virtual environment at " + get_venv())
105    else:
106        print("!!! runninng in global environment.  Are you sure? !!!")
107    print_system_info()
108    print_versions()
109    print_native_info()
110
111
112if __name__ == "__main__":
113    bug_report()
114