Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault when using PkClient GTask, self.percentage() and pisi.api APIs that use the @locked decorator with a pisi.ui.UI override. #14

Open
joebonrichie opened this issue Apr 30, 2024 · 1 comment

Comments

@joebonrichie
Copy link

joebonrichie commented Apr 30, 2024

Since b068646

We're getting a segfault when we run self.percentage() from our pisi.ui.UI override for pisi APIs that use the @locked decorator.

The pisi locked decorator is here: https://github.com/getsolus/eopkg/blob/python3/pisi/api.py#L39

A simplified version of our code is below

class SimplePisiHandler(pisi.ui.UI):
    def __init__(self, base):
        pisi.ui.UI.__init__(self, False, False)
        # PackageKitPisiBackend
        self.base = base
        def notify(self, event, **keywords):
            if event == installing:
                emit_installing blah blah blah
                self.base.percentage(somenumber)

class PackageKitPisiBackend(PackageKitBaseBackend, PackagekitPackage):
    def __init__(self, args):
        PackageKitBaseBackend.__init__(self, args)
        self.get_db()
        self.saved_ui = pisi.context.ui

    def get_db(self):
        self.componentdb = pisi.db.componentdb.ComponentDB()
        # self.filesdb = pisi.db.filesdb.FilesDB()
        self.installdb = pisi.db.installdb.InstallDB()
        self.packagedb = pisi.db.packagedb.PackageDB()
        self.historydb = pisi.db.historydb.HistoryDB()
        self.repodb = pisi.db.repodb.RepoDB()

    def privileged(func):
        """
        Decorator for synchronizing privileged functions
        """
        def wrapper(self, *__args,**__kw):
            ui = SimplePisiHandler(self)
            pisi.api.set_userinterface(ui)
            try:
                func(self, *__args,**__kw)
            except Exception as e:
                raise(e)
            # FIXME: the first call gets garbled 16:2percentage'entagegeK100: invalid command 'parse:
            self.percentage(100)
            self.percentage(100)
            self.get_db()
            self.finished()
            pisi.api.set_userinterface(self.saved_ui)
        return wrapper

    @privileged
    def install_packages(self, transaction_flags, package_ids):
        pisi.api.install(packages)

When we don't try to emit percentage updates we no longer get a segfault. If we revert b068646 as a workaround we'll get a (pkcon:7463): GLib-GObject-CRITICAL **: 16:07:48.354: g_object_unref: assertion 'G_IS_OBJECT (object)' failed warning.

Additionally, we have to emit self.percentage(100) twice after finishing as the first call gets garbled up with a ' endix getting added to the self.percentage() call.

Interestingly emitting self.item_progress() updates doesn't result in a segfault only self.percentage()

Note that this segfault only occurs when using pisi APIs that use the @locked decorator. Using something like pisi.api.fetch we can set percentage updates and experience no segfault.

It seems a combination of the @locked decorator that calls pisi.db.invalidate_caches() which invalidates our self.get_db() initialized values and emitting self.percentage() updates is causing the issue.

Backtrace with b068646

(gdb) bt
#0  g_type_check_instance_is_fundamentally_a (type_instance=type_instance@entry=0x5646812bfe70, fundamental_type=fundamental_type@entry=0x50 [GObject])
    at ../gobject/gtype.c:4153
#1  0x00007f74dfd63d2e in g_object_unref (_object=0x5646812bfe70) at ../gobject/gobject.c:4287
#2  0x00007f74dff3b0a6 in glib_autoptr_clear_GTask (_ptr=0x5646812bfe70) at /usr/include/glib-2.0/gio/gio-autocleanups.h:138
#3  0x00007f74dff3b0c3 in glib_autoptr_cleanup_GTask (_ptr=0x7ffe60ccb280) at /usr/include/glib-2.0/gio/gio-autocleanups.h:138
#4  0x00007f74dff3df0c in pk_task_ready_cb (source_object=0x5646812b4370 [PkTaskText], res=0x5646812c15d0, user_data=0x5646812bfe70)
    at ../lib/packagekit-glib2/pk-task.c:846
#5  0x00007f74dfc1c33c in g_task_return_now (task=task@entry=0x5646812c15d0 [GTask]) at ../gio/gtask.c:1361
#6  0x00007f74dfc1d145 in g_task_return (type=<optimized out>, task=0x5646812c15d0 [GTask]) at ../gio/gtask.c:1430
#7  g_task_return (task=0x5646812c15d0 [GTask], type=<optimized out>) at ../gio/gtask.c:1387
#8  0x00007f74dff0a5a1 in pk_client_state_finish (state=0x5646812c1720 [PkClientState], error=0x0) at ../lib/packagekit-glib2/pk-client.c:245
#9  0x00007f74dff0ce96 in pk_client_signal_finished (state=0x5646812c1720 [PkClientState], exit_enum=PK_EXIT_ENUM_SUCCESS, runtime=7264)
    at ../lib/packagekit-glib2/pk-client.c:1202
#10 0x00007f74dff0d279 in pk_client_signal_cb
    (proxy=0x5646812c1390 [GDBusProxy], sender_name=0x7f74c0009610 ":1.360", signal_name=0x7f74c0008e40 "Finished", parameters=0x7f74c0003b60, user_data=0x5646812b9560) at ../lib/packagekit-glib2/pk-client.c:1284
#15 0x00007f74dfd7a2a0 in <emit signal 'g-signal' on instance 0x5646812c1390 [GDBusProxy]>
    (instance=instance@entry=0x5646812c1390, signal_id=<optimized out>, detail=<optimized out>) at ../gobject/gsignal.c:3583
    #11 0x00007f74dfd5e5fa in g_closure_invoke
    (closure=0x5646812aa800, return_value=0x0, n_param_values=4, param_values=0x7ffe60ccb6c0, invocation_hint=0x7ffe60ccb610)
    at ../gobject/gclosure.c:834
    #12 0x00007f74dfd72b16 in signal_emit_unlocked_R
    (node=node@entry=0x7ffe60ccb7c0, detail=detail@entry=0, instance=instance@entry=0x5646812c1390, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7ffe60ccb6c0) at ../gobject/gsignal.c:3888
    #13 0x00007f74dfd744c2 in signal_emit_valist_unlocked
    (instance=instance@entry=0x5646812c1390, signal_id=signal_id@entry=12, detail=detail@entry=0, var_args=var_args@entry=0x7ffe60ccb930)
    at ../gobject/gsignal.c:3520
    #14 0x00007f74dfd7a1de in g_signal_emit_valist (instance=0x5646812c1390, signal_id=12, detail=0, var_args=0x7ffe60ccb930)
    at ../gobject/gsignal.c:3263
#16 0x00007f74dfc8b205 in on_signal_received
    (connection=<optimized out>, sender_name=0x7f74c0006fb0 ":1.360", object_path=<optimized out>, interface_name=<optimized out>, signal_name=0x7f74c00094f0 "Finished", parameters=0x7f74c0003b60, user_data=0x5646812b0180) at ../gio/gdbusproxy.c:874
#17 0x00007f74dfc77395 in emit_signal_instance_in_idle_cb (data=0x7f74c0009240) at ../gio/gdbusconnection.c:3798
#18 0x00007f74dfe02377 in g_main_dispatch (context=context@entry=0x5646812a1dd0) at ../glib/gmain.c:3344
#19 0x00007f74dfe05677 in g_main_context_dispatch_unlocked (context=0x5646812a1dd0) at ../glib/gmain.c:4152
#20 g_main_context_iterate_unlocked (context=0x5646812a1dd0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
    at ../glib/gmain.c:4217
#21 0x00007f74dfe05fd7 in g_main_loop_run (loop=0x5646812a1ff0) at ../glib/gmain.c:4419
#22 0x0000564680126113 in main (argc=3, argv=0x7ffe60ccc008) at ../client/pk-console.c:2400
(gdb) 
#0  g_type_check_instance_is_fundamentally_a (type_instance=type_instance@entry=0x5646812bfe70, fundamental_type=fundamental_type@entry=0x50 [GObject])
    at ../gobject/gtype.c:4153
#1  0x00007f74dfd63d2e in g_object_unref (_object=0x5646812bfe70) at ../gobject/gobject.c:4287
#2  0x00007f74dff3b0a6 in glib_autoptr_clear_GTask (_ptr=0x5646812bfe70) at /usr/include/glib-2.0/gio/gio-autocleanups.h:138
#3  0x00007f74dff3b0c3 in glib_autoptr_cleanup_GTask (_ptr=0x7ffe60ccb280) at /usr/include/glib-2.0/gio/gio-autocleanups.h:138
#4  0x00007f74dff3df0c in pk_task_ready_cb (source_object=0x5646812b4370 [PkTaskText], res=0x5646812c15d0, user_data=0x5646812bfe70)
    at ../lib/packagekit-glib2/pk-task.c:846
#5  0x00007f74dfc1c33c in g_task_return_now (task=task@entry=0x5646812c15d0 [GTask]) at ../gio/gtask.c:1361
#6  0x00007f74dfc1d145 in g_task_return (type=<optimized out>, task=0x5646812c15d0 [GTask]) at ../gio/gtask.c:1430
#7  g_task_return (task=0x5646812c15d0 [GTask], type=<optimized out>) at ../gio/gtask.c:1387
#8  0x00007f74dff0a5a1 in pk_client_state_finish (state=0x5646812c1720 [PkClientState], error=0x0) at ../lib/packagekit-glib2/pk-client.c:245
#9  0x00007f74dff0ce96 in pk_client_signal_finished (state=0x5646812c1720 [PkClientState], exit_enum=PK_EXIT_ENUM_SUCCESS, runtime=7264)
    at ../lib/packagekit-glib2/pk-client.c:1202
#10 0x00007f74dff0d279 in pk_client_signal_cb
    (proxy=0x5646812c1390 [GDBusProxy], sender_name=0x7f74c0009610 ":1.360", signal_name=0x7f74c0008e40 "Finished", parameters=0x7f74c0003b60, user_data=0x5646812b9560) at ../lib/packagekit-glib2/pk-client.c:1284
#15 0x00007f74dfd7a2a0 in <emit signal 'g-signal' on instance 0x5646812c1390 [GDBusProxy]>
    (instance=instance@entry=0x5646812c1390, signal_id=<optimized out>, detail=<optimized out>) at ../gobject/gsignal.c:3583
    #11 0x00007f74dfd5e5fa in g_closure_invoke
    (closure=0x5646812aa800, return_value=0x0, n_param_values=4, param_values=0x7ffe60ccb6c0, invocation_hint=0x7ffe60ccb610)
    at ../gobject/gclosure.c:834
    #12 0x00007f74dfd72b16 in signal_emit_unlocked_R
    (node=node@entry=0x7ffe60ccb7c0, detail=detail@entry=0, instance=instance@entry=0x5646812c1390, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7ffe60ccb6c0) at ../gobject/gsignal.c:3888
    #13 0x00007f74dfd744c2 in signal_emit_valist_unlocked
    (instance=instance@entry=0x5646812c1390, signal_id=signal_id@entry=12, detail=detail@entry=0, var_args=var_args@entry=0x7ffe60ccb930)
    at ../gobject/gsignal.c:3520
    #14 0x00007f74dfd7a1de in g_signal_emit_valist (instance=0x5646812c1390, signal_id=12, detail=0, var_args=0x7ffe60ccb930)
    at ../gobject/gsignal.c:3263
#16 0x00007f74dfc8b205 in on_signal_received
    (connection=<optimized out>, sender_name=0x7f74c0006fb0 ":1.360", object_path=<optimized out>, interface_name=<optimized out>, signal_name=0x7f74c00094f0 "Finished", parameters=0x7f74c0003b60, user_data=0x5646812b0180) at ../gio/gdbusproxy.c:874
#17 0x00007f74dfc77395 in emit_signal_instance_in_idle_cb (data=0x7f74c0009240) at ../gio/gdbusconnection.c:3798
#18 0x00007f74dfe02377 in g_main_dispatch (context=context@entry=0x5646812a1dd0) at ../glib/gmain.c:3344
#19 0x00007f74dfe05677 in g_main_context_dispatch_unlocked (context=0x5646812a1dd0) at ../glib/gmain.c:4152
#20 g_main_context_iterate_unlocked (context=0x5646812a1dd0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
    at ../glib/gmain.c:4217
#21 0x00007f74dfe05fd7 in g_main_loop_run (loop=0x5646812a1ff0) at ../glib/gmain.c:4419
#22 0x0000564680126113 in main (argc=3, argv=0x7ffe60ccc008) at ../client/pk-console.c:2400
@joebonrichie
Copy link
Author

TODO: test commits from this branch PackageKit#756 (comment) as well as PackageKit#756

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant