Description
Version and Platform (required):
- Binary Ninja Version: 4.3.6617-dev (28632797)
- OS: macOS
- OS Version: 15.1.1
- CPU Architecture: M1
Bug Description:
Not sure my title does a good job of capturing the issue here so please change it if you have a more succinct description.
Loading a large BNDB or file like DYLD Shared Cache in the background causes the main UI thread to hang alot. Using the sample
binary (on macOS) and with a debugger attached it seems that UI related updates to a Binary View created in a script can block the main UI thread even though this Binary View is not visible (and as far as I know can never be visible).
The issue isn't necessarily due to large BNDBs or DYLD Shared Cache, they just make it easier to observe because they tax Binary Ninja harder. I think there maybe 2 issues occurring here:
- Binary Views created through scripting (which I believe can never be visible?) trigger UI updates without actually having a visible UI.
- UI updates for every single Binary View that currently exists, including for each visible window of Binary Ninja (as long as its from the same Binary Ninja process which by default on macOS is the case), uses a single thread. So if 10 Binary Views are open and all 10 have ongoing analysis then thats 10 things all contending for a single thread everytime they trigger a UI update.
Assuming I'm correct here about these issues, this doesn't really make sense. I think the behaviour should be more like this:
- Each Binary Ninja window should have a separate UI thread.
- Binary Views in the same window, but behind different tabs, should only trigger UI updates if their tab is visible.
- Binary Views created with scripting should not trigger UI updates at all. If they can eventually be shown visibly to the user then at that point UI work should be done.
Steps To Reproduce:
- Create a large BNDB by loading many images of a copy of DYLD Shared Cache (10s-100s). In my testing I had a BNDB that was 20GB having loaded a 1000 images in DSC. Auto analysis was paused during the loading of those images and it required my custom version of the DSC plugin which made loading that many fairly quick. I mention this just for context as to what I was working with to cause this issue.
- Close Binary Ninja, re-open it and load some small binary.
- In the Python console load the BNDB created in step 1 using
binaryninja.load
and assign the result to a variable (not sure if the assignment actually matters).
dsc_bv = binaryninja.load("path/to/bndb")
- Observe the UI initially freezing for an extended period, during which it seems that just reading out the file is causing the UI to block continuously whilst it happens.
- Once the initial freeze has stopped and the background Binary View's file is loaded, observe micro freezes and stuttering as UI updates occur for the background BV.
Alternatively:
- Open Binary Ninja and open a copy of DYLD Shared Cache.
- Click
File -> New Window
in Binary Ninja. - Open any binary.
- In the first window with DYLD Shared Cache open use the Python console to continuously load all images in DSC:
dsc = binaryninja.sharedcache.SharedCache(bv) for image in dsc.images: dsc.load_image_with_install_name(image.name)
- Go back to the 2nd Binary Ninja window.
- Observe it freezing and stuttering due to the loading of images occurring in the 1st Binary Ninja window.
Those steps won't show binaryninja.load
causing the UI to freeze whilst it reads in a large file but they're quicker steps to replicate.
Expected Behavior:
- Binary Ninja should avoid blocking the UI thread when doing things like reading a file when calling
binaryninja.load
in the Python console.- No idea why this in particular happens because usually the Python console doesn't block the UI this badly.
- Binary Ninja should avoid doing UI updates for things that are not visible on the screen. In some cases this might be hard to determine but I think there's some low hanging fruit here.
Additional Information:
There's probably some relation to #6169.