Hello,

I am encountering intermittent (but easily reproducible) segfaults when freeing 
an MMManager object using g_object_unref().

I am using libmm-glib from ModemManager 1.14.8 to get the state and signal 
quality on the modem I am using (u-blox TOBY-R200) on an embedded device.  I 
based the usage of the API on what is done in the mmcli source code when 
printing modem information.  In my code, I first create and initialize a 
GDBusConnection using g_bus_get_sync().  Then, in a 15-second loop, I:

    1. make sure the GDBusConnection still exists (attempting to remake it if 
it does not)
    2. create an MMManager for the connection with mm_manager_new_sync()
    3. make sure ModemManager is running using 
g_dbus_object_manager_client_get_name_owner() with the manager
    4. get a list of modems using g_dbus_object_manager_get_objects() with the 
manager
    5. use mm_object_get_modem() on the item in the list to get the modem object
    6. use mm_modem_get_state() and mm_modem_get_signal_quality() to get 
information from the modem object
    7. free all above objects using g_object_unref() (and g_list_free_full() on 
the list)

Between each step, I check to make sure there are no errors before proceeding.

This process works as far as getting the data -- I am able to successfully read 
the data from the modem and it updates each loop as expected.  However, after 
an indeterminate number of iterations (which varies, but usually within 5 
minutes or so), I encounter a segfault when freeing the MMManager object 
specifically.  Prior to the segfault, the rest of the iteration happens 
normally and data is still read correctly from the modem.  Here is a brief 
backtrace from gdb showing that the segfault happens during g_object_unref():

    Thread 6 "XXX" received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 0x73eff410 (LWP 2195)]
    0x764cb85c in g_type_check_instance_is_fundamentally_a () from 
/lib/libgobject-2.0.so.0
    (gdb) bt
    #0  0x764cb85c in g_type_check_instance_is_fundamentally_a () from 
/lib/libgobject-2.0.so.0
    #1  0x764a43fc in g_object_unref () from /lib/libgobject-2.0.so.0
    #2  0x76b429b4 in ?? () from /lib/libglib-2.0.so.0

And here is the code that I am using to actually do the freeing:

    /* Clean up */
    if (modem) {
        g_object_unref (modem);
    }
    if (object) {
        g_object_unref (object);
    }
    if (modems) {
        g_list_free_full (modems, g_object_unref);
    }
    if (manager) {
        g_object_unref (manager);
    }

Where "modem" is an MMModem*, "object" is an MMObject*, "modems" is a GList*, 
and "manager" is an MMManager*.  The DBusConnection* exists outside the loop 
and is freed afterwards.  The segfault, when it happens, *only* occurs when 
freeing "manager."

In my testing, I tried using g_clear_object(*manager) and encountered the same 
issue.  In addition, I compiled my application with it freeing every object 
other than the manager and it ran perfectly fine (other than the memory leak) 
for hours without encountering a segfault.

Do you have any idea what might be causing this?  Are there any potential 
workarounds I could use to free that object's memory?  I would appreciate any 
advice.

Best,

Andrew
_______________________________________________
ModemManager-devel mailing list
ModemManager-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel

Reply via email to