diff options
| -rw-r--r-- | binaryninjaapi.h | 18 | ||||
| -rw-r--r-- | binaryninjacore.h | 5 | ||||
| -rw-r--r-- | binaryview.cpp | 2 | ||||
| -rw-r--r-- | flowgraph.cpp | 12 | ||||
| -rw-r--r-- | python/binaryview.py | 17 | ||||
| -rw-r--r-- | python/flowgraph.py | 16 |
6 files changed, 59 insertions, 11 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 2df09818..daf3db4f 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -95,15 +95,22 @@ namespace BinaryNinja { #ifdef WIN32 if (InterlockedDecrement((LONG*)&m_refs) == 0) - delete this; + { + if (!m_registeredRef) + delete this; + } #else if (__sync_fetch_and_add(&m_refs, -1) == 1) - delete this; + { + if (!m_registeredRef) + delete this; + } #endif } public: int m_refs; + bool m_registeredRef = false; T* m_object; CoreRefCountObject(): m_refs(0), m_object(nullptr) {} virtual ~CoreRefCountObject() {} @@ -133,13 +140,15 @@ namespace BinaryNinja void AddRefForRegistration() { - AddRefInternal(); + m_registeredRef = true; } void ReleaseForRegistration() { m_object = nullptr; - ReleaseInternal(); + m_registeredRef = false; + if (m_refs == 0) + delete this; } }; @@ -2806,6 +2815,7 @@ namespace BinaryNinja static void PopulateNodesCallback(void* ctxt); static void CompleteLayoutCallback(void* ctxt); static BNFlowGraph* UpdateCallback(void* ctxt); + static void FreeObjectCallback(void* ctxt); protected: FlowGraph(BNFlowGraph* graph); diff --git a/binaryninjacore.h b/binaryninjacore.h index 25bf1e46..e29b813c 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1083,6 +1083,8 @@ extern "C" void* context; bool (*init)(void* ctxt); void (*freeObject)(void* ctxt); + void (*externalRefTaken)(void* ctxt); + void (*externalRefReleased)(void* ctxt); size_t (*read)(void* ctxt, void* dest, uint64_t offset, size_t len); size_t (*write)(void* ctxt, uint64_t offset, const void* src, size_t len); size_t (*insert)(void* ctxt, uint64_t offset, const void* src, size_t len); @@ -1961,6 +1963,9 @@ extern "C" void (*populateNodes)(void* ctxt); void (*completeLayout)(void* ctxt); BNFlowGraph* (*update)(void* ctxt); + void (*freeObject)(void* ctxt); + void (*externalRefTaken)(void* ctxt); + void (*externalRefReleased)(void* ctxt); }; struct BNRange diff --git a/binaryview.cpp b/binaryview.cpp index c70685ed..e0948a1c 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -479,6 +479,8 @@ BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryVi view.context = this; view.init = InitCallback; view.freeObject = FreeCallback; + view.externalRefTaken = nullptr; + view.externalRefReleased = nullptr; view.read = ReadCallback; view.write = WriteCallback; view.insert = InsertCallback; diff --git a/flowgraph.cpp b/flowgraph.cpp index 3de9c90e..9e3466c8 100644 --- a/flowgraph.cpp +++ b/flowgraph.cpp @@ -76,6 +76,11 @@ FlowGraph::FlowGraph() callbacks.prepareForLayout = PrepareForLayoutCallback; callbacks.populateNodes = PopulateNodesCallback; callbacks.completeLayout = CompleteLayoutCallback; + callbacks.update = UpdateCallback; + callbacks.freeObject = FreeObjectCallback; + callbacks.externalRefTaken = nullptr; + callbacks.externalRefReleased = nullptr; + AddRefForRegistration(); m_object = BNCreateCustomFlowGraph(&callbacks); } @@ -117,6 +122,13 @@ BNFlowGraph* FlowGraph::UpdateCallback(void* ctxt) } +void FlowGraph::FreeObjectCallback(void* ctxt) +{ + FlowGraph* graph = (FlowGraph*)ctxt; + graph->ReleaseForRegistration(); +} + + void FlowGraph::FinishPrepareForLayout() { BNFinishPrepareForLayout(m_object); diff --git a/python/binaryview.py b/python/binaryview.py index 1baeab2b..66c30d06 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -735,7 +735,6 @@ class BinaryView(object): _registered_instances = [] def __init__(self, file_metadata=None, parent_view=None, handle=None): - self._must_free = True if handle is not None: self.handle = core.handle_of_type(handle, core.BNBinaryView) if file_metadata is None: @@ -755,7 +754,8 @@ class BinaryView(object): self._cb = core.BNCustomBinaryView() self._cb.context = 0 self._cb.init = self._cb.init.__class__(self._init) - self._cb.freeObject = self._cb.freeObject.__class__(self._free_object) + self._cb.externalRefTaken = self._cb.externalRefTaken.__class__(self._external_ref_taken) + self._cb.externalRefReleased = self._cb.externalRefReleased.__class__(self._external_ref_released) self._cb.read = self._cb.read.__class__(self._read) self._cb.write = self._cb.write.__class__(self._write) self._cb.insert = self._cb.insert.__class__(self._insert) @@ -778,8 +778,6 @@ class BinaryView(object): if parent_view is not None: parent_view = parent_view.handle self.handle = core.BNCreateCustomBinaryView(self.__class__.name, file_metadata.handle, parent_view, self._cb) - self.__class__._registered_instances.append(self) - self._must_free = False self.notifications = {} self.next_address = None # Do NOT try to access view before init() is called, use placeholder @@ -925,8 +923,7 @@ class BinaryView(object): def __del__(self): for i in self.notifications.values(): i._unregister() - if self._must_free: - core.BNFreeBinaryView(self.handle) + core.BNFreeBinaryView(self.handle) def __iter__(self): count = ctypes.c_ulonglong(0) @@ -1388,7 +1385,13 @@ class BinaryView(object): log.log_error(traceback.format_exc()) return False - def _free_object(self, ctxt): + def _external_ref_taken(self, ctxt): + try: + self.__class__._registered_instances.append(self) + except: + log.log_error(traceback.format_exc()) + + def _external_ref_released(self, ctxt): try: self.__class__._registered_instances.remove(self) except: diff --git a/python/flowgraph.py b/python/flowgraph.py index 58add8b0..189b075c 100644 --- a/python/flowgraph.py +++ b/python/flowgraph.py @@ -338,6 +338,8 @@ class FlowGraph(object): from incoming edges, or graphs that have disjoint subgraphs will not render correctly. This will be fixed \ in a future version. """ + _registered_instances = [] + def __init__(self, handle = None): if handle is None: self._ext_cb = core.BNCustomFlowGraph() @@ -346,6 +348,8 @@ class FlowGraph(object): self._ext_cb.populateNodes = self._ext_cb.populateNodes.__class__(self._populate_nodes) self._ext_cb.completeLayout = self._ext_cb.completeLayout.__class__(self._complete_layout) self._ext_cb.update = self._ext_cb.update.__class__(self._update) + self._ext_cb.externalRefTaken = self._ext_cb.externalRefTaken.__class__(self._external_ref_taken) + self._ext_cb.externalRefReleased = self._ext_cb.externalRefReleased.__class__(self._external_ref_released) handle = core.BNCreateCustomFlowGraph(self._ext_cb) self.handle = handle @@ -390,6 +394,18 @@ class FlowGraph(object): log.log_error(traceback.format_exc()) return None + def _external_ref_taken(self, ctxt): + try: + self.__class__._registered_instances.append(self) + except: + log.log_error(traceback.format_exc()) + + def _external_ref_released(self, ctxt): + try: + self.__class__._registered_instances.remove(self) + except: + log.log_error(traceback.format_exc()) + def finish_prepare_for_layout(self): """ ``finish_prepare_for_layout`` signals that preparations for rendering a graph are complete. |
