Skip to content

Instantly share code, notes, and snippets.

@battleguard
Created December 1, 2023 14:48
Show Gist options
  • Save battleguard/10546597fc0140a75e5aa4b6a02473ea to your computer and use it in GitHub Desktop.
Save battleguard/10546597fc0140a75e5aa4b6a02473ea to your computer and use it in GitHub Desktop.
Circular reference detection methods
def obj_from_id(obj_id: int):
# <https://stackoverflow.com/a/15702647>
return ctypes.cast(obj_id, ctypes.py_object).value
def print_referrers_tree(obj_id: int, level=0, prev_ids: set[int] | None = None) -> None:
if prev_ids is None:
prev_ids = set[int]()
if level > 20:
return
if obj_id in prev_ids:
print(f"{' ' * level}{level+1}:{hex(obj_id)} | !CIRCULAR REFERENCE FOUND! | {(obj_from_id(obj_id)).__class__.__name__} | {obj_from_id(obj_id)}")
return
else:
print(f"{' ' * level}{level+1}:{hex(obj_id)} | {(obj_from_id(obj_id)).__class__.__name__} | {obj_from_id(obj_id)}")
referrer_ids = [id(r) for r in gc.get_referrers(obj_from_id(obj_id))]
gc.collect()
for r_id in referrer_ids:
new_set = set(prev_ids)
new_set.add(obj_id)
print_referrers_tree(r_id, level + 1, new_set)
@battleguard
Copy link
Author

1:0x163817ea170 | Controller | <__main__.Controller object at 0x00000163817EA170>
 2:0x16381c43940 | method | <bound method Controller.circular_callback of <__main__.Controller object at 0x00000163817EA170>>
  3:0x16381c43980 | dict | {'execute_time': 30, 'sim': <weakproxy at 0x0000016381C3D7B0 to PySim at 0x0000016381C30D00>, 'callback_func': <bound method Controller.circular_callback of <__main__.Controller object at 0x00000163817EA170>>}      
   4:0x16381c31f00 | PyEvent | PyEvent at 0x16381c31f00: self.execute_time=30 self.callback_func=<bound method Controller.circular_callback of <__main__.Controller object at 0x00000163817EA170>>
    5:0x163817e1180 | list | [PyEvent at 0x16381c31e70: self.execute_time=35 self.callback_func=<function safe_cb at 0x0000016381C4DB40>, PyEvent at 0x16381c31f00: self.execute_time=30 self.callback_func=<bound method Controller.circular_callback of <__main__.Controller object at 0x00000163817EA170>>]
     6:0x16381786340 | dict | {'events': [PyEvent at 0x16381c31e70: self.execute_time=35 self.callback_func=<function safe_cb at 0x0000016381C4DB40>, PyEvent at 0x16381c31f00: self.execute_time=30 self.callback_func=<bound method Controller.circular_callback of <__main__.Controller object at 0x00000163817EA170>>], 'sim_time': 0.0}
      7:0x16381c30d00 | PySim | <__main__.PySim object at 0x0000016381C30D00>
       8:0x163817f8ac0 | dict | {'sim': <__main__.PySim object at 0x0000016381C30D00>}
        9:0x163817ea170 | !CIRCULAR REFERENCE FOUND! | Controller | <__main__.Controller object at 0x00000163817EA170>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment