GSConnect / gnome-shell-extension-gsconnect

KDE Connect implementation for GNOME
GNU General Public License v2.0
3.21k stars 259 forks source link

Memory leak - 700mb RAM #394

Closed x0a closed 5 years ago

x0a commented 5 years ago

Describe the bug Accumulates hundreds of MB of ram over the course of several hours.

To Reproduce Not entirely sure how to reproduce. But it happens pretty consistently. I've not changed any of the defaults, I've only connected one device, my tablet.

Screenshots screenshot from 2018-12-16 18-52-29 screenshot from 2018-12-16 12-34-18

Debug output Heap attached. Doesn't seem to match what the terminal shows.

g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed
g_object_unref: assertion 'G_IS_OBJECT (object)' failed

gsconnect.heap.zip

System Details (please complete the following information):

GSConnect environment (if applicable):

pegasusearl commented 2 years ago

Hello, I'm not sure if this one is related but I experienced giant memory usage as well. 11_10-10-03_381

In my case it's caused by a software that send massive amount of notifications. Perhaps the more notification in a session, the bigger ram usage is.

Here is the video of my reproduction: https://www.youtube.com/watch?v=pYR2W7_bsjQ&list=PLhcbq4A0YXYCYHE-XN5-nQcBam4Vq_DKj&index=1

ferdnyc commented 2 years ago

@pegasusearl

Hm, that's interesting! Some differential diagnosis:

  1. Are the notifications originating on the Linux side, or the Android side? (I'm not familiar with that application.)
  2. Whichever side they're on, do you have that device relaying notifications to peer devices?
  3. If it's on the Android side, what happens if you block relaying of that app's notifications?
  4. If it's on the Linux side and you're sharing notifications,
    1. Does the memory leak still happen if you disable notification sharing?
    2. Does it still happen if you disable the notification plugin completely?
  5. If it's on the Linux side and you're NOT sharing, does it still happen if you enable sharing? (I'm thinking maybe there's a leak where notifications that aren't being sent across the wire aren't properly disposed of.)
pegasusearl commented 2 years ago
  1. Linux side
  2. no
  3. - 4~5. there is no notification shared. At the time I didn't connect to any android devices. I only use GSconnect occasionally to copy files. I never do anything else with it. I'm not sure how do I do that. I already connected to my android device, in GSconnect I already enabled notification in Advanced Setting and make sure "Share Notification" is checked. And then in KDEconnect I made sure Notification Sync is enabled, and then made sure notification plugin does not require more permission. But notification is not sent when I call notify-send on linux. notify-send in GSconnect setting is also checked.

About that app: It was picosnitch's bug that sends massive amount of notification at short period. And the program that trigger said bug is a windows game, Nova Ragnarok. And it happened while there is problem with my internet. Very rare case that no one else will ever encounter. Not even me!

This can also be reproduced by calling notify-send every 0.05 second for few seconds. But doing that might make gnome unresponsive when opening notification window.

I'm not sure if there is any case where user would receive a lot of notification. One thing that I can think of is if I enable all notification instead of just mentions for Discord and run it for long period of time without rebooting.

Doing the discord thing appears to have similar effect. Memory usage slowly increase, sometimes it went down but overall it kept increasing. In my case it's still not a big problem.

Perhaps this is different than what people discussed above.

ferdnyc commented 2 years ago

@pegasusearl

Ah, sorry, I was on my phone when I sent that previous reply and couldn't look into things too deeply.

On the Android side, to receive notifications from a Linux peer you'd want the "Receive notifications" plugin enabled for that peer ­— "Notification sync" enables sharing in the other direction, for notifications that originate locally on the Android device.

On the Linux side, the Notifications plugin handles sharing in both directions, unlike on Android where it's two separate plugins. It can be enabled/disabled under "Advanced". (It's normally enabled). When enabled, the Notifications settings panel lets you enable/disable global notification sending, and then if that's enabled, also disable sharing for specific Linux application sources.

One thing I notice is that the DBus notification handler unpacks the notification contents anytime a notification comes in, because it handles managing the applications list unconditionally. Only then does it check whether notification sharing is enabled. If not, it bails, otherwise it attempts to generate a message over the wire to the connected peer.

https://github.com/GSConnect/gnome-shell-extension-gsconnect/blob/aa02b6ad1457bbe936dba0ff0ecc933ccd4e676e/src/service/plugins/notification.js#L232-L265

So, it's possible there's some sort of leak in GLib.Variant.deepUnpack() or Gio.Icon.deserialize(), which are used by notification.full_unpack() to unpack the notification payload. (That's another thing, this may only occur for notifications with a certain type of associated icon — you can simulate that by running notify-send with a -i argument and providing either a stock-icon name, or the path to an icon file. The code path for each is different.)

The other thing, though, is that AFAICT all of this plugin code runs on a per-peer basis. So if you didn't have any peers connected to the Linux machine at the time, none of this should even have been running. If that's the case, I'm really at a loss as to how the gjs process could've racked up so much memory usage. Unless perhaps we're not correctly dropping our DBus listener connections when peers disconnect, so that we'd still be bombarded with unhandled notifications.

You don't happen to see any messages like these in your user journal, referencing the GSConnect session bus connection, do you?

The maximum number of pending replies for "(some DBus address)" (connection details) has been reached

(I know what that message would look like because, in an unrelated problem, I've been getting flooded with them for goa-identity-service for some time now.)