The Invoice Editor has toolbar button to generate printable invoice report. The new feature to reuse existing invoice report seems to crash on Windows. To reproduce (on Windows): - Open Invoice Editor - Create dummy invoice - Click "Print Invoice" button - Close the invoice report just generated - Click "Print Invoice" again Result: crash
The same logic exists for the budget editor -> budget report toolbar button.
Hint: d6082e1a60da5179a9309ccccb96f5c26014d895 void gnc_invoice_window_printCB (GtkWindow* parent, gpointer data) { InvoiceWindow *iw = data; if (iw->reportPage && GNC_IS_PLUGIN_PAGE (iw->reportPage)) gnc_plugin_page_report_reload (GNC_PLUGIN_PAGE_REPORT (iw->reportPage)); else iw->reportPage = gnc_invoice_window_print_invoice (parent, iw_get_invoice (iw)); gnc_main_window_open_page (GNC_MAIN_WINDOW (iw->dialog), iw->reportPage); } The only conclusion I can draw is that GNC_IS_PLUGIN_PAGE (iw->reportPage) will return TRUE on Windows and FALSE on Linux, if the iw->reportPage has been closed. But not sure how to fix this.
Do you have a stack trace showing that it's actually getting to gnc_plugin_page_reload? I think it more likely that the crash is in g_type_check_instance_type(), the function that underlies GNC_IS_PLUGIN_PAGE, trying to access freed memory. The else clause in your commit saves a pointer to allocated memory without reffing it and without any way of detecting that it's been freed. Use either g_object_ref to keep the report page from being freed or g_object_weak_ref to automatically NULL iw->reportPage when it is destroyed. Note that in the first case you need to call g_object_unref(iw->reportPage) in gnc_invoice_window_destroy_cb so that reportPage isn't leaked. See https://developer.gnome.org/gobject/stable/gobject-memory.html
Created attachment 374072 [details] like this? (doesn't work) * 18:05:40 ERROR <gnc.html> gnc_html_reload: assertion 'self != NULL' failed * 18:05:40 ERROR <gnc.report.core> gnc_run_report_with_error_handling: assertion '!scm_is_false (report)' failed munmap_chunk(): invalid pointer ./run-maint.sh: line 10: 57341 Aborted (core dumped) ./gnucash --extra --logto stdout
I think you're right i valgrind output: ==60781== Invalid read of size 8 ==60781== at 0x4F29882: gnc_invoice_window_printCB (dialog-invoice.c:837) ==60781== by 0x4F7D841: gnc_plugin_page_invoice_cmd_print (gnc-plugin-page-invoice.c:1042) ==60781== by 0x5B998F9: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BAC4B2: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BB2C60: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BB2DC2: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x528B814: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2404.19) ==60781== by 0x552F92C: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2404.19) ==60781== by 0x5B99B55: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BB2BDE: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BB2DC2: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x53149DF: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2404.19) ==60781== Address 0x151ae590 is 224 bytes inside a block of size 280 free'd ==60781== at 0x483D948: free (in /gnu/store/7dmfnzh4yvfcbsdb1ik456zp27r1acka-valgrind-3.16.1/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==60781== by 0x5BB99A3: g_type_free_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x511FA60: gnc_main_window_close_page (gnc-main-window.c:3330) ==60781== by 0x5B99B55: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BB2BDE: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BB2DC2: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x53149DF: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2404.19) ==60781== by 0x5B99B55: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BB2BDE: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BB2DC2: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5312C13: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2404.19) ==60781== by 0x55DACFE: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2404.19) ==60781== Block was alloc'd at ==60781== at 0x483C79B: malloc (in /gnu/store/7dmfnzh4yvfcbsdb1ik456zp27r1acka-valgrind-3.16.1/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==60781== by 0x4C4C698: g_malloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6600.1) ==60781== by 0x4C64CF1: g_slice_alloc (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6600.1) ==60781== by 0x4C6536D: g_slice_alloc0 (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6600.1) ==60781== by 0x5BB964B: g_type_create_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5B9F077: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x4FAB2E2: gnc_plugin_page_report_constructor (gnc-plugin-page-report.c:1170) ==60781== by 0x5B9F1E5: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BA102B: g_object_new_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x5BA138C: g_object_new (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.6600.1) ==60781== by 0x4FABB01: gnc_plugin_page_report_new (gnc-plugin-page-report.c:1322) ==60781== by 0x4F297F1: gnc_invoice_window_print_invoice (dialog-invoice.c:819)
(In reply to Christopher Lam from comment #4) > Created attachment 374072 [details] > like this? > > (doesn't work) > > * 18:05:40 ERROR <gnc.html> gnc_html_reload: assertion 'self != NULL' failed > * 18:05:40 ERROR <gnc.report.core> gnc_run_report_with_error_handling: > assertion '!scm_is_false (report)' failed > munmap_chunk(): invalid pointer > ./run-maint.sh: line 10: 57341 Aborted (core dumped) > ./gnucash --extra --logto stdout Yes, like that, but you also need to make sure that the report page pays attention to the reference count. A lot of GnuCash's UI objects don't.
(In reply to John Ralls from comment #6) > Yes, like that, but you also need to make sure that the report page pays > attention to the reference count. A lot of GnuCash's UI objects don't. This is beyond my skills. If this is not fixed soon, then I'd disable the feature to save reportPage into the budget/invoice. It's never nice to have a reliable hard crash in Windows.
It's not a feature if it crashes, so by all means revert d6082e1a if you don't want to put the effort into making it correct. It's not beyond your skills. It may be beyond your understanding of the code and your motivation to gain that understanding.
Just a thought, why don't you set up a callback for the page removed signal so that you can make iw->reportPage = NULL when it is removed; Have no tested and not looked at code so may be way of on this.
Thinking about that, remove may not work as you will probably get one when you move the page to another window so destroy/close maybe better if there is one.
https://github.com/Gnucash/gnucash/pull/1007 candidate fix
(In reply to Christopher Lam from comment #11) > https://github.com/Gnucash/gnucash/pull/1007 candidate fix Not yet.
confirmed fixed in windows \o/