GNOME Bugzilla – Bug 689942
Random crash
Last modified: 2012-12-10 17:36:58 UTC
Created attachment 231091 [details] Detailed information of the crash. Facts ----- Every now and then (once per 1-3 h) gnucash seems to crash. This can happen after a save, or updating a transaction or even leaving the computer alone for a while - when I come back it's crashed. The crash is a null pointer exception inside libcairo.cairo_image_get_surface_data where a comparison check is done against 0. 68DE04E1 |. 8138 20AEE968 CMP DWORD PTR DS:[EAX],libcairo.68E9AE20 libcairo.68E9AE20 is just 00 00 00 00 This bug can be fixed by first checking EAX for 0 and then checking the pointer pointed to by EAX if it's 0. See attached "crash.txt" for more details. Speculation ----------- Ie a possible fix in C would look like old code if (*p == NULL) { } new code if (p == NULL) || (*p == NULL) { } From my side this looks like a bug in libcairo itself more than any problem with gnucash.
Then why don't you file the bug against Cairo? Their bugtracker is at https://bugs.freedesktop.org/enter_bug.cgi?product=cairo The actual patch is: diff --git a/src/cairo-image-surface-inline.h b/src/cairo-image-surface-inline.h index 743d5fd..63e0c50 100644 --- a/src/cairo-image-surface-inline.h +++ b/src/cairo-image-surface-inline.h @@ -74,7 +74,7 @@ static inline cairo_bool_t _cairo_surface_is_image (const cairo_surface_t *surface) { /* _cairo_surface_nil sets a NULL backend so be safe */ - return surface->backend && surface->backend->type == CAIRO_SURFACE_TYPE_IMA + return surface && surface->backend && surface->backend->type == CAIRO_SURFA } /** However, that's just a symptom: Somehow cairo_image_surface_get_data() is being called with a NULL surface*, and that may well be Gnucash's fault. Can you provide a backtrace?
Created attachment 231109 [details] Location of message loop.
Thanks for the quick find and fix. I already did a cross-post to the cairo bugtracker: https://bugs.freedesktop.org/show_bug.cgi?id=58061 but they already closed it with "Not Our Bug". Cairo never sets a pointer to NULL. Re backtrace, unfortunately Ollydbg was unable to produce more than what is in the attached file. Call stack of main thread Address Stack Procedure / arguments Called from Frame 0028E4EC 6C38D268 <JMP.&libcairo-2.cairo_image_surface_get_data> libgdk-w.6C38D263 0028E4E8 But with a manual analysis of the Stack Dump, it looks like it is coming from the main message loop (g_main_loop_run). I'm not familiar with gnucash code too much but there should be a hook function for the messages somewhere in gnucash - that would be a good start to look at. My guesses: between gnucash.00403BC2 (gnucash main) and gnucash.00403D48 (call to hook_ui_shutdown), possibly hook_ui_post_startup --> see second attachment
g_main_loop is the main event loop. Pretty much everything starts there once the GUI is initialized. Fortunately, it turns out that this is called exactly once in Gtk+-2.24, in gdkpixmap-win32.c. The error handling there looks like it's obsolete, because it checks for cairo_win32_surface_create_from_dib() to return NULL, which it hasn't for a long time. It should also check for the return from cairo_win32_surface_get_image() to protect against passing the NULL back to cairo_image_surface_get_data(). Reassigning to Gtk.
Fixed with corrected error handling: e8535149 pushed to gtk-2-24 branch.