Repository: angr/angr

Issue:
region identifier error
### Description

```
def subgraph_between_nodes(graph, source, frontier, include_frontier=False):
    """
    For a directed graph, return a subgraph that includes all nodes going from a source node to a target node.

    :param networkx.DiGraph graph:  The directed graph.
    :param source:                  The source node.
    :param list frontier:           A collection of target nodes.
    :param bool include_frontier:   Should nodes in frontier be included in the subgraph.
    :return:                        A subgraph.
    :rtype:                         networkx.DiGraph
    """

    graph = networkx.DiGraph(graph)  # make a copy
    for pred in list(graph.predecessors(source)):
        # make sure we cannot go from any other node to the source node
        graph.remove_edge(pred, source)

    g0 = networkx.DiGraph()

    if source not in graph or any(node not in graph for node in frontier):
        raise KeyError("Source node or frontier nodes are not in the source graph.")

    # BFS on graph and add new nodes to g0
    queue = [source]
    traversed = set()

    frontier = set(frontier)

    while queue:
        node = queue.pop(0)
        traversed.add(node)

        for _, succ, data in graph.out_edges(node, data=True):
            g0.add_edge(node, succ, **data)
            if succ in traversed or succ in frontier:
                continue
            for frontier_node in frontier:
                if networkx.has_path(graph, succ, frontier_node):
                    queue.append(succ)
                    break

    # recursively remove all nodes that have less than two neighbors
    to_remove = [
        n
        for n in g0.nodes()
        if n not in frontier and n is not source and (g0.out_degree[n] == 0 or g0.in_degree[n] == 0)
    ]
    while to_remove:
        g0.remove_nodes_from(to_remove)
        to_remove = [
            n
            for n in g0.nodes()
            if n not in frontier and n is not source and (g0.out_degree[n] == 0 or g0.in_degree[n] == 0)
        ]

    if not include_frontier:
        # remove the frontier nodes
        g0.remove_nodes_from(frontier)

    return g0
```
If don't skip g0.has_edge(node, succ), it will enter an infinite loop

### Steps to reproduce the bug
[归档.zip](https://github.com/angr/angr/files/11068273/default.zip)



### Environment

_No response_

### Additional context

_No response_


Discussion:

Resolving patch:
diff --git a/angr/analyses/decompiler/region_identifier.py b/angr/analyses/decompiler/region_identifier.py
--- a/angr/analyses/decompiler/region_identifier.py
+++ b/angr/analyses/decompiler/region_identifier.py
@@ -871,7 +871,7 @@ def _abstract_cyclic_region(
                 full_graph.add_edge(src, dst, **data)
                 if src in loop_nodes:
                     subgraph.add_edge(src, dst, **data)
-                elif src is region:
+                elif src == region:
                     subgraph.add_edge(head, dst, **data)
                 elif src in normal_entries:
                     # graph.add_edge(src, region, **data)
@@ -887,9 +887,9 @@ def _abstract_cyclic_region(
                 full_graph.add_edge(src, dst, **data)
                 if dst in loop_nodes:
                     subgraph.add_edge(src, dst, **data)
-                elif dst is region:
+                elif dst == region:
                     subgraph.add_edge(src, head, **data)
-                elif dst is normal_exit_node:
+                elif dst == normal_exit_node:
                     region_outedges.append((node, dst))
                     # graph.add_edge(region, dst, **data)
                     delayed_edges.append((region, dst, data))
diff --git a/angr/utils/graph.py b/angr/utils/graph.py
--- a/angr/utils/graph.py
+++ b/angr/utils/graph.py
@@ -146,6 +146,9 @@ def subgraph_between_nodes(graph, source, frontier, include_frontier=False):
         traversed.add(node)
 
         for _, succ, data in graph.out_edges(node, data=True):
+            if g0.has_edge(node, succ):
+                continue
+
             g0.add_edge(node, succ, **data)
             if succ in traversed or succ in frontier:
                 continue


Test patch: