我如何使用 gdb
调试(并到达某个断点)我的错误程序(使用 GTK3)显示:
(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,有问题的程序是我正在开发的一些 GPLv3 免费软件(我在 this question 中询问过,我在其中提供了更多上下文和解释)。它在 github 上:commit fc8e0b247d8dac4 (要重现我的错误,构建它,以 ./monimelt
运行它,准确键入 p a y < kbd>TAB 在标有 monimelt 命令 的窗口中。
我已经试过了(全部都在同一个 gdb
session 中):
在我的
main
中很早就调用了 g_log_set_default_handler使用我自己的mom_g_log_handler
日志处理程序函数(如建议的 here )并在那里放置一个 gdb 断点在
g_warning
上放置一个 gdb 断点(不起作用,因为它可能是一个宏)在 g_log_default_handler 上设置 gdb 断点
同时调用(在提交 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);
不要帮忙...
但是那些断点没有到达,Gtk-WARNING **: Invalid text buffer iterator
消息仍然出现。
也许 GTK 正在创建一些 pthreads,或者它正在注册自己的日志处理程序...
我是怎么发现我的错误的....
我终于找到了我的错误(在提交 82bb111402fdd97... 中更正)。在 gtk_text_buffer_insert
之后(错误地)发生了两次对 gtk_text_iter_get_offset
的调用。
但是我对发现错误的方式不满意。我不得不取 gtk+-3.21.6.tar.xz我修补了它的 gtk/gtktextiter.c
以在第 180 行附近编写以下代码:
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;
}
我所做的唯一更改(w.r.t. pristine GTK3.21.26)是对 basile_gtk_text_iter_warning
的定义和调用,我使用 gdb
在其中放置了一个断点。
能够做这样卑鄙的把戏是我尽可能只使用免费软件的原因之一,但不得不做这样的把戏实在是一种耻辱,必须有更好的方法。支持>
所以我的问题仍然存在,我怎么能放置这样一个断点而不重新编译 GTK3?或者更一般地说,我如何使用 GDB 来捕获此类错误(当然无需重新编译 GTK3)。
顺便说一句,使用简单的 --g-fatal-warnings
选项并不是真正的解决方案,因为我也得到了
(monimelt:21949): Gtk-WARNING **: Failed to get the GNOME session proxy:
The name org.gnome.SessionManager is not owned
我认为这是虚假警告,因为我运行的桌面是 Mate,而不是 Gnome。我的代码正在调用 gtk_application_new
& g_application_run
并且在我的 mom_gtkapp
上有一个 activate
信号。
附言。在 Linux/Debian/Sid/x86-64 上,GTK3 是 3.21.5,使用 GCC6 和 -g3 -Og
标志编译...
最佳答案
您可以通过在 g_logv 上放置断点来中断 g_warning(以及任何其他日志级别消息)。
我在这里找到了这个信息,仅供引用:http://wiki.inkscape.org/wiki/index.php/Debugging_Inkscape
关于c - gdb调试(带断点): Gtk-WARNING **: Invalid text buffer iterator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39509231/