示例#1
0
def main(args):
    """
    Execute a wrapper over log-analyze-parse, aka 'check'.
    """

    logger.setup_logger(args.verbose if 'verbose' in args else None)

    def __update_if_key_exists(source, target, key):
        """Append the source Namespace's element with 'key' to target with
        the same key, but only if it exists."""
        if key in source:
            setattr(target, key, getattr(source, key))

    if 'force' in args:
        LOG.warning('"--force" option has been deprecated and it will be '
                    'removed in the future version of CodeChecker. Use the '
                    '"--clean" option to delete analysis reports stored in '
                    'the output directory.')

    # If no output directory is given then the checker results go to a
    # temporary directory. This way the subsequent "quick" checks don't pollute
    # the result list of a previous check. If the detection status function is
    # intended to be used (i.e. by keeping the .plist files) then the output
    # directory has to be provided explicitly.
    is_temp_output = False
    if 'output_dir' in args:
        output_dir = args.output_dir
    else:
        output_dir = tempfile.mkdtemp()
        is_temp_output = True

    output_dir = os.path.abspath(output_dir)
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    logfile = None
    is_command = False
    try:
        # --- Step 1.: Perform logging if build command was specified.
        if 'command' in args:
            logfile = tempfile.NamedTemporaryFile().name
            is_command = True

            # Translate the argument list between check and log.
            log_args = argparse.Namespace(command=args.command,
                                          logfile=logfile)
            __update_if_key_exists(args, log_args, 'quiet')
            __update_if_key_exists(args, log_args, 'verbose')

            import codechecker_analyzer.cmd.log as log_module
            LOG.debug("Calling LOG with args:")
            LOG.debug(log_args)

            log_module.main(log_args)
        elif 'logfile' in args:
            logfile = args.logfile

        # --- Step 2.: Perform the analysis.
        if not os.path.exists(logfile):
            raise OSError("The specified logfile '" + logfile + "' does not "
                          "exist.")

        analyze_args = argparse.Namespace(logfile=[logfile],
                                          output_path=output_dir,
                                          output_format='plist',
                                          jobs=args.jobs)
        # Some arguments don't have default values.
        # We can't set these keys to None because it would result in an error
        # after the call.
        args_to_update = [
            'quiet',
            'skipfile',
            'analyzers',
            'add_compiler_defaults',
            'clangsa_args_cfg_file',
            'tidy_args_cfg_file',
            'tidy_config',
            'capture_analysis_output',
            'ctu_phases',
            'stats_output',
            'stats_dir',
            'stats_enabled',
            'stats_relevance_threshold',
            'stats_min_sample_count',
            'enable_all',
            'ordered_checkers',  # --enable and --disable.
            'timeout',
            'compile_uniqueing',
            'report_hash',
            'enable_z3',
            'enable_z3_refutation'
        ]
        for key in args_to_update:
            __update_if_key_exists(args, analyze_args, key)
        if 'clean' in args:
            setattr(analyze_args, 'clean', True)
        __update_if_key_exists(args, analyze_args, 'verbose')

        import codechecker_analyzer.cmd.analyze as analyze_module
        LOG.debug("Calling ANALYZE with args:")
        LOG.debug(analyze_args)

        analyze_module.main(analyze_args)

        # --- Step 3.: Print to stdout.
        parse_args = argparse.Namespace(input=[output_dir],
                                        input_format='plist')
        __update_if_key_exists(args, parse_args, 'print_steps')
        __update_if_key_exists(args, parse_args, 'verbose')
        __update_if_key_exists(args, parse_args, 'skipfile')

        import codechecker_analyzer.cmd.parse as parse_module
        LOG.debug("Calling PARSE with args:")
        LOG.debug(parse_args)

        parse_module.main(parse_args)
    except ImportError:
        LOG.error("Check failed: couldn't import a library.")
    except Exception:
        LOG.exception("Running check failed.")
        import traceback
        traceback.print_exc()
    finally:
        if is_temp_output:
            shutil.rmtree(output_dir)
        if is_command:
            os.remove(logfile)

    LOG.debug("Check finished.")
示例#2
0
def main(args):
    """
    Execute a wrapper over log-analyze-parse, aka 'check'.
    """

    logger.setup_logger(args.verbose if 'verbose' in args else None)

    if 'ctu_ast_mode' in args and 'ctu_phases' not in args:
        LOG.error("Analyzer option 'ctu-ast-mode' requires CTU mode enabled")
        sys.exit(1)

    def __update_if_key_exists(source, target, key):
        """Append the source Namespace's element with 'key' to target with
        the same key, but only if it exists."""
        if key in source:
            setattr(target, key, getattr(source, key))

    # If no output directory is given then the checker results go to a
    # temporary directory. This way the subsequent "quick" checks don't pollute
    # the result list of a previous check. If the detection status function is
    # intended to be used (i.e. by keeping the .plist files) then the output
    # directory has to be provided explicitly.
    if 'output_dir' in args:
        output_dir = args.output_dir
    else:
        output_dir = tempfile.mkdtemp()

    output_dir = os.path.abspath(output_dir)
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    logfile = None
    try:
        # --- Step 1.: Perform logging if build command was specified.
        if 'command' in args:
            logfile = tempfile.NamedTemporaryFile().name

            # Translate the argument list between check and log.
            log_args = argparse.Namespace(command=args.command,
                                          logfile=logfile)
            __update_if_key_exists(args, log_args, 'quiet')
            __update_if_key_exists(args, log_args, 'verbose')

            import codechecker_analyzer.cmd.log as log_module
            LOG.debug("Calling LOG with args:")
            LOG.debug(log_args)

            # If not explicitly given the debug log file of ld_logger is placed
            # in report directory if any. Otherwise parallel "CodeChecker
            # check" commands would overwrite each other's log files under /tmp
            # which is the default location for "CodeChecker check".
            if 'CC_LOGGER_DEBUG_FILE' not in os.environ:
                os.environ['CC_LOGGER_DEBUG_FILE'] = \
                    os.path.join(output_dir, 'codechecker.logger.debug')

            log_module.main(log_args)
        elif 'logfile' in args:
            logfile = args.logfile

        # --- Step 2.: Perform the analysis.
        analyze_args = argparse.Namespace(
            logfile=logfile,
            output_path=output_dir,
            output_format='plist',
            jobs=args.jobs,
            keep_gcc_include_fixed=args.keep_gcc_include_fixed,
            keep_gcc_intrin=args.keep_gcc_intrin)
        # Some arguments don't have default values.
        # We can't set these keys to None because it would result in an error
        # after the call.
        args_to_update = [
            'quiet',
            'skipfile',
            'files',
            'analyzers',
            'add_compiler_defaults',
            'clangsa_args_cfg_file',
            'tidy_args_cfg_file',
            'tidy_config',
            'analyzer_config',
            'checker_config',
            'capture_analysis_output',
            'config_file',
            'ctu_phases',
            'ctu_reanalyze_on_failure',
            'stats_output',
            'stats_dir',
            'stats_enabled',
            'stats_relevance_threshold',
            'stats_min_sample_count',
            'enable_all',
            'ordered_checkers',  # --enable and --disable.
            'timeout',
            'compile_uniqueing',
            'report_hash',
            'enable_z3',
            'enable_z3_refutation'
        ]
        for key in args_to_update:
            __update_if_key_exists(args, analyze_args, key)
        if 'clean' in args:
            setattr(analyze_args, 'clean', True)
        __update_if_key_exists(args, analyze_args, 'verbose')

        import codechecker_analyzer.cmd.analyze as analyze_module
        LOG.debug("Calling ANALYZE with args:")
        LOG.debug(analyze_args)

        analysis_exit_status = analyze_module.main(analyze_args)

        # --- Step 3.: Print to stdout.
        parse_args = argparse.Namespace(input=[output_dir],
                                        input_format='plist')
        __update_if_key_exists(args, parse_args, 'print_steps')
        __update_if_key_exists(args, parse_args, 'review_status')
        __update_if_key_exists(args, parse_args, 'verbose')
        __update_if_key_exists(args, parse_args, 'skipfile')
        __update_if_key_exists(args, parse_args, 'suppress')

        import codechecker_analyzer.cmd.parse as parse_module
        LOG.debug("Calling PARSE with args:")
        LOG.debug(parse_args)

        parse_module.main(parse_args)
    except ImportError:
        LOG.error("Check failed: couldn't import a library.")
    except Exception:
        LOG.exception("Running check failed.")
        import traceback
        traceback.print_exc()
    finally:
        if 'output_dir' not in args:
            shutil.rmtree(output_dir)
        if 'command' in args:
            os.remove(logfile)

    LOG.debug("Check finished.")

    return analysis_exit_status
示例#3
0
def main(args):
    """
    Execute a wrapper over log-analyze-parse, aka 'check'.
    """

    logger.setup_logger(args.verbose if 'verbose' in args else None)

    def __update_if_key_exists(source, target, key):
        """Append the source Namespace's element with 'key' to target with
        the same key, but only if it exists."""
        if key in source:
            setattr(target, key, getattr(source, key))

    # If no output directory is given then the checker results go to a
    # temporary directory. This way the subsequent "quick" checks don't pollute
    # the result list of a previous check. If the detection status function is
    # intended to be used (i.e. by keeping the .plist files) then the output
    # directory has to be provided explicitly.
    is_temp_output = False
    if 'output_dir' in args:
        output_dir = args.output_dir
    else:
        output_dir = tempfile.mkdtemp()
        is_temp_output = True

    output_dir = os.path.abspath(output_dir)
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    logfile = None
    is_command = False
    try:
        # --- Step 1.: Perform logging if build command was specified.
        if 'command' in args:
            logfile = tempfile.NamedTemporaryFile().name
            is_command = True

            # Translate the argument list between check and log.
            log_args = argparse.Namespace(
                command=args.command,
                logfile=logfile
            )
            __update_if_key_exists(args, log_args, 'quiet')
            __update_if_key_exists(args, log_args, 'verbose')

            import codechecker_analyzer.cmd.log as log_module
            LOG.debug("Calling LOG with args:")
            LOG.debug(log_args)

            log_module.main(log_args)
        elif 'logfile' in args:
            logfile = args.logfile

        # --- Step 2.: Perform the analysis.
        if not os.path.exists(logfile):
            raise OSError("The specified logfile '" + logfile + "' does not "
                          "exist.")

        analyze_args = argparse.Namespace(
            logfile=[logfile],
            output_path=output_dir,
            output_format='plist',
            jobs=args.jobs
        )
        # Some arguments don't have default values.
        # We can't set these keys to None because it would result in an error
        # after the call.
        args_to_update = ['quiet',
                          'skipfile',
                          'analyzers',
                          'add_compiler_defaults',
                          'clangsa_args_cfg_file',
                          'tidy_args_cfg_file',
                          'tidy_config',
                          'capture_analysis_output',
                          'ctu_phases',
                          'stats_output',
                          'stats_dir',
                          'stats_enabled',
                          'stats_relevance_threshold',
                          'stats_min_sample_count',
                          'enable_all',
                          'ordered_checkers',  # --enable and --disable.
                          'timeout',
                          'compile_uniqueing',
                          'report_hash'
                          ]
        for key in args_to_update:
            __update_if_key_exists(args, analyze_args, key)
        if 'force' in args or 'clean' in args:
            setattr(analyze_args, 'clean', True)
        __update_if_key_exists(args, analyze_args, 'verbose')

        import codechecker_analyzer.cmd.analyze as analyze_module
        LOG.debug("Calling ANALYZE with args:")
        LOG.debug(analyze_args)

        analyze_module.main(analyze_args)

        # --- Step 3.: Print to stdout.
        parse_args = argparse.Namespace(
            input=[output_dir],
            input_format='plist'
        )
        __update_if_key_exists(args, parse_args, 'print_steps')
        __update_if_key_exists(args, parse_args, 'verbose')
        __update_if_key_exists(args, parse_args, 'skipfile')

        import codechecker_analyzer.cmd.parse as parse_module
        LOG.debug("Calling PARSE with args:")
        LOG.debug(parse_args)

        parse_module.main(parse_args)
    except ImportError:
        LOG.error("Check failed: couldn't import a library.")
    except Exception as ex:
        LOG.exception("Running check failed.")
        import traceback
        traceback.print_exc()
    finally:
        if is_temp_output:
            shutil.rmtree(output_dir)
        if is_command:
            os.remove(logfile)

    LOG.debug("Check finished.")