def test_no_atomicity_violation1(self):
        file_to_parse = "no_atomicity_violation1.c"
        file_path = join(self.source_path_prefix, file_to_parse)
        c.relations["symmetric"].append(('++', 'printf'))
        with purify(file_path) as pure_file_path:
            ast = parse_file(pure_file_path)
            mascm = create_mascm(deque([ast]))
        result = list(detect_atomicity_violation(mascm))

        self.assertEqual(0, len(result))
        self.assertListEqual([], result)
    def test_atomicity_violation3(self):
        file_to_parse = "atomicity_violation3.c"
        file_path = join(self.source_path_prefix, file_to_parse)
        c.relations["symmetric"].append(('++', 'printf'))
        with purify(file_path) as pure_file_path:
            ast = parse_file(pure_file_path)
            mascm = create_mascm(deque([ast]))
        result = list(detect_atomicity_violation(mascm))

        self.assertEqual(1, len(result))
        # First thread
        self.assertEqual(mascm.edges[18], result[0][0][0])
        self.assertEqual(mascm.edges[36], result[0][0][1])
        self.assertEqual(mascm.edges[51], result[0][0][2])
    def test_atomicity_violation5_with_forward_relation(self):
        file_to_parse = "atomicity_violation5.c"
        file_path = join(self.source_path_prefix, file_to_parse)
        c.relations["forward"].append(('++', 'printf'))
        c.relations["forward"].append(('--', 'printf'))
        with purify(file_path) as pure_file_path:
            ast = parse_file(pure_file_path)
            mascm = create_mascm(deque([ast]))
        result = list(detect_atomicity_violation(mascm))

        self.assertEqual(2, len(result))
        # First thread
        self.assertEqual(mascm.edges[20], result[0][0][0])
        self.assertEqual(mascm.edges[31], result[0][0][1])
        self.assertEqual(mascm.edges[37], result[0][0][2])

        self.assertEqual(mascm.edges[22], result[1][0][0])
        self.assertEqual(mascm.edges[33], result[1][0][1])
        self.assertEqual(mascm.edges[39], result[1][0][2])
Пример #4
0
def main():
    """ Main function
    """
    args = parser.parse_args()
    c.relations['forward'].extend(args.forward_rel_pairs)
    c.relations['backward'].extend(args.backward_rel_pairs)
    c.relations['symmetric'].extend(args.symmetric_rel_pairs)
    logging.basicConfig(filename=join(dirname(__file__), "rdao.log"), level=args.log_level)
    mascm = create_mascm(create_ast(args.path, args.cflags))

    reported_errors = 0
    print("Race conditions:")
    for edge in detect_race_condition(mascm):
        print(f"\tRace condition detected in element: {edge}")
        print("\tError can be found in")
        print(f"\t\t{edge.first.node.coord}")
        print("\tDetected race condition is linked with")
        print(f"\t\tresource: {get_resource_name_from_edge(edge)}")
        print(f"\t\tdeclared in {edge.second.node.coord}\n")
        reported_errors += 1
    print(f"Race condition was reported {reported_errors} times.")
    print("="*60)

    reported_errors = 0
    print("Deadlocks:")
    for cause, edges in detect_deadlock(mascm):
        if DeadlockType.incorrect_lock_type != cause:
            print(f"\tDeadlock detected involving a set of locks: {set((edge.first for edge in chain(*edges)))}")
        else:
            print(f"\tDeadlock detected involving incorrect type of lock in recursion.")

        print("\t\tDeadlock cause:", deadlock_causes_str[cause])

        if DeadlockType.incorrect_lock_type != cause:
            print("\tLocking operations can be found in:")
            for edge in chain(*edges):
                print(f"\t\t{edge.second.node.coord}", end=" ")
                print(f"using mutex variable {edge.first.name} of type {lock_types_str[edge.first.type]}")
            print()
        else:
            edge1, edge2 = chain(*edges)
            print(f"\tReturn operation in {edge1.first.node.coord} returning to {edge1.second.node.coord}")
            print(f"\tCause re-lock of {edge2.first.name} by operation in {edge2.second.node.coord}")
            print(f"\t\tInvolved mutex has type {lock_types_str[edge2.first.type]}\n")
        reported_errors += 1
    print(f"Deadlock was reported {reported_errors} times.")
    print("="*60)

    reported_errors = 0
    print("Atomicity violations:")
    for collection in detect_atomicity_violation(mascm):
        for f_edge, s_edge, *rest in collection:
            f_name = get_operation_name_from_edge(f_edge)
            s_name = get_operation_name_from_edge(s_edge)
            print(f"\tAtomicity violation detect for pair: {f_name}, {s_name}")
            print(f"\t\t{f_name} is located in: {get_operation_from_edge(f_edge).node.coord}")
            print(f"\t\t{s_name} is located in: {get_operation_from_edge(s_edge).node.coord}")
            for edge in rest:
                print(f"\t\tViolation is cause by: {get_operation_name_from_edge(edge)}")
                print(f"\t\tViolating operation is located in: {get_operation_from_edge(edge).node.coord}")
            print()
        reported_errors += 1
    print(f"Atomicity violation was reported {reported_errors} times.")
    print("="*60)

    reported_errors = 0
    print("Order violations:")
    for op1, op2, resource in detect_order_violation(mascm):
        print(f"\tOrder violation detected for pair: {op1.name}, {op2.name}")
        print(f"\t\t{op1.name} is located in {op1.node.coord}")
        print(f"\t\t{op2.name} is located in {op2.node.coord}")
        print("\tDetected order violation is linked with ")
        print(f"\t\tresource: {resource.get_resource_names_set()}")
        print(f"\t\tdeclared in {resource.node.coord}\n")
        reported_errors += 1
    print(f"Order violation was reported {reported_errors} times.")