GnuCash
Contact   Instructions
Bug 798147 - Notes entry crashes program
Summary: Notes entry crashes program
Status: RESOLVED FIXED
Alias: None
Product: GnuCash
Classification: Unclassified
Component: User Interface General (show other bugs)
Version: 4.4
Hardware: PC Mac OS
: Normal normal
Target Milestone: ---
Assignee: ui
QA Contact: ui
URL:
Whiteboard:
Keywords:
: 798152 798171 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-03-15 20:55 EDT by Kevin Hale Boyes
Modified: 2021-04-22 12:48 EDT (History)
8 users (show)

See Also:


Attachments
GncCellRenderTextView patch (5.26 KB, patch)
2021-03-19 09:08 EDT, Bob
no flags Details
GncCellRenderTextView patch (7.47 KB, patch)
2021-03-21 05:34 EDT, Bob
no flags Details

Description Kevin Hale Boyes 2021-03-15 20:55:10 EDT
The program crashes when I copy a note from one account to another account.
Sometimes the program also crashes when I tab off a newly entered note.

I've reproduced it as follows:
1) Create a new file using the "Investment Accounts" category.
2) Save as XML (I used the name gnc-bug-reporting.gnucash)
3) Click down-arrow to add the Notes column.
4) On the Assets account, click on the Notes cell and type anything.
5) Tab away from the field.
6) Click back onto the field (making it editable) and copy the text (Cmd-C).
7) Program crashes, if not see step 8.
8) Click Notes cell on another account and paste (Cmd-V).
9) Program crashes.

In case it matters, I'm using gnucash installed with homebrew.

$ brew list --cask gnucash
==> App
/Applications/Gnucash.app (11,283 files, 416.4MB)

$ brew info gnucash
gnucash: 4.4,1
https://www.gnucash.org/
/usr/local/Caskroom/gnucash/4.4,1 (5 files, 427.8KB)
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/gnucash.rb
==> Name
GnuCash
==> Description
Double-entry accounting program
==> Artifacts
Gnucash.app (App)
==> Analytics
install: 138 (30 days), 446 (90 days), 1,931 (365 days)
Comment 1 Bob 2021-03-16 06:06:01 EDT
This is most likely down to when I changed the notes field from a GtkCellRendererText to the GncCellRendererTextView I wrote. I thought I tested copying and pasting so will have a look.
Comment 2 John Ralls 2021-03-16 13:06:58 EDT
OK. I've done a little debugging that I think you'll find helpful.

I got an extra crash as well because I tried to use <ctrl>Enter to save the contents of the first note. It's a use-after-free of cv:
  * frame #0: 0x0000000100f89edc libgnc-gnome-utils.dylib`gtk_cell_editable_key_press_event(text_view=0x000000010c8dabe0, key_event=0x000000010d1f75b0, cv=0x0000000117a152d0) at gnc-cell-view.c:160:13
    frame #1: 0x00000001015df721 libgtk-3.0.dylib`_gtk_marshal_BOOLEAN__BOXED(closure=0x000000014bc27a60, return_value=0x00007ffeefbfb388, n_param_values=2, param_values=0x00007ffeefbfb430, invocation_hint=0x00007ffeefbfb3d0, marshal_data=0x0000000000000000) at gtkmarshalers.c:83:14

I don't get a crash when I copy (step 6) but I do get a warning:
  sys:1: Warning: invalid cast from 'GtkTextBuffer' to 'GtkWidget'

On paste it's 
  * frame #0: 0x00000001015aef5f libgtk-3.0.dylib`gtk_clipboard_wait_for_contents(clipboard=0x0000000000000000, target=0x0000000000000050) at gtkclipboard-quartz.c:823:18
    frame #1: 0x00000001015aeef5 libgtk-3.0.dylib`gtk_clipboard_request_contents(clipboard=0x0000000000000000, target=0x0000000000000050, callback=(libgtk-3.0.dylib`clipboard_clipboard_buffer_received at gtktextbuffer.c:3632), user_data=0x00000001254f8a50) at gtkclipboard-quartz.c:692:10
    frame #2: 0x00000001014a742f libgtk-3.0.dylib`gtk_text_buffer_paste_clipboard(buffer=0x0000000115229770, clipboard=0x0000000000000000, override_location=0x0000000000000000, default_editable=0) at gtktextbuffer.c:3872:3
    frame #3: 0x0000000100fb71b6 libgnc-gnome-utils.dylib`gnc_main_window_cmd_edit_paste(action=0x000000011509d5b0, window=0x000000011509a310) at gnc-main-window.c:4421:9

because gtk_clipboard_wait_for_contents dereferences the clipboard* without checking it and as you can see it's nullptr. That's originating in gnc_main_window_cmd_edit_paste where it's retrieved from gtk_widget_get_clipboard.

Obvs gtk_clipboard_wait_for_contents should nullptr-check clipboard before trying to dereference it, otoh gnc_main_window_cmd_edit_paste could do the same.

Tried on Fedora 33, didn't crash but it didn't paste anything either.
Comment 3 Kevin Hale Boyes 2021-03-16 13:36:18 EDT
Thanks guys for looking into this.
I wanted to keep the bug report focused but now that you've found something I want to point out that I've had similar crashes when editing/copy/pasting the Action/Num field in an investment split.
Comment 4 John Ralls 2021-03-18 21:00:26 EDT
A bit more on the crash on save mentioned in comment 2:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x0000000100f6e69c libgnc-gnome-utils.dylib`gtk_cell_editable_key_press_event(text_view=0x000000010c187620, key_event=0x000000010d31fb60, cv=0x000000010c1fe5e0) at gnc-cell-view.c:160:13
    frame #1: 0x00000001015c74a1 libgtk-3.0.dylib`_gtk_marshal_BOOLEAN__BOXED(closure=0x0000000122aa26e0, return_value=0x00007ffeefbfbd60, n_param_values=2, param_values=0x00007ffeefbfbe30, invocation_hint=0x00007ffeefbfbdb8, marshal_data=0x0000000000000000) at gtkmarshalers.c:83:14
    frame #2: 0x000000010228ebbd libgobject-2.0.0.dylib`g_closure_invoke(closure=0x0000000122aa26e0, return_value=0x00007ffeefbfbd60, n_param_values=<unavailable>, param_values=0x00007ffeefbfbe30, invocation_hint=0x00007ffeefbfbdb8) at gclosure.c:810:7 [opt]
    frame #3: 0x00000001022a5130 libgobject-2.0.0.dylib`signal_emit_unlocked_R(node=<unavailable>, detail=0, instance=<unavailable>, emission_return=0x00007ffeefbfbea0, instance_and_params=0x00007ffeefbfbe30) at gsignal.c:3738:8 [opt]
    frame #4: 0x00000001022a617c libgobject-2.0.0.dylib`g_signal_emit_valist(instance=<unavailable>, signal_id=<unavailable>, detail=<unavailable>, var_args=0x00007ffeefbfc050) at gsignal.c:3504:7 [opt]
    frame #5: 0x00000001022a6652 libgobject-2.0.0.dylib`g_signal_emit(instance=<unavailable>, signal_id=<unavailable>, detail=<unavailable>) at gsignal.c:3550:3 [opt]
    frame #6: 0x000000010155d2ba libgtk-3.0.dylib`gtk_widget_event_internal(widget=0x000000010c187620, event=0x000000010d31fb60) at gtkwidget.c:7808:4
    frame #7: 0x000000010155cf94 libgtk-3.0.dylib`gtk_widget_event(widget=0x000000010c187620, event=0x000000010d31fb60) at gtkwidget.c:7378:10
    frame #8: 0x00000001015816b5 libgtk-3.0.dylib`gtk_window_propagate_key_event(window=0x000000010f81e2e0, event=0x000000010d31fb60) at gtkwindow.c:8223:21
    frame #9: 0x000000010158b940 libgtk-3.0.dylib`gtk_window_key_press_event(widget=0x000000010f81e2e0, event=0x000000010d31fb60) at gtkwindow.c:8256:15
    frame #10: 0x00000001015c74a1 libgtk-3.0.dylib`_gtk_marshal_BOOLEAN__BOXED(closure=0x000000010bb2f710, return_value=0x00007ffeefbfc2d0, n_param_values=2, param_values=0x00007ffeefbfc3a0, invocation_hint=0x00007ffeefbfc328, marshal_data=0x000000010158b8f0) at gtkmarshalers.c:83:14
    frame #11: 0x000000010228ebbd libgobject-2.0.0.dylib`g_closure_invoke(closure=0x000000010bb2f710, return_value=0x00007ffeefbfc2d0, n_param_values=<unavailable>, param_values=0x00007ffeefbfc3a0, invocation_hint=0x00007ffeefbfc328) at gclosure.c:810:7 [opt]
    frame #12: 0x00000001022a525d libgobject-2.0.0.dylib`signal_emit_unlocked_R(node=<unavailable>, detail=0, instance=<unavailable>, emission_return=0x00007ffeefbfc410, instance_and_params=0x00007ffeefbfc3a0) at gsignal.c:3776:7 [opt]
    frame #13: 0x00000001022a617c libgobject-2.0.0.dylib`g_signal_emit_valist(instance=<unavailable>, signal_id=<unavailable>, detail=<unavailable>, var_args=0x00007ffeefbfc5c0) at gsignal.c:3504:7 [opt]
    frame #14: 0x00000001022a6652 libgobject-2.0.0.dylib`g_signal_emit(instance=<unavailable>, signal_id=<unavailable>, detail=<unavailable>) at gsignal.c:3550:3 [opt]
    frame #15: 0x000000010155d2ba libgtk-3.0.dylib`gtk_widget_event_internal(widget=0x000000010f81e2e0, event=0x000000010d31fb60) at gtkwidget.c:7808:4
    frame #16: 0x000000010155cf94 libgtk-3.0.dylib`gtk_widget_event(widget=0x000000010f81e2e0, event=0x000000010d31fb60) at gtkwidget.c:7378:10
    frame #17: 0x0000000101367a53 libgtk-3.0.dylib`propagate_event(widget=0x000000010f81e2e0, event=0x000000010d31fb60, captured=0, topmost=0x0000000000000000) at gtkmain.c:2680:29
    frame #18: 0x0000000101366fa0 libgtk-3.0.dylib`gtk_propagate_event(widget=0x000000010f81e2e0, event=0x000000010d31fb60) at gtkmain.c:2724:3
    frame #19: 0x00000001013667c7 libgtk-3.0.dylib`gtk_main_do_event(event=0x000000010d31fb60) at gtkmain.c:1920:9
    frame #20: 0x0000000101be8165 libgdk-3.0.dylib`_gdk_event_emit(event=0x000000010d31fb60) at gdkevents.c:73:5
    frame #21: 0x0000000101c2c33f libgdk-3.0.dylib`gdk_event_dispatch(source=0x000000010bc0fe10, callback=0x0000000000000000, user_data=0x0000000000000000) at gdkeventloop-quartz.c:715:7
    frame #22: 0x0000000100a63b1c libglib-2.0.0.dylib`g_main_context_dispatch at gmain.c:3325:27 [opt]
    frame #23: 0x0000000100a639e7 libglib-2.0.0.dylib`g_main_context_dispatch(context=0x000000010bc0fe70) at gmain.c:4016 [opt]
    frame #24: 0x0000000100a63e8d libglib-2.0.0.dylib`g_main_context_iterate(context=<unavailable>, block=<unavailable>, dispatch=1, self=<unavailable>) at gmain.c:4092:5 [opt]
    frame #25: 0x0000000100a641ca libglib-2.0.0.dylib`g_main_loop_run(loop=0x00000001155ea0a0) at gmain.c:4290:5 [opt]
    frame #26: 0x0000000101365edc libgtk-3.0.dylib`gtk_main at gtkmain.c:1328:7

The line that's crashing is 

-> 160 	        if (GTK_IS_CELL_EDITABLE(cv))
   161 	            gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE(cv));

and the reason it's crashing is because cv has already been deallocated and overwritten.
Comment 5 John Ralls 2021-03-18 21:01:40 EDT
*** Bug 798152 has been marked as a duplicate of this bug. ***
Comment 6 Bob 2021-03-19 07:57:15 EDT
I pushed a fix for the Ctrl+Cut/Copy and Paste from the main window. I am not sure this ever worked for a GtkTextView widget as it was trying to obtain the clipboard from the GtkTextBuffer which is not a widget so instead I changed it to get it from the GtkTextView instead.

The only other possible place I could find to test was for the notes field on an Invoice page but that's not wired up to use it at all, will sort that out as a separate commit.

John,
I am looking at 'shift+enter', if I comment out line 160 and add some gprint statements I see that the gnc_cell_view_finalize is being called before that line is called.
Need to have a think...
Comment 7 Bob 2021-03-19 09:08:04 EDT
Created attachment 374035 [details]
GncCellRenderTextView patch

John,

I think I have fixed the 'shift+enter' error, for me the error was being masked by the GTK_IS_CELL_EDITABLE(cv) on line 160 as you pointed out. I have now moved the gtk_cell_editable_remove_widget to the gcrtv_editing_done callback so it is before the emitting of the 'edited' signal.

Part of this patch was a change I was going to make that allows for the context sensitive menu, accessed by right mouse when in editing mode which also has the cut/copy/paste/delete/Select All/Insert Emoji menu items just like the description field.

If you could give it a try and confirm it fixes the issue most appreciated.

Also is there a compiler switch I should add to allow me to see these issues?
Comment 8 John Ralls 2021-03-19 12:16:31 EDT
I'll give it a try later today. 

> Also is there a compiler switch I should add to allow me to see these issues?

Since I build everything from source for macOS I can configure GLib with G_ENABLE_DEBUG; that gets gtype  to scribble freed memory with 0xaa. That's why use after free errors are usually detected on macOS before other platforms: It guarantees a hard crash instead of weirdness on use-after-free.

Unless you also want to build GLib from source your best bet on Linux would be to build GnuCash with -fsanitize=address, but that's likely to flag a lot of other problems and because GLib is built without it might not work. If it doesn't I think valgrind is the only other option.
Comment 9 Bob 2021-03-19 15:08:18 EDT
Thanks, My Linux VM's are all based in Gentoo so I have rebuilt Glib several times so can add the debug flag for that, I think I build Gtk+ like that already.
Comment 10 John Ralls 2021-03-19 15:11:29 EDT
Bob,

Well...
Instead of crashing when one uses shift-return to commit the edit it crashes when using tab:

 * frame #0: 0x0000000100f89cac libgnc-gnome-utils.dylib`gcv_remove_tooltip(cv=0x000000010c2a95f0) at gnc-cell-view.c:206:9
    frame #1: 0x0000000100a3f507 libglib-2.0.0.dylib`g_timeout_dispatch(source=0x000000010bef4830, callback=(libgnc-gnome-utils.dylib`gcv_remove_tooltip at gnc-cell-view.c:205), user_data=0x000000010c2a95f0) at gmain.c:4849:11
    frame #2: 0x0000000100a4481b libglib-2.0.0.dylib`g_main_dispatch(context=0x000000010bc08790) at gmain.c:3325:27

It doesn't crash on paste anymore so that's something.
Comment 11 John Ralls 2021-03-19 15:27:57 EDT
I don't know what is the point of gcv_remove_tooltip, but if it's really necessary either g_object_ref(cv) when connecting to the signal and g_object_unref(cv) at the end of gcv_remove_tooltip or better yet add a the idle's id to cv and null it in gcv_remove_tooltip. Test that id in gnc_cell_view_finalize (or add gnc_cell_view_dispose) and kill the idle if it's nonzero.
Comment 12 Bob 2021-03-21 05:34:25 EDT
Created attachment 374039 [details]
GncCellRenderTextView patch

John,

Thank you for testing, I updated my Linux VM yesterday and included the change for Glib and as a result of that I can see both crashes so that should be good for the future.

The reason for the idle_timeout was that I did not want the tool tip to keep popping up so decided to add the timeout so when it first pops up and maybe it did not register you have an opportunity to display it again.

I have made amendments to my patch and am unable to make it fail after being compiled with my updated setup.
Comment 13 John Ralls 2021-03-22 12:44:57 EDT
Comment on attachment 374039 [details]
GncCellRenderTextView patch

You might as well remove gnc_cell_view_finalize while you're at it, all it does is chain up.

Otherwise looks good.
Comment 14 Bob 2021-03-23 06:37:07 EDT
OK have pushed the changes to maint and will be in he next release 4.5

Kevin,
Please test in new version which should be this weekend and confirm all is OK so bug can be closed. Regarding the other crashes you mentioned, if possible identify a sequence of events and file a new bug and if possible attach the crash report that I believe mac's produce.
Comment 15 Kevin Hale Boyes 2021-03-31 11:57:03 EDT
I have updated Gnucash to 4.5 and have tested again.
The bug appears to be fixed.  Thanks.

For the other crashes, I've forgotten how they happened so I'll file a new bug report if I come across them again.
Comment 16 John Ralls 2021-04-22 12:48:17 EDT
*** Bug 798171 has been marked as a duplicate of this bug. ***

Note You need to log in before you can comment on or make changes to this bug.