Vector35 / Vector35/binaryninja-api

Filtering symbol list is unusably slow with large binary

Open
#7,363 2 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Impact: Medium UI: Symbols
Dominant language
C++
Stars
1.3k
Forks
298
Avg merge
5d 5h
Merged PRs (30d)
19

Description

Version and Platform (required):

  • Binary Ninja Version: 5.2.8240-dev
  • Edition: Commercial
  • OS: macOS
  • OS Version: 15.6.1 (24G90)
  • CPU Architecture: arm64

Bug Description:
After opening a large binary, filtering the symbol list becomes unusably slow.

Steps To Reproduce:
I opened a large binary (patched version of the YouTube iOS app, ~177MB) and started using the symbol list while analysis was ongoing.

Starting with some text in the filter text box, clearing the filter caused the UI to freeze for multiple minutes.
I attached two spindumps (below) showing a sampling profile of the process during a freeze. In both cases, the main thread was spending all its time in ComponentTree::setFilter -> QSortFilterProxyModel::setFilterFixedString -> … -> QSortFilterProxyModelPrivate::insert_source_items.

The spindump by itself can't distinguish between setFilterFixedString being slow and it being called many times. So I also attached a debugger and verified that the whole multi-minute wait was in a single call to setFilterFixedString.

Other operations similarly froze the UI:

  • Typing something into the filter text box was slow (but not as slow as clearing it).
  • Selecting all symbols using shift-click was fast, but right-clicking after selecting all resulted in an unusable menu. In this case, the slow function was QSortFilterProxyModelPrivate::store_persistent_indexes: each individual call took about a minute, but it was also being called over and over without any user action in between.

Overall, the slowness got worse over time, perhaps because the ongoing analysis was creating more data variables.

According to the console, the number of symbols (at some arbitrary point during analysis, after encountering the freezes) was:

>>> len(bv.functions)
847326
>>› len(bv.data_vars)
3023265

That's a large number, but not so large that I'd expect Binary Ninja to buckle under the load. Most of the UI seemed fine. Even the symbol list was fine if I didn't touch the filter list or select all symbols.

Incidentally, simply evaluating len(bv.data_vars) took several seconds.

Spindumps:
binaryninja_2356.2.spindump.txt
binaryninja_2356.3.spindump.txt

Binary:
Uploaded through the portal: coded archer inspires uniformly

Additional Information:
The function detection appears roughly correct, as function_starts data in the Mach-O shows 720,168 functions. I can't verify the data variable detection but the count seems reasonable.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the issue with the reported large binary and inspect the symbol-list path around ComponentTree::setFilter, QSortFilterProxyModel::setFilterFixedString, and store_persistent_indexes. Use the attached spindumps and profiling to identify why filtering and selection operations block the UI; done means these operations remain responsive during analysis at comparable symbol counts.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.