summaryrefslogtreecommitdiff
path: root/suite/testcommon.py
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2019-04-30 20:15:28 -0400
committerRusty Wagner <rusty@vector35.com>2019-04-30 20:16:22 -0400
commit9331755a3986941375d0362c098979e3d8b59dc9 (patch)
treef197c9bab21acfb07e5ecd5f81a423a65d278776 /suite/testcommon.py
parentb1460bf69207f4a4719e8a809a4744817dac01cf (diff)
Add unit test to detect memory leaks
Diffstat (limited to 'suite/testcommon.py')
-rw-r--r--suite/testcommon.py44
1 files changed, 44 insertions, 0 deletions
diff --git a/suite/testcommon.py b/suite/testcommon.py
index 70f815a0..02ed13c4 100644
--- a/suite/testcommon.py
+++ b/suite/testcommon.py
@@ -862,3 +862,47 @@ class VerifyBuilder(Builder):
return [str(functions == bndb_functions and comments == bndb_comments)]
finally:
self.delete_package("helloworld")
+
+ def test_memory_leaks(self):
+ """Detected memory leaks during analysis"""
+ # This test will attempt to detect object leaks during headless analysis
+ file_name = self.unpackage_file("helloworld")
+ try:
+ # Open the binary once and let any persistent structures be created (typically types)
+ bv = binja.BinaryViewType['ELF'].open(file_name)
+ bv.update_analysis_and_wait()
+ # Hold on to a graph reference while tearing down the binary view. This will keep a reference
+ # in the core. If we directly free the view, the teardown will happen in a worker thread and
+ # we will not be able to get a reliable object count. By keeping a reference in a different
+ # object in the core, the teardown will occur immediately upon freeing the other object.
+ graph = bv.functions[0].create_graph()
+ bv.file.close()
+ del bv
+ import gc
+ gc.collect()
+ del graph
+ gc.collect()
+
+ initial_object_counts = binja.get_memory_usage_info()
+
+ # Analyze the binary again
+ bv = binja.BinaryViewType['ELF'].open(file_name)
+ bv.update_analysis_and_wait()
+ graph = bv.functions[0].create_graph()
+ bv.file.close()
+ del bv
+ gc.collect()
+ del graph
+ gc.collect()
+
+ # Capture final object count
+ final_object_counts = binja.get_memory_usage_info()
+
+ # Check for leaks
+ ok = True
+ for i in initial_object_counts.keys():
+ if final_object_counts[i] > initial_object_counts[i]:
+ ok = False
+ return ok
+ finally:
+ self.delete_package("helloworld")