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

ABI change in libfm.so.4 in recent commit #104

Closed
mtasaka opened this issue Dec 25, 2024 · 10 comments · Fixed by #105
Closed

ABI change in libfm.so.4 in recent commit #104

mtasaka opened this issue Dec 25, 2024 · 10 comments · Fixed by #105

Comments

@mtasaka
Copy link
Contributor

mtasaka commented Dec 25, 2024

Looks like due to
b0545e0
2854a4c

the size of struct _FmConfig got changed and this resulted in ABI change in libfm.so.4.

Downside bug report
https://bugzilla.redhat.com/show_bug.cgi?id=2333955

is perhaps due to the following condition

libfm between these commits includes 2854a4c

Then pcmanfm causes segfault.
The downside bug's backtrace seems to be sugesting that _cfg_mon in _FmConfig is not initialized to 0 despite that g_object_new is called.

@mtasaka
Copy link
Contributor Author

mtasaka commented Dec 25, 2024

Actually _cfg_mon seems to be 0-initialized, however gdb shows that later cfg->_cfg_mon gets modified at the wrong place:

tasaka1@localhost ~]$ gdb --args pcmanfm
GNU gdb (Fedora Linux) 15.2-3.fc41
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from pcmanfm...
Reading symbols from /usr/lib/debug/usr/bin/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64.debug...
(gdb) set style enabled off
(gdb) break fm_config_init
Function "fm_config_init" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (fm_config_init) pending.
(gdb) r
Starting program: /usr/bin/pcmanfm 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

(pcmanfm:719630): dbind-WARNING **: 16:26:10.627: Couldn't connect to accessibility bus: Failed to connect to socket /root/.cache/at-spi/bus_0: 許可がありません
Breakpoint 1, fm_config_init (self=0x4bc930 [FmConfig])
    at /usr/src/debug/libfm-1.3.2^20241216gitfb651b87-1.fc41.x86_64/libfm/_BUILDDIR_gtk3/../src/base/fm-config.c:137
137     {
(gdb) bt

#0  fm_config_init (self=0x4bc930 [FmConfig])
    at /usr/src/debug/libfm-1.3.2^20241216gitfb651b87-1.fc41.x86_64/libfm/_BUILDDIR_gtk3/../src/base/fm-config.c:137
#1  0x00007ffff6e9af27 in g_type_create_instance (type=0x4c00f0 [FmAppConfig/FmConfig]) at ../gobject/gtype.c:1945
#2  0x00007ffff6e801c4 in g_object_new_internal (class=0x4c0360, params=0x0, n_params=0) at ../gobject/gobject.c:2606
#3  0x00007ffff6e817de in g_object_new_internal (class=<optimized out>, params=<optimized out>, n_params=<optimized out>)
    at ../gobject/gobject.c:2603
#4  g_object_new_with_properties (object_type=<optimized out>, n_properties=<optimized out>, names=names@entry=0x0, values=values@entry=0x0)
    at ../gobject/gobject.c:2769
#5  0x00007ffff6e82801 in g_object_new (object_type=<optimized out>, first_property_name=first_property_name@entry=0x0)
    at ../gobject/gobject.c:2415
#6  0x0000000000407704 in fm_app_config_new () at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/app-config.c:543
#7  main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/pcmanfm.c:253
(gdb) p *self

$1 = {parent = {g_type_instance = {g_class = 0x4bff00 [g_type: FmConfig]}, ref_count = 1, qdata = 0x0}, _cfg_name = 0x0, terminal = 0x0, 
  archiver = 0x0, big_icon_size = 0, small_icon_size = 0, pane_icon_size = 0, thumbnail_size = 0, thumbnail_max = 0, auto_selection_delay = 0, 
  drop_default_action = 0, single_click = 0, middle_click = 0, use_trash = 0, confirm_del = 0, confirm_trash = 0, show_thumbnail = 0, 
  thumbnail_local = 0, show_internal_volumes = 0, si_unit = 0, advanced_mode = 0, force_startup_notify = 0, date_iso_8601 = 0, 
  backup_as_hidden = 0, no_usb_trash = 0, no_child_non_expandable = 0, show_full_names = 0, shadow_hidden = 0, places_home = 0, 
  places_desktop = 0, places_applications = 0, places_trash = 0, places_root = 0, places_computer = 0, places_network = 0, places_unmounted = 0, 
  only_user_templates = 0, template_run_app = 0, template_type_once = 0, defer_content_test = 0, quick_exec = 0, modules_blacklist = 0x0, 
  modules_whitelist = 0x0, system_modules_blacklist = 0x0, list_view_size_units = 0x0, format_cmd = 0x0, smart_desktop_autodrop = 0, 
  saved_search = 0x0, _reserved1 = 0x0, _reserved2 = 0x0, _reserved3 = 0x0, _reserved4 = 0x0, _reserved5 = 0x0, _reserved6 = 0x0, 
  _reserved7 = 0x0, _cfg_mon = 0x0}
(gdb) p &(self->_cfg_mon)

$2 = (GFileMonitor **) 0x4bca68
(gdb) watch *((long *)0x4b0x4bca68

Hardware watchpoint 2: *((long *)0x4bca68)
(gdb) c

Continuing.
[New Thread 0x7fffe7c006c0 (LWP 719694)]
[New Thread 0x7fffe72006c0 (LWP 719695)]
[New Thread 0x7fffe68006c0 (LWP 719696)]

Thread 1 "pcmanfm" hit Hardware watchpoint 2: *((long *)0x4bca68)

Old value = 0
New value = 5124544
_cfg_monitor_add (cfg=0x4bc930, path=0x4bde30 "/home/tasaka1/.config/libfm/libfm.conf")
    at /usr/src/debug/libfm-1.3.2^20241216gitfb651b87-1.fc41.x86_64/libfm/_BUILDDIR_gtk3/../src/base/fm-config.c:107
107         g_object_unref(gf);
Missing debuginfo, try: dnf debuginfo-install gvfs-client-1.56.1-1.fc41.x86_64

(gdb) c

Continuing.

Thread 1 "pcmanfm" hit Hardware watchpoint 2: *((long *)0x4bca68)

Old value = 5124544
New value = 4294967296
fm_app_config_init (cfg=0x4bc930) at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/app-config.c:495
fm_app_config_init (cfg=0x4bc930) at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/app-config.c:495
495         cfg->max_tab_chars = 32;

(gdb) li

490     
491         cfg->desktop_section.desktop_fg.red = cfg->desktop_section.desktop_fg.green = cfg->desktop_section.desktop_fg.blue = 65535;
492         cfg->win_width = 640;
493         cfg->win_height = 480;
494         cfg->splitter_pos = 150;
495         cfg->max_tab_chars = 32;
496         cfg->media_in_new_tab = FALSE;
497         cfg->desktop_folder_new_win = FALSE;
498     
499         cfg->side_pane_mode = FM_SP_PLACES;
(gdb) c

Continuing.
[New Thread 0x7fffe5e006c0 (LWP 719757)]
[New Thread 0x7fffe54006c0 (LWP 719758)]

Thread 1 "pcmanfm" hit Hardware watchpoint 2: *((long *)0x4bca68)

Old value = 4294967296
New value = 4294967297
fm_key_file_get_int (kf=kf@entry=0x5725c0, grp=grp@entry=0x43536c "config", key=key@entry=0x43535d "bm_open_method", val=val@entry=0x4bca68)
    at /usr/src/debug/libfm-1.3.2^20241216gitfb651b87-1.fc41.x86_64/libfm/_BUILDDIR_gtk3/../src/base/fm-utils.c:217
217             g_free(str);

(gdb) bt

#0  fm_key_file_get_int (kf=kf@entry=0x5725c0, grp=grp@entry=0x43536c "config", key=key@entry=0x43535d "bm_open_method", val=val@entry=0x4bca68)
    at /usr/src/debug/libfm-1.3.2^20241216gitfb651b87-1.fc41.x86_64/libfm/_BUILDDIR_gtk3/../src/base/fm-utils.c:217
#1  0x0000000000412437 in fm_app_config_load_from_key_file (cfg=cfg@entry=0x4bc930, kf=kf@entry=0x5725c0)
    at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/app-config.c:662
#2  0x0000000000407a7c in fm_app_config_load_from_profile (cfg=0x4bc930, name=0x436908 "default")
    at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/app-config.c:846
#3  main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/pcmanfm.c:273
(gdb) li

212     {
213         char* str = g_key_file_get_value(kf, grp, key, NULL);
214         if(G_LIKELY(str))
215         {
216             *val = atoi(str);
217             g_free(str);
218         }
219         return str != NULL;
220     }
221     
(gdb) c

Continuing.
[Thread 0x7fffe54006c0 (LWP 719758) exited]
[New Thread 0x7fffe54006c0 (LWP 719818)]
[New Thread 0x7fffe4a006c0 (LWP 719819)]
[New Thread 0x7fffdde006c0 (LWP 719820)]
[New Thread 0x7fffdd4006c0 (LWP 719822)]

(
Thread 1 "pcmanfm" received signal SIGSEGV, Segmentation fault.
g_type_check_instance (type_instance=0x100000001) at ../gobject/gtype.c:4257
4257          if (type_instance->g_class)
Missing debuginfo, try: dnf debuginfo-install ibus-gtk3-1.5.31-1.fc41.x86_64
Missing debuginfo, try: dnf debuginfo-install ibus-libs-1.5.31-1.fc41.x86_64
Missing debuginfo, try: dnf debuginfo-install rsvg-pixbuf-loader-2.59.2-1.fc41.x86_64
Missing debuginfo, try: dnf debuginfo-install librsvg2-2.59.2-1.fc41.x86_64

(gdb) bt

#0  g_type_check_instance (type_instance=0x100000001) at ../gobject/gtype.c:4257
#1  0x00007ffff6e8898c in g_signal_handlers_block_matched
    (instance=0x100000001, mask=mask@entry=(G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), signal_id=signal_id@entry=0, detail=detail@entry=0, closure=closure@entry=0x0, func=func@entry=0x7ffff70ae230 <_on_cfg_file_changed>, data=0x4bc930) at ../gobject/gsignal.c:2881
#2  0x00007ffff70a8296 in fm_config_save (cfg=0x4bc930, name=0x8eeb50 "/home/tasaka1/.config/libfm/libfm.conf", name@entry=0x0)
    at /usr/src/debug/libfm-1.3.2^20241216gitfb651b87-1.fc41.x86_64/libfm/_BUILDDIR_gtk3/../src/base/fm-config.c:487
#3  0x0000000000411f96 in pcmanfm_save_config (immediate=1)
    at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/pcmanfm.c:594
#4  on_save_config_idle (user_data=<optimized out>) at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/pcmanfm.c:585
#5  0x00007ffff7c2c00d in gdk_threads_dispatch (data=data@entry=0x8cc9a0) at ../gdk/gdk.c:769
#6  0x00007ffff6d5eadd in g_idle_dispatch (source=0x8f5550, callback=0x7ffff7c2bfe0 <gdk_threads_dispatch>, user_data=0x8cc9a0)
    at ../glib/gmain.c:6243
#7  0x00007ffff6d5828c in g_main_dispatch (context=0x48c420) at ../glib/gmain.c:3357
#8  g_main_context_dispatch_unlocked (context=0x48c420) at ../glib/gmain.c:4208
#9  0x00007ffff6db87b8 in g_main_context_iterate_unlocked.isra.0
    (context=0x48c420, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4273
#10 0x00007ffff6d5e377 in g_main_loop_run (loop=0x5b3cf0) at ../glib/gmain.c:4475
#11 0x00007ffff75efb35 in gtk_main () at ../gtk/gtkmain.c:1329
#12 0x0000000000407aab in main (argc=<optimized out>, argv=<optimized out>)
    at /usr/src/debug/pcmanfm-1.3.2^20241203git836c77c8-1.fc41.x86_64/pcmanfm/src/pcmanfm.c:284
(gdb) up

#1  0x00007ffff6e8898c in g_signal_handlers_block_matched (instance=0x100000001, mask=mask@entry=(G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 
    signal_id=signal_id@entry=0, detail=detail@entry=0, closure=closure@entry=0x0, func=func@entry=0x7ffff70ae230 <_on_cfg_file_changed>, 
    data=0x4bc930) at ../gobject/gsignal.c:2881
2881      g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
(gdb) 

#2  0x00007ffff70a8296 in fm_config_save (cfg=0x4bc930, name=0x8eeb50 "/home/tasaka1/.config/libfm/libfm.conf", name@entry=0x0)
    at /usr/src/debug/libfm-1.3.2^20241216gitfb651b87-1.fc41.x86_64/libfm/_BUILDDIR_gtk3/../src/base/fm-config.c:487
487                 g_signal_handlers_block_by_func(cfg->_cfg_mon, _on_cfg_file_changed, cfg);
(gdb) p *cfg

$3 = {parent = {g_type_instance = {g_class = Python Exception <class 'gdb.error'>: value has been optimized out
}, ref_count = 2, qdata = 0x0}, _cfg_name = 0x4bcbf0 "libfm/libfm.conf", 
  terminal = 0x4cafd0 "lxterminal", archiver = 0x4cafb0 "file-roller", big_icon_size = 64, small_icon_size = 24, pane_icon_size = 24, 
  thumbnail_size = 128, thumbnail_max = 0, auto_selection_delay = 600, drop_default_action = 0, single_click = 0, middle_click = 0, 
  use_trash = 0, confirm_del = 1, confirm_trash = 1, show_thumbnail = 1, thumbnail_local = 0, show_internal_volumes = 0, si_unit = 0, 
  advanced_mode = 0, force_startup_notify = 1, date_iso_8601 = 0, backup_as_hidden = 1, no_usb_trash = 0, no_child_non_expandable = 0, 
  show_full_names = 1, shadow_hidden = 0, places_home = 1, places_desktop = 1, places_applications = 1, places_trash = 1, places_root = 0, 
  places_computer = 0, places_network = 0, places_unmounted = 1, only_user_templates = 0, template_run_app = 0, template_type_once = 0, 
  defer_content_test = 0, quick_exec = 0, modules_blacklist = 0x0, modules_whitelist = 0x0, system_modules_blacklist = 0x0, 
  list_view_size_units = 0x0, format_cmd = 0x0, smart_desktop_autodrop = 1, saved_search = 0x4bef10 "401/*54*/", _reserved1 = 0x0, 
  _reserved2 = 0x0, _reserved3 = 0x0, _reserved4 = 0x0, _reserved5 = 0x0, _reserved6 = 0x0, _reserved7 = 0x0, _cfg_mon = 0x100000001}
(gdb) quit

A debugging session is active.

        Inferior 1 [process 719630] will be killed.

Quit anyway? (y or n) quit

EOF [assumed Y]
[tasaka1@localhost ~]$ 

exit

@mtasaka mtasaka changed the title ABI change in libfm.so.4 in recent commit? ABI change in libfm.so.4 in recent commit Dec 25, 2024
mtasaka added a commit to mtasaka/libfm that referenced this issue Dec 25, 2024
The following 2 commit:
lxde@b0545e0
lxde@2854a4c
broke libfm.so ABI because this changed the size of `struct _FmConfig` .

Restore libfm.so ABI compared to before.
Fixes lxde#104 .
@ib ib closed this as completed in #105 Dec 25, 2024
ib pushed a commit that referenced this issue Dec 25, 2024
The following 2 commit:
b0545e0
2854a4c
broke libfm.so ABI because this changed the size of `struct _FmConfig` .

Restore libfm.so ABI compared to before.
Fixes #104 .
@ib
Copy link
Member

ib commented Dec 26, 2024

I'm afraid I was too hasty with your pull request and need to revert it and bump the major version of libfm instead. Otherwise, configuring date_iso_8601 won't work in pcmanfm.

Right now, pcmanfm is still safe because all uses of the new configuration settings are safeguarded with FM_CHECK_VERSION. But date_iso_8601, once available in libfm, will be read by INIT_BOOL_SHOW(builder, FmConfig, date_iso_8601, NULL) with gboolean* val = (gboolean*)G_STRUCT_MEMBER_P(fm_config, off) and *val which won't work with the definition of gintptr date_iso_8601 if gboolean is smaller than gintptr on big-endian.

@mtasaka
Copy link
Contributor Author

mtasaka commented Dec 26, 2024

Or create INIT_INTPTR or so. Otherwise struct _FmConfig have to have every bool reserved, int reserved type.

@mtasaka
Copy link
Contributor Author

mtasaka commented Dec 26, 2024

Or create INIT_FMCONFIG_WITH_SIZE with specifying size to read?

@ib
Copy link
Member

ib commented Dec 26, 2024

INIT_FMCONFIG_WITH_SIZE

What you mean by that?

@ib
Copy link
Member

ib commented Dec 27, 2024

The ABI remains stable with anonymous unions:

    union
    {
        gboolean date_iso_8601;
        gpointer _reserved1;
    };
    union
    {
        gboolean middle_click;
        gpointer _reserved2;
    };

Unless I missed something, this is how I'm going to fix #105.

@mtasaka
Copy link
Contributor Author

mtasaka commented Dec 27, 2024

INIT_FMCONFIG_WITH_SIZE

What you mean by that?

Currently INIT_BOOL or INIT_BOOL_SHOW cast a pointer by *gboolean and read it.
Instead, create go to a pointer and specify the size to read, something like:

static void init_bool(GtkBuilder* b, const char* name, gsize off,
                      const char* changed_notify, gboolean force_show,
                      gsize read_size
)
{
    GtkToggleButton* btn = GTK_TOGGLE_BUTTON(gtk_builder_get_object(b, name));
    gpointer* val = (gpointer*)G_STRUCT_MEMBER_P(fm_config, off);

    long value;
    switch (read_size) {
    case 1:
          int8_t val8;
          memcpy(&val8, val, 1);
         value = val8;
         break;
  case 2:
         int16_t val16;
         memcpy(&val16, val, 2);
        value = val16;
      break;
    ......
 }
}

@mtasaka
Copy link
Contributor Author

mtasaka commented Dec 27, 2024

But maybe the above method is overdone.

@mtasaka
Copy link
Contributor Author

mtasaka commented Dec 29, 2024

The ABI remains stable with anonymous unions:

    union
    {
        gboolean date_iso_8601;
        gpointer _reserved1;
    };
    union
    {
        gboolean middle_click;
        gpointer _reserved2;
    };

Unless I missed something, this is how I'm going to fix #105.

This seems reasonable to me.

@ib
Copy link
Member

ib commented Dec 30, 2024

Applied.

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

Successfully merging a pull request may close this issue.

2 participants