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

Fix crash closing directory from the openfiles sidebar #3535

Merged
merged 1 commit into from
Oct 8, 2023

Conversation

b4n
Copy link
Member

@b4n b4n commented Jul 30, 2023

When the openfiles sidebar shows documents as a tree, closing a document can lead to sever re-layout of the view (e.g. collapsing directory nodes together). This makes walking the tree and closing documents at the same time highly tricky, as nodes might be shifting as we go.

This lead to invalid memory access, and unexpected results, when closing some tree structures.

One example of Valgrind showing how bad things are:

==917061== Invalid read of size 8
==917061==    at 0x5B31345: g_node_nth_child (gnode.c:1052)
==917061==    by 0x50A7361: gtk_tree_store_iter_nth_child (gtktreestore.c:793)
==917061==    by 0x491DB76: on_openfiles_document_action_apply (sidebar.c:1330)
==917061==    by 0x491DC0C: on_openfiles_document_action (sidebar.c:1347)
==917061==    by 0x5A833AF: g_closure_invoke (gclosure.c:832)
==917061==    by 0x5A96075: signal_emit_unlocked_R.isra.0 (gsignal.c:3796)
==917061==    by 0x5A9CBF4: g_signal_emit_valist (gsignal.c:3549)
==917061==    by 0x5A9CDBE: g_signal_emit (gsignal.c:3606)
==917061==    by 0x50D7833: gtk_widget_activate (gtkwidget.c:7845)
==917061==    by 0x4F8A935: gtk_menu_shell_activate_item (gtkmenushell.c:1375)
==917061==    by 0x4F8AC70: gtk_menu_shell_button_release (gtkmenushell.c:791)
==917061==    by 0x4DFBCB3: _gtk_marshal_BOOLEAN__BOXEDv (gtkmarshalers.c:130)
==917061==  Address 0x9bcdc20 is 32 bytes inside a block of size 40 free'd
==917061==    at 0x484317B: free (vg_replace_malloc.c:872)
==917061==    by 0x5B3068B: g_nodes_free (gnode.c:123)
==917061==    by 0x5B3068B: g_node_destroy (gnode.c:143)
==917061==    by 0x50AA8F2: gtk_tree_store_remove (gtktreestore.c:1229)
==917061==    by 0x491F851: sidebar_openfiles_remove_iter (sidebar.c:959)
==917061==    by 0x491F8AE: openfiles_remove (sidebar.c:972)
==917061==    by 0x491FA6C: sidebar_remove_document (sidebar.c:1027)
==917061==    by 0x48D0B5B: remove_page (document.c:733)
==917061==    by 0x48D29C0: document_remove_page (document.c:787)
==917061==    by 0x48D29FC: document_close (document.c:695)
==917061==    by 0x491DAED: document_action (sidebar.c:1299)
==917061==    by 0x491DB47: on_openfiles_document_action_apply (sidebar.c:1322)
==917061==    by 0x491DB9E: on_openfiles_document_action_apply (sidebar.c:1332)
==917061==  Block was alloc'd at
==917061==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
==917061==    by 0x5B2C678: g_malloc (gmem.c:130)
==917061==    by 0x5B45011: g_slice_alloc (gslice.c:1074)
==917061==    by 0x5B305BD: g_node_new (gnode.c:110)
==917061==    by 0x50AAF0B: gtk_tree_store_insert_before (gtktreestore.c:1375)
==917061==    by 0x491E725: tree_add_new_dir (sidebar.c:654)
==917061==    by 0x491E89A: get_parent_for_file (sidebar.c:840)
==917061==    by 0x491E995: sidebar_openfiles_add_iter (sidebar.c:869)
==917061==    by 0x491F5C7: sidebar_openfiles_add (sidebar.c:901)
==917061==    by 0x48D0CE4: document_create (document.c:662)
==917061==    by 0x48D3840: document_open_file_full (document.c:1349)
==917061==    by 0x48D3C81: document_open_file (document.c:914)

Fix this by decoupling tree walking from closing documents. We now do two passes: first we collect documents to work on walking the tree as before, and only then we perform the action on each node of the list.

Fixes #3527.

@b4n b4n added bug crash Geany crashes because of this issue labels Jul 30, 2023
@b4n b4n added this to the 1.39/2.0 milestone Jul 30, 2023
@b4n b4n requested review from kugel- and removed request for kugel- July 30, 2023 21:52
src/sidebar.c Outdated Show resolved Hide resolved
When the openfiles sidebar shows documents as a tree, closing a
document can lead to sever re-layout of the view (e.g. collapsing
directory nodes together).  This makes walking the tree and closing
documents at the same time highly tricky, as nodes might be shifting as
we go.

This lead to invalid memory access, and unexpected results, when
closing some tree structures.

One example of Valgrind showing how bad things are:

    ==917061== Invalid read of size 8
    ==917061==    at 0x5B31345: g_node_nth_child (gnode.c:1052)
    ==917061==    by 0x50A7361: gtk_tree_store_iter_nth_child (gtktreestore.c:793)
    ==917061==    by 0x491DB76: on_openfiles_document_action_apply (sidebar.c:1330)
    ==917061==    by 0x491DC0C: on_openfiles_document_action (sidebar.c:1347)
    ==917061==    by 0x5A833AF: g_closure_invoke (gclosure.c:832)
    ==917061==    by 0x5A96075: signal_emit_unlocked_R.isra.0 (gsignal.c:3796)
    ==917061==    by 0x5A9CBF4: g_signal_emit_valist (gsignal.c:3549)
    ==917061==    by 0x5A9CDBE: g_signal_emit (gsignal.c:3606)
    ==917061==    by 0x50D7833: gtk_widget_activate (gtkwidget.c:7845)
    ==917061==    by 0x4F8A935: gtk_menu_shell_activate_item (gtkmenushell.c:1375)
    ==917061==    by 0x4F8AC70: gtk_menu_shell_button_release (gtkmenushell.c:791)
    ==917061==    by 0x4DFBCB3: _gtk_marshal_BOOLEAN__BOXEDv (gtkmarshalers.c:130)
    ==917061==  Address 0x9bcdc20 is 32 bytes inside a block of size 40 free'd
    ==917061==    at 0x484317B: free (vg_replace_malloc.c:872)
    ==917061==    by 0x5B3068B: g_nodes_free (gnode.c:123)
    ==917061==    by 0x5B3068B: g_node_destroy (gnode.c:143)
    ==917061==    by 0x50AA8F2: gtk_tree_store_remove (gtktreestore.c:1229)
    ==917061==    by 0x491F851: sidebar_openfiles_remove_iter (sidebar.c:959)
    ==917061==    by 0x491F8AE: openfiles_remove (sidebar.c:972)
    ==917061==    by 0x491FA6C: sidebar_remove_document (sidebar.c:1027)
    ==917061==    by 0x48D0B5B: remove_page (document.c:733)
    ==917061==    by 0x48D29C0: document_remove_page (document.c:787)
    ==917061==    by 0x48D29FC: document_close (document.c:695)
    ==917061==    by 0x491DAED: document_action (sidebar.c:1299)
    ==917061==    by 0x491DB47: on_openfiles_document_action_apply (sidebar.c:1322)
    ==917061==    by 0x491DB9E: on_openfiles_document_action_apply (sidebar.c:1332)
    ==917061==  Block was alloc'd at
    ==917061==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
    ==917061==    by 0x5B2C678: g_malloc (gmem.c:130)
    ==917061==    by 0x5B45011: g_slice_alloc (gslice.c:1074)
    ==917061==    by 0x5B305BD: g_node_new (gnode.c:110)
    ==917061==    by 0x50AAF0B: gtk_tree_store_insert_before (gtktreestore.c:1375)
    ==917061==    by 0x491E725: tree_add_new_dir (sidebar.c:654)
    ==917061==    by 0x491E89A: get_parent_for_file (sidebar.c:840)
    ==917061==    by 0x491E995: sidebar_openfiles_add_iter (sidebar.c:869)
    ==917061==    by 0x491F5C7: sidebar_openfiles_add (sidebar.c:901)
    ==917061==    by 0x48D0CE4: document_create (document.c:662)
    ==917061==    by 0x48D3840: document_open_file_full (document.c:1349)
    ==917061==    by 0x48D3C81: document_open_file (document.c:914)

Fix this by decoupling tree walking from closing documents.  We now do
two passes: first we collect documents to work on walking the tree as
before, and only then we perform the action on each node of the list.

Fixes geany#3527.
@elextr
Copy link
Member

elextr commented Aug 5, 2023

Not tested but seems ok in principle.

@b4n b4n requested a review from kugel- October 5, 2023 20:15
@b4n
Copy link
Member Author

b4n commented Oct 5, 2023

Anybody up for giving this a test spin? I'm running that daily, but a second opinion is always welcome :)

@techee
Copy link
Member

techee commented Oct 6, 2023

So, first, cool, one can close all files from one directory, I didn't know about that!

I just had a look at the patch which seems to do the right thing and also tested it a bit. I wasn't able to reproduce the crash, just the incorrect closing of directories with the original version and the patch fixes it for me. So from my point of view the patch can be merged.

@b4n b4n merged commit f9c14c3 into geany:master Oct 8, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug crash Geany crashes because of this issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Crash closing directory from the openfiles sidebar
3 participants