How can I debug (and reach some breakpoint) with gdb
my buggy program (using GTK3) showing:
(monimelt:161): Gtk-WARNING **: Invalid text buffer iterator: either the iterator
is uninitialized, or the characters/pixbufs/widgets in the buffer have been
modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position
across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can
be referred to by character offset)
will invalidate all outstanding iterators
FWIW, the faulty program is some GPLv3 free software that I am developing (the same I asked this question for, where I give more context and explanation). It is on github: commit fc8e0b247d8dac4 (to reproduce my bug, build it, run it as ./monimelt
, type exactly p a y TAB in the window labelled monimelt command).
I have tried (all, in the same gdb
session):
calling quite early in my main
the g_log_set_default_handler function (as suggested here) with my own mom_g_log_handler
log handler and put a gdb breakpoint there
putting a gdb breakpoint on g_warning
(does not work, since that is probably a macro)
putting a gdb breakpoint on g_log_default_handler
also calling (in commit fb374425c69f2ddbd...)
g_log_set_handler ("Gtk", G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL
| G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING
| G_LOG_FLAG_RECURSION, mom_g_log_handler, NULL);
don't help...
But those breakpoints are not reached and the Gtk-WARNING **: Invalid text buffer iterator
message is still appearing.
Perhaps GTK is creating some pthreads, or perhaps it is registering its own log handler...
I finally found my bug (corrected in commit 82bb111402fdd97...). It was two calls to gtk_text_iter_get_offset
happening (incorrectly) after gtk_text_buffer_insert
.
But I am not satisfied with the way I found my bug. I had to fetch gtk+-3.21.6.tar.xz and I patched its gtk/gtktextiter.c
to code near line 180 the following:
extern void basile_gtk_text_iter_warning (void);
void basile_gtk_text_iter_warning (void)
{
usleep (1000);
}
/* This function ensures that the segment-dependent information is
truly computed lazily; often we don't need to do the full make_real
work. This ensures the btree and line are valid, but doesn't
update the segments. */
static GtkTextRealIter*
gtk_text_iter_make_surreal (const GtkTextIter *_iter)
{
GtkTextRealIter *iter = (GtkTextRealIter*)_iter;
if (iter->chars_changed_stamp !=
_gtk_text_btree_get_chars_changed_stamp (iter->tree))
{
g_warning ("Invalid text buffer iterator: either the iterator "
"is uninitialized, or the characters/pixbufs/widgets "
"in the buffer have been modified since the iterator "
"was created.\nYou must use marks, character numbers, "
"or line numbers to preserve a position across buffer "
"modifications.\nYou can apply tags and insert marks "
"without invalidating your iterators,\n"
"but any mutation that affects 'indexable' buffer contents "
"(contents that can be referred to by character offset)\n"
"will invalidate all outstanding iterators");
basile_gtk_text_iter_warning ();
return NULL;
}
The only change I made (w.r.t. pristine GTK3.21.26) is the definition and call to basile_gtk_text_iter_warning
and I put a breakpoint in it with gdb
.
Being able to do such dirty tricks is one of the reasons I am only using free software as much as possible, but having to make such tricks is really a shame, and there must be a better way.
So my question still stands, how could I have put such a breakpoint without recompiling GTK3? Or more generally how could I use GDB to catch such bugs (of course without recompiling GTK3).
BTW, using the simple --g-fatal-warnings
option is not really a solution, since I am also getting
(monimelt:21949): Gtk-WARNING **: Failed to get the GNOME session proxy:
The name org.gnome.SessionManager is not owned
which I consider being a spurious warning, because my running desktop is Mate, not Gnome. And my code is calling gtk_application_new
& g_application_run
and having a activate
signal on my mom_gtkapp
.
PS. On Linux/Debian/Sid/x86-64, GTK3 is 3.21.5, compiled with GCC6 and -g3 -Og
flags...
You can break on a g_warning (and any other log level message) by putting a breakpoint on g_logv.
I found this info here, fyi: http://wiki.inkscape.org/wiki/index.php/Debugging_Inkscape
Use G_DEBUG=fatal-warnings gdb ./your_app
to make gdb stop on warnings, too.
Reference: https://developer.gnome.org/glib/unstable/glib-Message-Logging.html#g-warning
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With