We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
DefUseGraph.top_predecessors() may trigger an infinite recursion
<!--
*Disclaimer:
The angr suite is maintained by a small team of volunteers.
While we cannot guarantee any timeliness for fixes and enhancements, we will do our best.
For more real-time help with angr, from us and the community, join our [Slack.](http://angr.io/invite/)*
-->

**Describe the bug.**
<!--
Please include a clear and concise description of what the bug is.
-->

Infinite recursion triggered by one of the test cases. Raw log is [here](https://dev.azure.com/angr/64bc1357-22a8-47d9-a89e-588cd888be53/_apis/build/builds/1354/logs/104).

```
======================================================================
ERROR: test_def_use_graph.transplant_class.<locals>.C (test_top_predecessors_should_not_contain_duplicates)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/__w/1/s/build/src/angr/tests/test_def_use_graph.py", line 100, in test_top_predecessors_should_not_contain_duplicates
    result = def_use_graph.top_predecessors(D)
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 121, in top_predecessors
    return _top_predecessors(definition, self._graph, [])
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 118, in _top_predecessors
    result
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 116, in <lambda>
    lambda acc, definition: _top_predecessors(definition, graph, acc),
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 118, in _top_predecessors
    result
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 116, in <lambda>
    lambda acc, definition: _top_predecessors(definition, graph, acc),
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 118, in _top_predecessors
    result
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 116, in <lambda>
    lambda acc, definition: _top_predecessors(definition, graph, acc),
...snip...
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 116, in <lambda>
    lambda acc, definition: _top_predecessors(definition, graph, acc),
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 118, in _top_predecessors
    result
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 116, in <lambda>
    lambda acc, definition: _top_predecessors(definition, graph, acc),
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py", line 110, in _top_predecessors
    predecessors = list(graph.predecessors(definition))
  File "/__w/1/s/build/virtualenv/lib/python3.6/site-packages/networkx/classes/digraph.py", line 837, in predecessors
    return iter(self._pred[n])
  File "/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/definition.py", line 40, in __hash__
    return hash((self.atom, self.codeloc, self.data))
RecursionError: maximum recursion depth exceeded while calling a Python object
```


**Environment Information.**
<!--
Many common issues are caused by problems with the local Python environment.
Before submitting, double-check that your versions of all modules in the angr suite (angr, cle, pyvex, ...) are up to date.
Please include the output of `python -m angr.misc.bug_report` here.
-->

Latest master branches of all projects (except for CLE) by 1/5/2020 and `cle:feat/pe_fast_load`.

**To Reproduce.**
<!--
Please include *both a script to reproduce the crash, and attach the binary used, if possible*
-->

Cannot be reproduced reliably. But running the test case multiple times should trigger it (if lucky).

**Additional context.**
<!--
Add any other context about the problem here.
-->


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `angr/analyses/reaching_definitions/dep_graph.py`
Content:
```
1 from typing import Optional, Dict, List
2 from functools import reduce
3 
4 import networkx
5 
6 from .definition import Definition
7 
8 
9 def _is_definition(node):
10     return isinstance(node, Definition)
11 
12 
13 class DepGraph:
14     """
15     The representation of a dependency graph: a directed graph, where nodes are definitions, and edges represent uses.
16 
17     Mostly a wrapper around a <networkx.DiGraph>.
18     """
19 
20     def __init__(self, graph: Optional[networkx.DiGraph]=None):
21         """
22         :param graph: A graph where nodes are definitions, and edges represent uses.
23         """
24         # Used for memoization of the `transitive_closure` method.
25         self._transitive_closures: Dict = {}
26 
27         if graph and not all(map(_is_definition, graph.nodes)):
28             raise TypeError("In a DepGraph, nodes need to be <%s>s." % Definition.__name__)
29 
30         self._graph = graph if graph is not None else networkx.DiGraph()
31 
32     @property
33     def graph(self) -> networkx.DiGraph:
34         return self._graph
35 
36     def add_node(self, node: Definition) -> None:
37         """
38         :param node: The definition to add to the definition-use graph.
39         """
40         if not _is_definition(node):
41             raise TypeError("In a DepGraph, nodes need to be <%s>s." % Definition.__name__)
42 
43         self._graph.add_node(node)
44 
45     def add_edge(self, source: Definition, destination: Definition, **labels) -> None:
46         """
47         The edge to add to the definition-use graph. Will create nodes that are not yet present.
48 
49         :param source: The "source" definition, used by the "destination".
50         :param destination: The "destination" definition, using the variable defined by "source".
51         :param labels: Optional keyword arguments to represent edge labels.
52         """
53         if not _is_definition(source) and not _is_definition(destination):
54             raise TypeError("In a DepGraph, edges need to be between <%s>s." % Definition.__name__)
55 
56         self._graph.add_edge(source, destination, **labels)
57 
58     def transitive_closure(self, definition: Definition) -> networkx.DiGraph:
59         """
60         Compute the "transitive closure" of a given definition.
61         Obtained by transitively aggregating the ancestors of this definition in the graph.
62 
63         Note: Each definition is memoized to avoid any kind of recomputation across the lifetime of this object.
64 
65         :param definition:  The Definition to get transitive closure for.
66         :return:            A graph of the transitive closure of the given definition.
67         """
68 
69         def _transitive_closure(def_: Definition, graph: networkx.DiGraph, result: networkx.DiGraph):
70             if def_ in self._transitive_closures.keys():
71                 return self._transitive_closures[def_]
72 
73             predecessors = list(graph.predecessors(def_))
74 
75             result.add_node(def_)
76             result.add_edges_from(list(map(
77                 lambda e: (*e, graph.get_edge_data(*e)),
78                 map(
79                     lambda p: (p, def_),
80                     predecessors
81                 )
82             )))
83 
84             closure = reduce(
85                 lambda acc, definition: _transitive_closure(definition, graph, acc),
86                 predecessors,
87                 result
88             )
89 
90             self._transitive_closures[def_] = closure
91             return closure
92 
93         return _transitive_closure(definition, self._graph, networkx.DiGraph())
94 
95     def top_predecessors(self, definition: Definition) -> List[Definition]:
96         """
97         Recover the "entrypoint definitions" flowing into a given definition.
98         Obtained by transitively computing the top-level ancestors (nodes without predecessors) of this definition in
99         the graph.
100 
101         :param definition: The <Definition> to return the top-level ancestors for.
102         :return: The list of top-level definitions flowing into the <node>.
103         """
104 
105         def _top_predecessors(def_: Definition, graph: networkx.DiGraph, result: List[Definition]):
106             predecessors = list(graph.predecessors(def_))
107 
108             if len(predecessors) == 0 and def_ not in result:
109                 return result + [ def_ ]
110 
111             return reduce(
112                 lambda acc, definition: _top_predecessors(definition, graph, acc),
113                 predecessors,
114                 result
115             )
116 
117         return _top_predecessors(definition, self._graph, [])
118
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/angr/analyses/reaching_definitions/dep_graph.py b/angr/analyses/reaching_definitions/dep_graph.py
--- a/angr/analyses/reaching_definitions/dep_graph.py
+++ b/angr/analyses/reaching_definitions/dep_graph.py
@@ -1,4 +1,4 @@
-from typing import Optional, Dict, List
+from typing import Optional, Dict
 from functools import reduce
 
 import networkx
@@ -91,27 +91,3 @@
             return closure
 
         return _transitive_closure(definition, self._graph, networkx.DiGraph())
-
-    def top_predecessors(self, definition: Definition) -> List[Definition]:
-        """
-        Recover the "entrypoint definitions" flowing into a given definition.
-        Obtained by transitively computing the top-level ancestors (nodes without predecessors) of this definition in
-        the graph.
-
-        :param definition: The <Definition> to return the top-level ancestors for.
-        :return: The list of top-level definitions flowing into the <node>.
-        """
-
-        def _top_predecessors(def_: Definition, graph: networkx.DiGraph, result: List[Definition]):
-            predecessors = list(graph.predecessors(def_))
-
-            if len(predecessors) == 0 and def_ not in result:
-                return result + [ def_ ]
-
-            return reduce(
-                lambda acc, definition: _top_predecessors(definition, graph, acc),
-                predecessors,
-                result
-            )
-
-        return _top_predecessors(definition, self._graph, [])

{"golden_diff": "diff --git a/angr/analyses/reaching_definitions/dep_graph.py b/angr/analyses/reaching_definitions/dep_graph.py\n--- a/angr/analyses/reaching_definitions/dep_graph.py\n+++ b/angr/analyses/reaching_definitions/dep_graph.py\n@@ -1,4 +1,4 @@\n-from typing import Optional, Dict, List\n+from typing import Optional, Dict\n from functools import reduce\n \n import networkx\n@@ -91,27 +91,3 @@\n             return closure\n \n         return _transitive_closure(definition, self._graph, networkx.DiGraph())\n-\n-    def top_predecessors(self, definition: Definition) -> List[Definition]:\n-        \"\"\"\n-        Recover the \"entrypoint definitions\" flowing into a given definition.\n-        Obtained by transitively computing the top-level ancestors (nodes without predecessors) of this definition in\n-        the graph.\n-\n-        :param definition: The <Definition> to return the top-level ancestors for.\n-        :return: The list of top-level definitions flowing into the <node>.\n-        \"\"\"\n-\n-        def _top_predecessors(def_: Definition, graph: networkx.DiGraph, result: List[Definition]):\n-            predecessors = list(graph.predecessors(def_))\n-\n-            if len(predecessors) == 0 and def_ not in result:\n-                return result + [ def_ ]\n-\n-            return reduce(\n-                lambda acc, definition: _top_predecessors(definition, graph, acc),\n-                predecessors,\n-                result\n-            )\n-\n-        return _top_predecessors(definition, self._graph, [])\n", "issue": "DefUseGraph.top_predecessors() may trigger an infinite recursion\n<!--\r\n*Disclaimer:\r\nThe angr suite is maintained by a small team of volunteers.\r\nWhile we cannot guarantee any timeliness for fixes and enhancements, we will do our best.\r\nFor more real-time help with angr, from us and the community, join our [Slack.](http://angr.io/invite/)*\r\n-->\r\n\r\n**Describe the bug.**\r\n<!--\r\nPlease include a clear and concise description of what the bug is.\r\n-->\r\n\r\nInfinite recursion triggered by one of the test cases. Raw log is [here](https://dev.azure.com/angr/64bc1357-22a8-47d9-a89e-588cd888be53/_apis/build/builds/1354/logs/104).\r\n\r\n```\r\n======================================================================\r\nERROR: test_def_use_graph.transplant_class.<locals>.C (test_top_predecessors_should_not_contain_duplicates)\r\n----------------------------------------------------------------------\r\nTraceback (most recent call last):\r\n  File \"/__w/1/s/build/src/angr/tests/test_def_use_graph.py\", line 100, in test_top_predecessors_should_not_contain_duplicates\r\n    result = def_use_graph.top_predecessors(D)\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 121, in top_predecessors\r\n    return _top_predecessors(definition, self._graph, [])\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 118, in _top_predecessors\r\n    result\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 116, in <lambda>\r\n    lambda acc, definition: _top_predecessors(definition, graph, acc),\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 118, in _top_predecessors\r\n    result\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 116, in <lambda>\r\n    lambda acc, definition: _top_predecessors(definition, graph, acc),\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 118, in _top_predecessors\r\n    result\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 116, in <lambda>\r\n    lambda acc, definition: _top_predecessors(definition, graph, acc),\r\n...snip...\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 116, in <lambda>\r\n    lambda acc, definition: _top_predecessors(definition, graph, acc),\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 118, in _top_predecessors\r\n    result\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 116, in <lambda>\r\n    lambda acc, definition: _top_predecessors(definition, graph, acc),\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/def_use_graph.py\", line 110, in _top_predecessors\r\n    predecessors = list(graph.predecessors(definition))\r\n  File \"/__w/1/s/build/virtualenv/lib/python3.6/site-packages/networkx/classes/digraph.py\", line 837, in predecessors\r\n    return iter(self._pred[n])\r\n  File \"/__w/1/s/build/src/angr/angr/analyses/reaching_definitions/definition.py\", line 40, in __hash__\r\n    return hash((self.atom, self.codeloc, self.data))\r\nRecursionError: maximum recursion depth exceeded while calling a Python object\r\n```\r\n\r\n\r\n**Environment Information.**\r\n<!--\r\nMany common issues are caused by problems with the local Python environment.\r\nBefore submitting, double-check that your versions of all modules in the angr suite (angr, cle, pyvex, ...) are up to date.\r\nPlease include the output of `python -m angr.misc.bug_report` here.\r\n-->\r\n\r\nLatest master branches of all projects (except for CLE) by 1/5/2020 and `cle:feat/pe_fast_load`.\r\n\r\n**To Reproduce.**\r\n<!--\r\nPlease include *both a script to reproduce the crash, and attach the binary used, if possible*\r\n-->\r\n\r\nCannot be reproduced reliably. But running the test case multiple times should trigger it (if lucky).\r\n\r\n**Additional context.**\r\n<!--\r\nAdd any other context about the problem here.\r\n-->\r\n\n", "before_files": [{"content": "from typing import Optional, Dict, List\nfrom functools import reduce\n\nimport networkx\n\nfrom .definition import Definition\n\n\ndef _is_definition(node):\n    return isinstance(node, Definition)\n\n\nclass DepGraph:\n    \"\"\"\n    The representation of a dependency graph: a directed graph, where nodes are definitions, and edges represent uses.\n\n    Mostly a wrapper around a <networkx.DiGraph>.\n    \"\"\"\n\n    def __init__(self, graph: Optional[networkx.DiGraph]=None):\n        \"\"\"\n        :param graph: A graph where nodes are definitions, and edges represent uses.\n        \"\"\"\n        # Used for memoization of the `transitive_closure` method.\n        self._transitive_closures: Dict = {}\n\n        if graph and not all(map(_is_definition, graph.nodes)):\n            raise TypeError(\"In a DepGraph, nodes need to be <%s>s.\" % Definition.__name__)\n\n        self._graph = graph if graph is not None else networkx.DiGraph()\n\n    @property\n    def graph(self) -> networkx.DiGraph:\n        return self._graph\n\n    def add_node(self, node: Definition) -> None:\n        \"\"\"\n        :param node: The definition to add to the definition-use graph.\n        \"\"\"\n        if not _is_definition(node):\n            raise TypeError(\"In a DepGraph, nodes need to be <%s>s.\" % Definition.__name__)\n\n        self._graph.add_node(node)\n\n    def add_edge(self, source: Definition, destination: Definition, **labels) -> None:\n        \"\"\"\n        The edge to add to the definition-use graph. Will create nodes that are not yet present.\n\n        :param source: The \"source\" definition, used by the \"destination\".\n        :param destination: The \"destination\" definition, using the variable defined by \"source\".\n        :param labels: Optional keyword arguments to represent edge labels.\n        \"\"\"\n        if not _is_definition(source) and not _is_definition(destination):\n            raise TypeError(\"In a DepGraph, edges need to be between <%s>s.\" % Definition.__name__)\n\n        self._graph.add_edge(source, destination, **labels)\n\n    def transitive_closure(self, definition: Definition) -> networkx.DiGraph:\n        \"\"\"\n        Compute the \"transitive closure\" of a given definition.\n        Obtained by transitively aggregating the ancestors of this definition in the graph.\n\n        Note: Each definition is memoized to avoid any kind of recomputation across the lifetime of this object.\n\n        :param definition:  The Definition to get transitive closure for.\n        :return:            A graph of the transitive closure of the given definition.\n        \"\"\"\n\n        def _transitive_closure(def_: Definition, graph: networkx.DiGraph, result: networkx.DiGraph):\n            if def_ in self._transitive_closures.keys():\n                return self._transitive_closures[def_]\n\n            predecessors = list(graph.predecessors(def_))\n\n            result.add_node(def_)\n            result.add_edges_from(list(map(\n                lambda e: (*e, graph.get_edge_data(*e)),\n                map(\n                    lambda p: (p, def_),\n                    predecessors\n                )\n            )))\n\n            closure = reduce(\n                lambda acc, definition: _transitive_closure(definition, graph, acc),\n                predecessors,\n                result\n            )\n\n            self._transitive_closures[def_] = closure\n            return closure\n\n        return _transitive_closure(definition, self._graph, networkx.DiGraph())\n\n    def top_predecessors(self, definition: Definition) -> List[Definition]:\n        \"\"\"\n        Recover the \"entrypoint definitions\" flowing into a given definition.\n        Obtained by transitively computing the top-level ancestors (nodes without predecessors) of this definition in\n        the graph.\n\n        :param definition: The <Definition> to return the top-level ancestors for.\n        :return: The list of top-level definitions flowing into the <node>.\n        \"\"\"\n\n        def _top_predecessors(def_: Definition, graph: networkx.DiGraph, result: List[Definition]):\n            predecessors = list(graph.predecessors(def_))\n\n            if len(predecessors) == 0 and def_ not in result:\n                return result + [ def_ ]\n\n            return reduce(\n                lambda acc, definition: _top_predecessors(definition, graph, acc),\n                predecessors,\n                result\n            )\n\n        return _top_predecessors(definition, self._graph, [])\n", "path": "angr/analyses/reaching_definitions/dep_graph.py"}], "after_files": [{"content": "from typing import Optional, Dict\nfrom functools import reduce\n\nimport networkx\n\nfrom .definition import Definition\n\n\ndef _is_definition(node):\n    return isinstance(node, Definition)\n\n\nclass DepGraph:\n    \"\"\"\n    The representation of a dependency graph: a directed graph, where nodes are definitions, and edges represent uses.\n\n    Mostly a wrapper around a <networkx.DiGraph>.\n    \"\"\"\n\n    def __init__(self, graph: Optional[networkx.DiGraph]=None):\n        \"\"\"\n        :param graph: A graph where nodes are definitions, and edges represent uses.\n        \"\"\"\n        # Used for memoization of the `transitive_closure` method.\n        self._transitive_closures: Dict = {}\n\n        if graph and not all(map(_is_definition, graph.nodes)):\n            raise TypeError(\"In a DepGraph, nodes need to be <%s>s.\" % Definition.__name__)\n\n        self._graph = graph if graph is not None else networkx.DiGraph()\n\n    @property\n    def graph(self) -> networkx.DiGraph:\n        return self._graph\n\n    def add_node(self, node: Definition) -> None:\n        \"\"\"\n        :param node: The definition to add to the definition-use graph.\n        \"\"\"\n        if not _is_definition(node):\n            raise TypeError(\"In a DepGraph, nodes need to be <%s>s.\" % Definition.__name__)\n\n        self._graph.add_node(node)\n\n    def add_edge(self, source: Definition, destination: Definition, **labels) -> None:\n        \"\"\"\n        The edge to add to the definition-use graph. Will create nodes that are not yet present.\n\n        :param source: The \"source\" definition, used by the \"destination\".\n        :param destination: The \"destination\" definition, using the variable defined by \"source\".\n        :param labels: Optional keyword arguments to represent edge labels.\n        \"\"\"\n        if not _is_definition(source) and not _is_definition(destination):\n            raise TypeError(\"In a DepGraph, edges need to be between <%s>s.\" % Definition.__name__)\n\n        self._graph.add_edge(source, destination, **labels)\n\n    def transitive_closure(self, definition: Definition) -> networkx.DiGraph:\n        \"\"\"\n        Compute the \"transitive closure\" of a given definition.\n        Obtained by transitively aggregating the ancestors of this definition in the graph.\n\n        Note: Each definition is memoized to avoid any kind of recomputation across the lifetime of this object.\n\n        :param definition:  The Definition to get transitive closure for.\n        :return:            A graph of the transitive closure of the given definition.\n        \"\"\"\n\n        def _transitive_closure(def_: Definition, graph: networkx.DiGraph, result: networkx.DiGraph):\n            if def_ in self._transitive_closures.keys():\n                return self._transitive_closures[def_]\n\n            predecessors = list(graph.predecessors(def_))\n\n            result.add_node(def_)\n            result.add_edges_from(list(map(\n                lambda e: (*e, graph.get_edge_data(*e)),\n                map(\n                    lambda p: (p, def_),\n                    predecessors\n                )\n            )))\n\n            closure = reduce(\n                lambda acc, definition: _transitive_closure(definition, graph, acc),\n                predecessors,\n                result\n            )\n\n            self._transitive_closures[def_] = closure\n            return closure\n\n        return _transitive_closure(definition, self._graph, networkx.DiGraph())\n", "path": "angr/analyses/reaching_definitions/dep_graph.py"}]}