diff --git a/post-processing/exceptions.py b/post-processing/exceptions.py new file mode 100644 index 000000000..925ff57f1 --- /dev/null +++ b/post-processing/exceptions.py @@ -0,0 +1,30 @@ +# Copyright 2022 Fuzz Introspector Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Exceptions used throughout the package.""" + + +class FuzzIntrospectorError(Exception): + """Base error""" + + +class CalltreeError(FuzzIntrospectorError): + """Error for when dealing with calltrees""" + + +class AnalysisError(FuzzIntrospectorError): + """Error for analysis logic""" + + +class DataLoaderError(FuzzIntrospectorError): + """Error for handling data loader issues""" diff --git a/post-processing/fuzz_analysis.py b/post-processing/fuzz_analysis.py index e6c8ca9f6..ebfddba38 100644 --- a/post-processing/fuzz_analysis.py +++ b/post-processing/fuzz_analysis.py @@ -29,6 +29,8 @@ import fuzz_data_loader from enum import Enum +from exceptions import AnalysisError + logger = logging.getLogger(name=__name__) logger.setLevel(logging.INFO) @@ -142,7 +144,9 @@ def callstack_set_curr_node(n, name, c): if demangled_name != "LLVMFuzzerTestOneInput" and "TestOneInput" not in demangled_name: logger.info("Unexpected first node in the calltree.") logger.info(f"Found: {demangled_name}") - exit(1) + raise AnalysisError( + "First node in calltree seems to be non-fuzzer function" + ) coverage_data = profile.coverage.get_hit_details("LLVMFuzzerTestOneInput") if len(coverage_data) == 0: logger.error("There is no coverage data (not even all negative).") @@ -165,7 +169,9 @@ def callstack_set_curr_node(n, name, c): node.cov_parent = callstack_get_parent(node, callstack) else: logger.error("A node should either be the first or it must have a parent") - exit(1) + raise AnalysisError( + "A node should either be the first or it must have a parent" + ) node.cov_hitcount = node_hitcount # Map hitcount to color of target. diff --git a/post-processing/fuzz_cfg_load.py b/post-processing/fuzz_cfg_load.py index 67a8b901c..ae90060a9 100644 --- a/post-processing/fuzz_cfg_load.py +++ b/post-processing/fuzz_cfg_load.py @@ -20,6 +20,8 @@ Optional ) +from exceptions import CalltreeError + logger = logging.getLogger(name=__name__) @@ -72,7 +74,8 @@ def extract_all_callsites_recursive( def extract_all_callsites(calltree: Optional[CalltreeCallsite]) -> List[CalltreeCallsite]: if calltree is None: logger.error("Trying to extract from a None calltree") - exit(1) + raise CalltreeError("Calltree is None") + cs_list: List[CalltreeCallsite] = [] extract_all_callsites_recursive(calltree, cs_list) return cs_list diff --git a/post-processing/fuzz_data_loader.py b/post-processing/fuzz_data_loader.py index 6c2736746..ef065b84c 100644 --- a/post-processing/fuzz_data_loader.py +++ b/post-processing/fuzz_data_loader.py @@ -32,6 +32,8 @@ import fuzz_cov_load import fuzz_utils +from exceptions import DataLoaderError + logger = logging.getLogger(name=__name__) logger.setLevel(logging.INFO) @@ -652,7 +654,9 @@ def add_func_to_reached_and_clone(merged_profile_old: MergedProjectProfile, if merged_profile.all_functions[func_to_add.function_name].hitcount == 0: logger.info("Error. Hitcount did not get set for some reason. Exiting") - exit(1) + raise DataLoaderError( + "Hitcount did not get set for some reason" + ) return merged_profile