Example #1
0
def scan_build():
    """ Entry point for scan-build command. """

    args = parse_args_for_scan_build()
    # will re-assign the report directory as new output
    with report_directory(
            args.output, args.keep_empty, args.output_format) as args.output:
        # Run against a build command. there are cases, when analyzer run
        # is not required. But we need to set up everything for the
        # wrappers, because 'configure' needs to capture the CC/CXX values
        # for the Makefile.
        if args.intercept_first:
            # Run build command with intercept module.
            exit_code = capture(args)
            # Run the analyzer against the captured commands.
            if need_analyzer(args.build):
                govern_analyzer_runs(args)
        else:
            # Run build command and analyzer with compiler wrappers.
            environment = setup_environment(args)
            exit_code = run_build(args.build, env=environment)
        # Cover report generation and bug counting.
        number_of_bugs = document(args)
        # Set exit status as it was requested.
        return number_of_bugs if args.status_bugs else exit_code
Example #2
0
def scan_build():
    # type: () -> int
    """ Entry point for scan-build command. """

    args = parse_args_for_scan_build()
    # will re-assign the report directory as new output
    with report_directory(args.output, args.keep_empty) as args.output:
        # run against a build command. there are cases, when analyzer run
        # is not required. but we need to set up everything for the
        # wrappers, because 'configure' needs to capture the CC/CXX values
        # for the Makefile.
        if args.intercept_first:
            # run build command with intercept module
            exit_code, compilations = capture(args)
            if need_analyzer(args.build):
                # run the analyzer against the captured commands
                run_analyzer_parallel(compilations, args)
        else:
            # run build command and analyzer with compiler wrappers
            environment = setup_environment(args)
            exit_code = run_build(args.build, env=environment)
        # cover report generation and bug counting
        number_of_bugs = document(args)
        # set exit status as it was requested
        return number_of_bugs if args.status_bugs else exit_code
Example #3
0
def analyze_build_main(bin_dir, from_build_command):
    """ Entry point for 'analyze-build' and 'scan-build'. """

    parser = create_parser(from_build_command)
    args = parser.parse_args()
    validate(parser, args, from_build_command)

    # setup logging
    initialize_logging(args.verbose)
    logging.debug('Parsed arguments: %s', args)

    with report_directory(args.output, args.keep_empty) as target_dir:
        if not from_build_command:
            # run analyzer only and generate cover report
            run_analyzer(args, target_dir)
            number_of_bugs = document(args, target_dir, True)
            return number_of_bugs if args.status_bugs else 0
        elif args.intercept_first:
            # run build command and capture compiler executions
            exit_code = capture(args, bin_dir)
            # next step to run the analyzer against the captured commands
            if need_analyzer(args.build):
                run_analyzer(args, target_dir)
                # cover report generation and bug counting
                number_of_bugs = document(args, target_dir, True)
                # remove the compilation database when it was not requested
                if os.path.exists(args.cdb):
                    os.unlink(args.cdb)
                # set exit status as it was requested
                return number_of_bugs if args.status_bugs else exit_code
            else:
                return exit_code
        else:
            # run the build command with compiler wrappers which
            # execute the analyzer too. (interposition)
            environment = setup_environment(args, target_dir, bin_dir)
            logging.debug('run build in environment: %s', environment)
            exit_code = subprocess.call(args.build, env=environment)
            logging.debug('build finished with exit code: %d', exit_code)
            # cover report generation and bug counting
            number_of_bugs = document(args, target_dir, False)
            # set exit status as it was requested
            return number_of_bugs if args.status_bugs else exit_code
Example #4
0
def analyze_build_main(bin_dir, from_build_command):
    """ Entry point for 'analyze-build' and 'scan-build'. """

    parser = create_parser(from_build_command)
    args = parser.parse_args()
    validate(parser, args, from_build_command)

    # setup logging
    initialize_logging(args.verbose)
    logging.debug('Parsed arguments: %s', args)

    with report_directory(args.output, args.keep_empty) as target_dir:
        if not from_build_command:
            # run analyzer only and generate cover report
            run_analyzer(args, target_dir)
            number_of_bugs = document(args, target_dir, True)
            return number_of_bugs if args.status_bugs else 0
        elif args.intercept_first:
            # run build command and capture compiler executions
            exit_code = capture(args, bin_dir)
            # next step to run the analyzer against the captured commands
            if need_analyzer(args.build):
                run_analyzer(args, target_dir)
                # cover report generation and bug counting
                number_of_bugs = document(args, target_dir, True)
                # remove the compilation database when it was not requested
                if os.path.exists(args.cdb):
                    os.unlink(args.cdb)
                # set exit status as it was requested
                return number_of_bugs if args.status_bugs else exit_code
            else:
                return exit_code
        else:
            # run the build command with compiler wrappers which
            # execute the analyzer too. (interposition)
            environment = setup_environment(args, target_dir, bin_dir)
            logging.debug('run build in environment: %s', environment)
            exit_code = subprocess.call(args.build, env=environment)
            logging.debug('build finished with exit code: %d', exit_code)
            # cover report generation and bug counting
            number_of_bugs = document(args, target_dir, False)
            # set exit status as it was requested
            return number_of_bugs if args.status_bugs else exit_code
Example #5
0
def scan_build():
    """ Entry point for scan-build command. """

    args = parse_args_for_scan_build()
    with report_directory(args.output, args.keep_empty) as target_dir:
        # Run against a build command. there are cases, when analyzer run
        # is not required. But we need to set up everything for the
        # wrappers, because 'configure' needs to capture the CC/CXX values
        # for the Makefile.
        if args.intercept_first:
            # Run build command with intercept module.
            exit_code = capture(args)
            # Run the analyzer against the captured commands.
            if need_analyzer(args.build):
                run_analyzer(args, target_dir)
        else:
            # Run build command and analyzer with compiler wrappers.
            environment = setup_environment(args, target_dir)
            exit_code = run_build(args.build, env=environment)
        # Cover report generation and bug counting.
        number_of_bugs = document(args, target_dir, False)
        # Set exit status as it was requested.
        return number_of_bugs if args.status_bugs else exit_code
Example #6
0
def intercept_build(args):
    # type: () -> int
    """ Entry point for 'intercept-build' command. """

    parser = arguments.create_intercept_parser()
    parser.add_argument('--project-path',
                        metavar="<path>",
                        dest='cwd',
                        type=str,
                        default=getcwd(),
                        help="""used path where the build tools are invoked""")
    parser.add_argument('--sanitize-build',
                        action='store_true',
                        help="""Rebuild command with sanitizers enabled""")
    parser.add_argument('--fuzzing-targets',
                        action='store_true',
                        help="""Build fuzzing targets""")
    args = parser.parse_args(args)
    chdir(args.cwd)

    if args.sanitize_build:
        if not args.build:
            LOGGER.error("Please provide a build command")
            sys.exit(2)
        compiler = "{} -g {} {}"

        LOGGER.debug(
            "Compiler command %s",
            compiler.format(CLANG, CLANG_SANITIZE_CMD, CLANG_COVERAGE_CMD))
        proc = subprocess.run(
            args.build,
            shell=True,
            env={
                **env,
                **{
                    'CC':
                    compiler.format(CLANG, CLANG_SANITIZE_CMD, CLANG_COVERAGE_CMD),
                    'CXX':
                    compiler.format(CLANGPP, CLANG_SANITIZE_CMD, CLANG_COVERAGE_CMD)
                }
            })
        parser.exit(status=proc.returncode)
    if args.fuzzing_targets:
        LOGGER.info("Building fuzzing targets")
        ret = build_fuzzing_targets()
        parser.exit(status=ret)

    args.append = True

    libscanbuild.reconfigure_logging(args.verbose)
    logging.debug('Raw arguments %s', sys.argv)

    # short validation logic
    if not args.build:
        parser.error(message='missing build command')

    logging.debug('Parsed arguments: %s', args)
    exit_code, current = intercept.capture(args)

    # To support incremental builds, it is desired to read elements from
    # an existing compilation database from a previous run.
    if args.append and path.isfile(args.cdb):
        previous = compilation.CompilationDatabase.load(args.cdb)
        entries = iter(set(itertools.chain(previous, current)))
        compilation.CompilationDatabase.save(args.cdb, entries)
    else:
        compilation.CompilationDatabase.save(args.cdb, current)

    return exit_code