def test_deadlock2(self): file_to_parse = "deadlock2.c" file_path = join(self.source_path_prefix, file_to_parse) with purify(file_path) as pure_file_path: ast = parse_file(pure_file_path) mascm = create_mascm(deque([ast])) result = list(detect_deadlock(mascm)) self.assertEqual(3, len(result), "Unexpected number of results.") self.assertEqual(2, len(result[0]), "Unexpected edges in the result.") self.assertEqual(2, len(result[1]), "Unexpected edges in the result.") self.assertEqual(2, len(result[2]), "Unexpected edges in the result.") # First pair self.assertEqual(DeadlockType.exclusion_lock, result[0][0], "Incorrect deadlock type") self.assertEqual(mascm.edges[10], result[0][1][0][0]) self.assertEqual(mascm.edges[12], result[0][1][0][1]) self.assertEqual(mascm.edges[32], result[0][1][1][0]) self.assertEqual(mascm.edges[34], result[0][1][1][1]) # Second pair self.assertEqual(DeadlockType.exclusion_lock, result[1][0], "Incorrect deadlock type") self.assertEqual(mascm.edges[10], result[1][1][0][0]) self.assertEqual(mascm.edges[14], result[1][1][0][1]) self.assertEqual(mascm.edges[30], result[1][1][1][0]) self.assertEqual(mascm.edges[34], result[1][1][1][1]) # Third pair self.assertEqual(DeadlockType.exclusion_lock, result[2][0], "Incorrect deadlock type") self.assertEqual(mascm.edges[12], result[2][1][0][0]) self.assertEqual(mascm.edges[14], result[2][1][0][1]) self.assertEqual(mascm.edges[30], result[2][1][1][0]) self.assertEqual(mascm.edges[32], result[2][1][1][1])
def test_no_recursion_deadlock1(self): file_to_parse = "no_recursion_deadlock1.c" file_path = join(self.source_path_prefix, file_to_parse) with purify(file_path) as pure_file_path: ast = parse_file(pure_file_path) mascm = create_mascm(deque([ast])) result = list(detect_deadlock(mascm)) self.assertEqual([], result)
def test_deadlock3(self): file_to_parse = "deadlock3.c" file_path = join(self.source_path_prefix, file_to_parse) with purify(file_path) as pure_file_path: ast = parse_file(pure_file_path) mascm = create_mascm(deque([ast])) result = list(detect_deadlock(mascm)) self.assertEqual(1, len(result), "Unexpected number of results.") self.assertEqual(DeadlockType.missing_unlock, result[0][0], "Incorrect deadlock type") self.assertEqual(mascm.edges[12], result[0][1][0][0])
def test_recursion_deadlock1(self): file_to_parse = "recursion_deadlock1.c" file_path = join(self.source_path_prefix, file_to_parse) with purify(file_path) as pure_file_path: ast = parse_file(pure_file_path) mascm = create_mascm(deque([ast])) result = list(detect_deadlock(mascm)) self.assertEqual(2, len(result), "Unexpected number of results.") self.assertEqual(DeadlockType.incorrect_lock_type, result[0][0], "Incorrect deadlock type") self.assertEqual(mascm.edges[19], result[0][1][0][0]) self.assertEqual(mascm.edges[10], result[0][1][0][1]) self.assertEqual(DeadlockType.incorrect_lock_type, result[1][0], "Incorrect deadlock type") self.assertEqual(mascm.edges[22], result[1][1][0][0]) self.assertEqual(mascm.edges[10], result[1][1][0][1])
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.")