Repository: fwupd/fwupd (C)

Issue:
fwupd crashes with SIGTRAP and logs `GLib                 g_ptr_array_set_size: assertion 'rarray' failed`
Debian sid/unstable with *fwupd* 2.0.6-3

Since upgrading from 2.0.3-3 to 2.0.5-1, when resuming from ACPI S3, fwupd logs

    Feb 04 17:33:26 abreu systemd-logind[571]: Lid opened.
    Feb 04 17:33:26 abreu fwupd[74003]: 16:33:26.097 GLib                 g_ptr_array_set_size: assertion 'rarray' failed

```
$ fwupdmgr --version
compile   info.libusb                   1.0.27
compile   com.hughsie.libxmlb           0.3.21
compile   com.hughsie.libjcat           0.2.0
compile   org.freedesktop.fwupd         2.0.6
runtime   org.freedesktop.fwupd-efi     1.7
runtime   com.hughsie.libxmlb           0.3.21
runtime   com.hughsie.libjcat           0.2.0
runtime   org.kernel                    6.14.0-rc4-00169-g1e15510b71c9
runtime   org.freedesktop.fwupd         2.0.6
```


Discussion: Is this 100% reproducible?  If so; can you please change the systemd unit to launch in verbose mode (add `-vv` to the launch `ExecStart` command)  and repro again?  Would like to see what is happening right before that.
Personally, I'd like to see `sudo G_DEBUG=fatal-criticals gdb /usr/libexec/fwupd/fwupd` and then a `bt` when it crashes.
With debug symbols:

    sudo DEBUGINFOD_URLS="https://debuginfod.debian.net" G_DEBUG=fatal-criticals gdb /usr/libexec/fwupd/fwupd

```
#0  _g_log_abort (breakpoint=<optimized out>) at ../../../glib/gmessages.c:431
#1  g_logv (log_domain=0x7ffff76ac00e "GLib", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffb050) at ../../../glib/gmessages.c:1287
#2  0x00007ffff7653103 in g_log (log_domain=<optimized out>, log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff76ae3dc "%s: assertion '%s' failed")
    at ../../../glib/gmessages.c:1329
#3  0x00007ffff76541ed in g_return_if_fail_warning (log_domain=<optimized out>, pretty_function=<optimized out>, expression=<optimized out>) at ../../../glib/gmessages.c:3074
#4  0x00007ffff7b44ede in fu_device_rescan (self=self@entry=0x55555590a4c0, error=error@entry=0x7fffffffb160) at ../libfwupdplugin/fu-device.c:5757
#5  0x00007ffff7b90779 in fu_udev_device_emit_changed (self=self@entry=0x55555590a4c0) at ../libfwupdplugin/fu-udev-device.c:94
#6  0x00007ffff7ca9390 in fu_engine_backend_device_changed_cb (backend=<optimized out>, device=0x55555590a4c0, self=<optimized out>) at ../src/fu-engine.c:7470
#7  0x00007ffff775ba10 in g_closure_invoke (closure=0x55555596db30, return_value=0x0, n_param_values=2, param_values=0x7fffffffb3c0, invocation_hint=0x7fffffffb310)
    at ../../../gobject/gclosure.c:833
#8  0x00007ffff776fd83 in signal_emit_unlocked_R (node=node@entry=0x7fffffffb4a0, detail=detail@entry=0, instance=instance@entry=0x5555555bb470, 
    emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffb3c0) at ../../../gobject/gsignal.c:3902
#9  0x00007ffff77717a9 in signal_emit_valist_unlocked (instance=instance@entry=0x5555555bb470, signal_id=signal_id@entry=21, detail=detail@entry=0, 
    var_args=var_args@entry=0x7fffffffb600) at ../../../gobject/gsignal.c:3534
#10 0x00007ffff77775e6 in g_signal_emit_valist (instance=0x5555555bb470, signal_id=21, detail=0, var_args=0x7fffffffb600) at ../../../gobject/gsignal.c:3277
#11 0x00007ffff77776a3 in g_signal_emit (instance=instance@entry=0x5555555bb470, signal_id=<optimized out>, detail=detail@entry=0) at ../../../gobject/gsignal.c:3597
#12 0x00007ffff7b20801 in fu_backend_device_changed (self=self@entry=0x5555555bb470, device=device@entry=0x55555590a4c0) at ../libfwupdplugin/fu-backend.c:134
#13 0x00007ffff7ccecfe in fu_udev_backend_netlink_parse_blob (self=0x5555555bb470, blob=0x555555761770, error=0x7fffffffb730) at ../src/fu-udev-backend.c:468
#14 fu_udev_backend_netlink_cb (fd=<optimized out>, condition=<optimized out>, user_data=0x5555555bb470) at ../src/fu-udev-backend.c:509
#15 0x00007ffff7647f65 in g_main_dispatch (context=context@entry=0x5555555ae190) at ../../../glib/gmain.c:3398
#16 0x00007ffff764a197 in g_main_context_dispatch_unlocked (context=0x5555555ae190) at ../../../glib/gmain.c:4249
#17 g_main_context_iterate_unlocked (context=0x5555555ae190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../../../glib/gmain.c:4314
#18 0x00007ffff764abff in g_main_loop_run (loop=0x5555555bd8d0) at ../../../glib/gmain.c:4516
#19 0x000055555555ed9b in fu_daemon_start (self=self@entry=0x5555555ad290, error=error@entry=0x7fffffffe1d8) at ../src/fu-daemon.c:256
#20 0x000055555555d497 in main (argc=<optimized out>, argv=<optimized out>) at ../src/fu-main.c:213
```
```
(gdb) set pagination off
(gdb) bt f
#0  _g_log_abort (breakpoint=<optimized out>) at ../../../glib/gmessages.c:431
        debugger_present = 1
        debugger_present = <optimized out>
#1  g_logv (log_domain=0x7ffff76ac00e "GLib", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffb050) at ../../../glib/gmessages.c:1287
        domain = 0x0
        data = <optimized out>
        depth = <optimized out>
        log_func = <optimized out>
        domain_fatal_mask = <optimized out>
        masquerade_fatal = <optimized out>
        test_level = <optimized out>
        was_fatal = <optimized out>
        was_recursion = <optimized out>
        buffer = <optimized out>
        msg_alloc = 0x555555725de0 "g_ptr_array_set_size: assertion 'rarray' failed"
        msg = 0x555555725de0 "g_ptr_array_set_size: assertion 'rarray' failed"
        i = 3
        size = <optimized out>
#2  0x00007ffff7653103 in g_log (log_domain=<optimized out>, log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff76ae3dc "%s: assertion '%s' failed")
    at ../../../glib/gmessages.c:1329
        args = {{gp_offset = 40, fp_offset = 48, overflow_arg_area = 0x7fffffffb130, reg_save_area = 0x7fffffffb070}}
#3  0x00007ffff76541ed in g_return_if_fail_warning (log_domain=<optimized out>, pretty_function=<optimized out>, expression=<optimized out>) at ../../../glib/gmessages.c:3074
No locals.
#4  0x00007ffff7b44ede in fu_device_rescan (self=self@entry=0x55555590a4c0, error=error@entry=0x7fffffffb160) at ../libfwupdplugin/fu-device.c:5757
        priv = 0x55555590a220
        device_class = 0x555555787090
        __func__ = "fu_device_rescan"
#5  0x00007ffff7b90779 in fu_udev_device_emit_changed (self=self@entry=0x55555590a4c0) at ../libfwupdplugin/fu-udev-device.c:94
        error = 0x0
        __func__ = "fu_udev_device_emit_changed"
#6  0x00007ffff7ca9390 in fu_engine_backend_device_changed_cb (backend=<optimized out>, device=0x55555590a4c0, self=<optimized out>) at ../src/fu-engine.c:7470
        device_tmp = 0x55555597fa70
        i = 6
        plugins = 0x5555555b79e0
        devices = 0x555555760db0
#7  0x00007ffff775ba10 in g_closure_invoke (closure=0x55555596db30, return_value=0x0, n_param_values=2, param_values=0x7fffffffb3c0, invocation_hint=0x7fffffffb310)
    at ../../../gobject/gclosure.c:833
        marshal = 0x7ffff775efa0 <g_cclosure_marshal_VOID__OBJECT>
        marshal_data = 0x0
        in_marshal = 0
        real_closure = 0x55555596db10
        __func__ = "g_closure_invoke"
#8  0x00007ffff776fd83 in signal_emit_unlocked_R (node=node@entry=0x7fffffffb4a0, detail=detail@entry=0, instance=instance@entry=0x5555555bb470, 
    emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffb3c0) at ../../../gobject/gsignal.c:3902
        tmp = <optimized out>
        handler = 0x555555829d80
        accumulator = <optimized out>
        emission = {next = 0x0, instance = 0x5555555bb470, ihint = {signal_id = 21, detail = 0, run_type = (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACCUMULATOR_FIRST_RUN)}, 
          state = EMISSION_RUN, chain_type = 4}
        class_closure = <optimized out>
        hlist = <optimized out>
        handler_list = 0x555555829d80
        return_accu = <optimized out>
        accu = {g_type = 0, data = {{v_int = 0, v_uint = 0, v_long = 0, v_ulong = 0, v_int64 = 0, v_uint64 = 0, v_float = 0, v_double = 0, v_pointer = 0x0}, {v_int = 0, 
              v_uint = 0, v_long = 0, v_ulong = 0, v_int64 = 0, v_uint64 = 0, v_float = 0, v_double = 0, v_pointer = 0x0}}}
        signal_id = <optimized out>
        max_sequential_handler_number = <optimized out>
        return_value_altered = <optimized out>
        n_params = <optimized out>
        EMIT_RESTART = <optimized out>
        __func__ = "signal_emit_unlocked_R"
#9  0x00007ffff77717a9 in signal_emit_valist_unlocked (instance=instance@entry=0x5555555bb470, signal_id=signal_id@entry=21, detail=detail@entry=0, 
    var_args=var_args@entry=0x7fffffffb600) at ../../../gobject/gsignal.c:3534
        instance_and_params = <optimized out>
        param_values = 0x7fffffffb3d8
        node = <optimized out>
        i = <optimized out>
        __func__ = "signal_emit_valist_unlocked"
        node_copy = <optimized out>
#10 0x00007ffff77775e6 in g_signal_emit_valist (instance=0x5555555bb470, signal_id=21, detail=0, var_args=0x7fffffffb600) at ../../../gobject/gsignal.c:3277
No locals.
#11 0x00007ffff77776a3 in g_signal_emit (instance=instance@entry=0x5555555bb470, signal_id=<optimized out>, detail=detail@entry=0) at ../../../gobject/gsignal.c:3597
        var_args = {{gp_offset = 32, fp_offset = 48, overflow_arg_area = 0x7fffffffb6e0, reg_save_area = 0x7fffffffb620}}
#12 0x00007ffff7b20801 in fu_backend_device_changed (self=self@entry=0x5555555bb470, device=device@entry=0x55555590a4c0) at ../libfwupdplugin/fu-backend.c:134
        priv = <optimized out>
        __func__ = "fu_backend_device_changed"
#13 0x00007ffff7ccecfe in fu_udev_backend_netlink_parse_blob (self=0x5555555bb470, blob=0x555555761770, error=0x7fffffffb730) at ../src/fu-udev-backend.c:468
        ctx = 0x5555555b0820
        action = FU_UDEV_ACTION_CHANGE
        buf = 0x5555557fe678 "UDEV_DATABASE_VERSION=1"
        st_hdr = 0x555555637e10
        blob_payload = 0x55555575fa30
        bufsz = 253
        sysfsdir = 0x5555556b1630 "/sys"
        device_donor = 0x55555590a4c0
        ctx = <optimized out>
        action = <optimized out>
        buf = <optimized out>
        bufsz = <optimized out>
        sysfsdir = <optimized out>
        st_hdr = <optimized out>
        device_donor = <optimized out>
        blob_payload = <optimized out>
        i = <optimized out>
        kvstr = <optimized out>
        kv = <optimized out>
        sysfspath = <optimized out>
        device_tmp = <optimized out>
        _object_ptr = <optimized out>
        device_actual = <optimized out>
#14 fu_udev_backend_netlink_cb (fd=<optimized out>, condition=<optimized out>, user_data=0x5555555bb470) at ../src/fu-udev-backend.c:509
        self = <optimized out>
        len = <optimized out>
        buf = "libudev\000\376\355\312\376(\000\000\000(\000\000\000\375\000\000\000Q\313\031N", '\000' <repeats 12 times>, "UDEV_DATABASE_VERSION=1\000ACTION=change\000DEVPATH=/devices/pci0000:00/0000:00:1d.0/0000:3c:00.0/nvme/nvme0\000SUBSYSTEM=nvme\000NVME_EVENT=connected\000DEVNAME=/dev/nvme0\000NV"...
        blob = 0x555555761770
        error_local = 0x0
#15 0x00007ffff7647f65 in g_main_dispatch (context=context@entry=0x5555555ae190) at ../../../glib/gmain.c:3398
        dispatch = 0x7ffff76a4c00 <g_unix_fd_source_dispatch>
        prev_source = 0x0
        begin_time_nsec = 56460991710727
        was_in_call = 0
        user_data = 0x5555555bb470
        callback = 0x7ffff7cce720 <fu_udev_backend_netlink_cb>
        cb_funcs = 0x7ffff7742260 <g_source_callback_funcs>
        cb_data = 0x5555556b39b0
        need_destroy = <optimized out>
        source = 0x5555556e0e90
        current = 0x5555556ae3a0
        i = 0
        __func__ = "g_main_dispatch"
#16 0x00007ffff764a197 in g_main_context_dispatch_unlocked (context=0x5555555ae190) at ../../../glib/gmain.c:4249
No locals.
#17 g_main_context_iterate_unlocked (context=0x5555555ae190, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../../../glib/gmain.c:4314
        max_priority = 2147483647
        timeout_usec = -1
        some_ready = 1
        nfds = 2
        allocated_nfds = <optimized out>
        fds = 0x5555556b0de0
        begin_time_nsec = 56460991707231
#18 0x00007ffff764abff in g_main_loop_run (loop=0x5555555bd8d0) at ../../../glib/gmain.c:4516
        self = <optimized out>
        __func__ = "g_main_loop_run"
#19 0x000055555555ed9b in fu_daemon_start (self=self@entry=0x5555555ad290, error=error@entry=0x7fffffffe1d8) at ../src/fu-daemon.c:256
        klass = 0x5555555adb80
        priv = <optimized out>
        __func__ = "fu_daemon_start"
#20 0x000055555555d497 in main (argc=<optimized out>, argv=<optimized out>) at ../src/fu-main.c:213
        immediate_exit = 0
        timed_exit = 0
        socket_filename = <optimized out>
        options = {{long_name = 0x555555566234 "timed-exit", short_name = 0 '\000', flags = 0, arg = G_OPTION_ARG_NONE, arg_data = 0x7fffffffe1d4, 
            description = 0x555555566209 "Exit after a small delay", arg_description = 0x0}, {long_name = 0x55555556623f "immediate-exit", short_name = 0 '\000', flags = 0, 
            arg = G_OPTION_ARG_NONE, arg_data = 0x7fffffffe1d0, description = 0x555555566f80 "Exit after the engine has loaded", arg_description = 0x0}, {long_name = 0x0, 
            short_name = 0 '\000', flags = 0, arg = G_OPTION_ARG_NONE, arg_data = 0x0, description = 0x0, arg_description = 0x0}}
        socket_address = 0x0
        error = 0x0
        argv0_file = 0x5555555ae0d0
        context = 0x5555555bf570
        daemon = 0x5555555ad290
        argv0_monitor = 0x5555557aa070
        memory_monitor = 0x55555594de00
```



Fix (patch):
diff --git a/libfwupdplugin/fu-device.c b/libfwupdplugin/fu-device.c
index d237aa384e38..265e04298285 100644
--- a/libfwupdplugin/fu-device.c
+++ b/libfwupdplugin/fu-device.c
@@ -5771,7 +5771,8 @@ fu_device_rescan(FuDevice *self, GError **error)
 	g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
 
 	/* remove all GUIDs */
-	g_ptr_array_set_size(priv->instance_ids, 0);
+	if (priv->instance_ids != NULL)
+		g_ptr_array_set_size(priv->instance_ids, 0);
 	g_ptr_array_set_size(fu_device_get_instance_ids(self), 0);
 	g_ptr_array_set_size(fu_device_get_guids(self), 0);