Skip to content

Something is triggering invisible work and sometimes re-analysis and leaking memory #6608

Open
@WeiN76LQh

Description

@WeiN76LQh

Version and Platform (required):

  • Binary Ninja Version: 5.0.7195-dev (2abafca6)
  • OS: macOS
  • OS Version: 15.2
  • CPU Architecture: M1

Bug Description:
Clicking around a bunch in HLIL of a DSC view seems to cause invisible work to be triggered (Binary Ninja doesn't tell you its doing anything but starts running a bunch of threads for a long perfiod of time). In the steps to reproduce below it doesn't seem to start doing re-analysis but I have had that happen before. Also it will start consuming a bunch of RAM and then not give it all back once its done.

This bug has been griefing quite a bit in larger database because the invisible work and re-analysis can take many hours and it can be triggered multiple times in the same session.

Steps To Reproduce:
Please provide all steps required to reproduce the behavior:

  1. Open the DYLD Shared Cache from the IPSW for iPhone17,2 iOS 18.1.1 22B91
  2. Wait for initial auto analysis to finish.
  3. Load the image /System/Library/Frameworks/Foundation.framework/Foundation.
  4. Wait for auto analysis to finish.
  5. Go to the function at 0x182300964 called -[NSFilePresenterXPCMessenger _makePresenter:accommodateEvictionWithSubitemURL:completionHandler:] in HLIL. No particular reason for that function other than I was looking for references to objc_msgSend.
  6. Click at the following locations in order: the red box (the reference to ___stack_chk_guard then the blue box (the reference to the field _queue) then the green box (the call to _objc_msgSend) and then the line below.
    Image
    I think the main problem here is _objc_msgSend which just clicking on it by itself seems to trigger the issue. I've found clicking around more makes things worse. So if you were to click on many different references to things and intermingle clicking on _objc_msgSend the duration of the invisible work and the memory consumption gets worse.
  7. Observe Binary Ninja will start doing a lot of work in the background. bv.analysis_info will not show anything. It will also rapidly start consuming memory, some of which will be given back once it is done but a bunch will remain allocated. I observed 10s of GBs of memory being consumed after all analysis was completed just by clicking around like this.
  8. Repeat the steps again and observe that again lots of background work will begin and eventually memory consumption will start to go up again.

Additional Steps:
Things get weirder

  1. Do something in the Python console to trigger an analysis update which will result in extra work being done. For some reason the analysis stopped short. You'll notice in the screenshot above that the objc_msgSend calls have no parameters even though the function type is set to take 2. After analysis completes the function updates to look like this:
    Image
    Also these are the before and after memory usages when triggering the analysis update:
>>> get_memory_usage_info()
{'Active BasicBlock objects': 2312467, 'Active BinaryView objects': 6, 'Active Component objects': 0, 'Active FileMetadata objects': 3, 'Active FlowGraph objects': 0, 'Active Function objects': 162925, 'Active LowLevelILFunction objects': 13122, 'Active MediumLevelILFunction objects': 17400, 'Active Type objects': 3054578, 'Active TypeArchive objects': 0}
>>> get_memory_usage_info()
{'Active BasicBlock objects': 4606588, 'Active BinaryView objects': 6, 'Active Component objects': 0, 'Active FileMetadata objects': 3, 'Active FlowGraph objects': 0, 'Active Function objects': 162925, 'Active LowLevelILFunction objects': 52602, 'Active MediumLevelILFunction objects': 70040, 'Active Type objects': 3564068, 'Active TypeArchive objects': 0}

There's a huge number more IL function objects.
2. Do the clicking around again and observe the same invisible work issue
3. Call get_memory_usage_info() and see the stats have changed weirdly again:

>>> get_memory_usage_info()
{'Active BasicBlock objects': 2456535, 'Active BinaryView objects': 6, 'Active Component objects': 0, 'Active FileMetadata objects': 3, 'Active FlowGraph objects': 0, 'Active Function objects': 162925, 'Active LowLevelILFunction objects': 15453, 'Active MediumLevelILFunction objects': 20508, 'Active Type objects': 3099131, 'Active TypeArchive objects': 0}

Also this will trigger another analysis update that will do a meaningful amount of work. Memory usage after that analysis update looks like this:

>>> get_memory_usage_info()
{'Active BasicBlock objects': 2398970, 'Active BinaryView objects': 6, 'Active Component objects': 0, 'Active FileMetadata objects': 3, 'Active FlowGraph objects': 0, 'Active Function objects': 162925, 'Active LowLevelILFunction objects': 13353, 'Active MediumLevelILFunction objects': 17708, 'Active Type objects': 3104037, 'Active TypeArchive objects': 0}
  1. You can keep doing this over and over; clicking around, waiting for the CPU usage to drop, triggering auto-analysis through the Python console, waiting for the analysis update to finish, rinse and repeat.

Additional Information:

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions