Beispiel #1
0
 def installed(cls, custom_binary_dir=None):
     """ Check that the tool is installed
         :return: bool reprenting whether the tool is installed or not 
                 (executable accessible on the path)
                 - True: the tool is installed and works
                 - False: the tool is not installed or do not work
     """
     for prog in (cls.tool, ):
         if custom_binary_dir is not None:
             prog = os.path.join(custom_binary_dir, prog)
         if not DriversUtils.check_tool(prog=prog, args_list=['--version'],\
                                                 expected_exit_codes=[1]):
             return False
     if not DriversUtils.check_tool(prog=cls.stdbuf, args_list=['--version'],\
                                                 expected_exit_codes=[0]):
         return False
     return True
Beispiel #2
0
 def installed(cls, custom_binary_dir=None):
     """ Check that the tool is installed
         :return: bool reprenting whether the tool is installed or not 
                 (executable accessible on the path)
                 - True: the tool is installed and works
                 - False: the tool is not installed or do not work
     """
     for prog in ('klee', 'klee-replay'):
         if not DriversUtils.check_tool(prog=prog, args_list=['--version'],\
                                                 expected_exit_codes=[1]):
             return False
     return True
Beispiel #3
0
    def get_instrumented_executable_paths_map(self, enabled_criteria):
        using_gdb_wrapper = self.driver_config.get_use_gdb_wrapper()
        if using_gdb_wrapper:
            # use wrapper if gdb is installed
            using_gdb_wrapper = DriversUtils.check_tool(prog='gdb', \
                                                    args_list=['--version'], \
                                                    expected_exit_codes=[0])

            if using_gdb_wrapper:
                # XXX: Docker has issues running programs in Docker,
                # unless the container is ran with the following arguments:
                #
                # docker run --cap-add=SYS_PTRACE \
                #               --security-opt seccomp=unconfined ...
                #
                # We check that it is fine by testing on echo
                ret, o_e, _ = DriversUtils.execute_and_get_retcode_out_err(
                                        prog='gdb', \
                                        args_list=['--batch-silent', \
                                                    '--quiet',
                                                    '--return-child-result',
                                                    '-ex', 'run',
                                                    '--args', 'echo'], \
                                        )#out_on=False, err_on=False)
                using_gdb_wrapper = (ret == 0)
                if not using_gdb_wrapper:
                    logging.warning("use gdb is enabled but call to gdb fails"
                                    " (retcode {}) with msg: {}".format(
                                        ret, o_e))
            else:
                logging.warning("use gdb is enabled but gdb is not installed")

        crit_to_exes_map = {}
        obj = common_fs.loadJSON(self.instrumentation_details)
        #exes = [p for _, p in list(obj.items())]
        for name in obj:
            obj[name] = os.path.join(self.instrumented_code_storage_dir, \
                                                                    obj[name])

        if using_gdb_wrapper:
            # Using GDB WRAPPER
            with open(self.gcov_gdb_wrapper_template) as f:
                template_str = f.read()
            single_exe = obj[list(obj)[0]]
            template_str = template_str.replace(\
                                'MUTERIA_GCOV_PROGRAMEXE_PATHNAME', single_exe)
            with open(self.gcov_gdb_wrapper_sh, 'w') as f:
                f.write(template_str)
            shutil.copymode(single_exe, self.gcov_gdb_wrapper_sh)
            obj[list(obj)[0]] = self.gcov_gdb_wrapper_sh

        exes_map = obj
        for criterion in enabled_criteria:
            crit_to_exes_map[criterion] = exes_map

        #logging.debug("DBG: {} {} {}".format(\
        #                  "Using gdb wrapper is {}.".format(using_gdb_wrapper), \
        #                  "crit_to_exe_map is {}.".format(crit_to_exes_map), \
        #                  "wraper path is {}!".format(self.gcov_gdb_wrapper_sh)))

        return crit_to_exes_map
Beispiel #4
0
    def convert_code(self, src_fmt, dest_fmt, file_src_dest_map, \
                                                repository_manager, **kwargs):
        # TODO: add can_fail parameter, in kwarg, for case like mutant
        # compilatioon that can fail but should not terminate execution
        # but return a specific value
        ERROR_HANDLER.assert_true(src_fmt in self.src_formats, \
                                    "Unsupported src format", __file__)

        # post build callbacks
        class CopyCallbackObject(DefaultCallbackObject):
            def after_command(self):
                if self.op_retval == \
                                    common_mix.GlobalConstants.COMMAND_FAILURE:
                    return common_mix.GlobalConstants.COMMAND_FAILURE
                for sf, df in list(file_src_dest_map.items()):
                    abs_sf = repository_manager.repo_abs_path(sf)
                    if not os.path.isfile(abs_sf):
                        ERROR_HANDLER.error_exit(\
                                "an expected file missing after build: "+\
                                                            abs_sf, __file__)
                    if df is not None:
                        shutil.copy2(abs_sf, df)
                return None

            #~ def after_command()

        #~ class CopyCallbackObject

        # Should not have callback_object and file_src_dest_map at the
        # same time
        callbak_obj_key = 'callback_object'
        if callbak_obj_key in kwargs:
            ERROR_HANDLER.assert_true(file_src_dest_map is None,\
                            "file_src_dest_map must be None "+ \
                            "if callback_object is passed", __file__)
        elif file_src_dest_map is not None and len(file_src_dest_map) > 0:
            kwargs[callbak_obj_key] = CopyCallbackObject()
        else:
            kwargs[callbak_obj_key] = None

        # Actual Processing
        if (dest_fmt == ccs.CodeFormats.C_PREPROCESSED_SOURCE):
            if (src_fmt == ccs.CodeFormats.C_SOURCE):
                ERROR_HANDLER.error_exit("Must Implement1", __file__)
            else:
                for src, dest in list(file_src_dest_map.items()):
                    shutil.copy2(src, dest)
        if (dest_fmt == ccs.CodeFormats.LLVM_BITCODE):
            # XXX: This build overrides passed clean_tmp and reconfigure
            # also overrides Compiler if wllvm if found
            # and does not use the callback object
            # and require file_src_dest_map to have the place to store
            # generated .bc by specifying the corresponding native file.
            # EX: {x.c: /path/to/main} passed to have /path/to/main.bc
            # generated

            spec_compiler = kwargs['compiler'] if 'compiler' in kwargs \
                                                                    else None
            # special kwargs
            spec_llvm_compiler_path = None
            if 'llvm_compiler_path' in kwargs:
                spec_llvm_compiler_path = kwargs['llvm_compiler_path']
                del kwargs['llvm_compiler_path']

            if spec_compiler is not None:
                bak_llvm_compiler = os.environ['LLVM_COMPILER']
                os.environ['LLVM_COMPILER'] = spec_compiler
            if spec_llvm_compiler_path is not None:
                bak_llvm_compiler_path = os.environ['LLVM_COMPILER_PATH']
                os.environ['LLVM_COMPILER_PATH'] = spec_llvm_compiler_path

            #1. Ensure wllvm is installed (For now use default llvm compiler)
            has_wllvm = DriversUtils.check_tool('wllvm', ['--version'])
            ERROR_HANDLER.assert_true(has_wllvm, 'wllvm not found', __file__)

            # tmp['LLVM_COMPILER_PATH'] = ...
            kwargs['compiler'] = 'wllvm'
            kwargs['clean_tmp'] = True
            kwargs['reconfigure'] = True

            # Normal build followed by executable copying
            pre_ret, ret, post_ret = repository_manager.build_code(**kwargs)
            ERROR_HANDLER.assert_true(\
                    ret != common_mix.GlobalConstants.COMMAND_FAILURE and\
                    pre_ret != common_mix.GlobalConstants.COMMAND_FAILURE and\
                    post_ret != common_mix.GlobalConstants.COMMAND_FAILURE,\
                                        "Build LLVM bitcode failed!", __file__)

            # extract bitcode from copied executables and remove non bitcode
            if file_src_dest_map is not None:
                for src, dest in list(file_src_dest_map.items()):
                    ret, out, err = \
                            DriversUtils.execute_and_get_retcode_out_err( \
                                                        "extract-bc", [dest])
                    ERROR_HANDLER.assert_true(ret == 0, \
                                        '{}. \n# OUT: {}\n# ERR: {}'.format(\
                                    'extract-bc failed', out, err), __file__)
                    os.remove(dest)

            if spec_compiler is not None:
                os.environ['LLVM_COMPILER'] = bak_llvm_compiler
            if spec_llvm_compiler_path is not None:
                os.environ['LLVM_COMPILER_PATH'] = bak_llvm_compiler_path

            # Clean build
            kwargs['compiler'] = None
            pre_ret, ret, post_ret = repository_manager.build_code(**kwargs)

        if (dest_fmt == ccs.CodeFormats.OBJECT_FILE):
            ERROR_HANDLER.error_exit("Must Implement3", __file__)
        if (dest_fmt == ccs.CodeFormats.NATIVE_CODE):
            pre_ret, ret, post_ret = repository_manager.build_code(**kwargs)
        return pre_ret, ret, post_ret