IDArling icon indicating copy to clipboard operation
IDArling copied to clipboard

High CPU usage

Open trou opened this issue 4 years ago • 13 comments

Hello, when I start IDA with IDArling, d63bb7c887be9ca61ff3457eadebfb8ba4bb94ff, CPU usage reaches 100%, even without any IDB loaded.

perf reports the following as being the most CPU intensive functions:

     4.58%  ida              libQt5Core.so.5              [.] QT::QByteArray::append
     3.03%  ida              libQt5Core.so.5              [.] QT::QArrayData::allocate
     2.27%  ida              libQt5Core.so.5              [.] std::__atomic_base<int>::load
     1.89%  ida              libQt5Core.so.5              [.] std::__atomic_base<int>::store
     1.37%  ida              libQt5Core.so.5              [.] QT::QMetaObject::normalizedSignature
     1.34%  ida              libQt5Core.so.5              [.] 0x00000000000a4d4f
     1.20%  ida              libQt5Core.so.5              [.] 0x00000000000a4d4c
     1.09%  ida              libQt5Core.so.5              [.] std::__atomic_base<int>::operator--

I have done some experiments removing the status bar, but to no avail.

Any idea ?

trou avatar Mar 17 '20 09:03 trou

Hi @trou,

We experimented this kind of issue in the past... I thought I fixed it, apparently it was not enough...

I have no idea for the moment, can you indicate me your version of IDA in order to reproduce the bug please?

patateqbool avatar Mar 17 '20 09:03 patateqbool

Sure, it's Version 7.4.191112 Linux x86_64 (32-bit address size) running python3

trou avatar Mar 17 '20 09:03 trou

Thanks.

Regarding Python3 support for IDA 7.4, I do not expect IDArling to work properly. As we want to support IDA 7.2 for the moment, I haven’t backported changes made by contributors. It exists a version of IDArling compatible with python3 IDA 7.4 : https://gitlab.com/THUCSTA/IDArlingProject. This version includes a lot of changes, and I haven’t read the code yet, but it seems pretty good so far. Do you think you can try with this one and see if the CPU usage problem is solved?

patateqbool avatar Mar 17 '20 09:03 patateqbool

I actually started with the fork, which has the same problem. I'm currently trying to pin down the issue and it seems it's the eventFilter function in filter.py which is the culprit as CPU usage is "normal" when I comment it out.

trou avatar Mar 17 '20 09:03 trou

It seems it's this, more specifically:

        # Is it a QShowEvent on a QDialog named "Dialog"?
        if (
            ev.__class__ == ev,
            QShowEvent
            and obj.__class__ == QDialog
            and obj.windowTitle() == "About",
        ):
            # Find a child QGroupBox
            for groupBox in obj.children():
                if groupBox.__class__ == QGroupBox:
                    # Find a child QLabel with an icon
                    for label in groupBox.children():
                        if isinstance(label, QLabel) and label.pixmap():
                            self._replace_icon(label)

trou avatar Mar 17 '20 09:03 trou

Thank you for tracking down the issue.

This functionality is just an easter egg to replace the IDA logo with the IDArling logo. As a quick fix, you can disable it, if you don’t care about the custom logo :).

patateqbool avatar Mar 17 '20 09:03 patateqbool

This functionality is just an easter egg to replace the IDA logo with the IDArling logo.

This is also used for the invites context menu, as mentionned in the docstring.

it seems it's the eventFilter function in filter.py which is the culprit

It makes total sense: the event filter is installed on the main application window, so this function is getting called for every Qt event that is occuring within IDA. Not my brightest idea...

I'm not working on IDArling anymore, but I can offer some alternative ideas:

  • For the invite context menu, we can listen to the ui_finish_populating_widget_popup UI event, check if the widget is the disassembly window, unwrap it and then install the event filter on it.
  • For the "easter egg", there might be some way to hook the "About" menu, maybe by installing an event filter on the menu bar. But in the meantime, it should probably be disabled.

NeatMonster avatar Mar 17 '20 10:03 NeatMonster

I actually started with the fork, which has the same problem. I'm currently trying to pin down the issue and it seems it's the eventFilter function in filter.py which is the culprit as CPU usage is "normal" when I comment it out.

When he says the fork, he actually means he used https://github.com/fidgetingbits/IDArling/ afaict.

saidelike avatar Mar 17 '20 11:03 saidelike

indeed

trou avatar Mar 17 '20 22:03 trou

Here's a PR which reduces the CPU usage quite a bit when IDA's idle. https://github.com/IDArlingTeam/IDArling/pull/105

trou avatar Mar 20 '20 12:03 trou

BTW, to check for perf issues, I do:

  • use perf to check the most CPU intensive functions:
perf record -a -p $(pgrep ida)
perf report | head -n 50
[...]
     2.05%  ida              libpython3.7m.so.1.0         [.] long_bitwise
     1.13%  ida              libQt5Gui.so.5               [.] QT::QImage::pixel
  • use gdb after installing python3.7-dbg (debian):
(gdb) break long_bitwise 
Breakpoint 2 at 0x7f103ce8b1c0: file ../Objects/longobject.c, line 4421.

[...]
Thread 1 "ida" hit Breakpoint 1, long_bitwise (a=0x7f102dc99890, op=38 '&', b=0x7f103d145880 <small_ints.lto_priv+8320>) at ../Objects/longobject.c:4421                                                                                                                                                                                                                                                                                                                                                       
(gdb) py-bt                                                                                                                                                                                                         
Traceback (most recent call first):                                                                                                                                                                                 
  File "/home/raph/.idapro/plugins/idarling/interface/widget.py", line 33, in ida_to_python                                                                                                                         
    r = (c & 255) / 255.0                                                                                                                                                                                           
  File "/home/raph/.idapro/plugins/idarling/interface/widget.py", line 53, in make_icon                                                                                                                             
    r, g, b = StatusWidget.ida_to_python(color)                                                                                                                                                                     
  File "/home/raph/.idapro/plugins/idarling/interface/widget.py", line 187, in refresh                                                                                                                              
    pixmap = self.make_icon(template, color)                                                           

trou avatar Mar 20 '20 12:03 trou

as discussed with @patateqbool and as noted by @NeatMonster, the eventFilter should be removed if possible.

trou avatar Mar 20 '20 13:03 trou

It's possible to write code that is both Python 2 and 3 at the same time. See this excellent cheat sheet https://python-future.org/compatible_idioms.html

assafnativ avatar Aug 05 '20 05:08 assafnativ