Lablgtk 回调中的异常

Exceptions in Lablgtk callbacks

在Lablgtk中,每当回调出现异常时,都会自动捕获异常并在控制台打印错误信息,如:

(prog:12345) LablGTK-CRITICAL **: gtk_tree_model_foreach_func: 
    callback raised an exception

这没有给出堆栈跟踪,也没有关于异常的详细信息,并且因为它已被捕获,所以我无法自己检索此信息。

我可以为这种情况启用更详细的日志记录信息吗?或者防止异常被自动捕获?

我想最好的方法是手动捕获异常并自行处理。

let callback_print_exn f () =
 try f () with
 e -> my_exn_printer e

假设 val my_exn_printer : exn -> unit 是您的自定义异常打印机,您只需在代码中将 ~callback:f 替换为 ~callback:(callback_print_exn f) 即可打印回调异常。

当然,您也可以使用该方法将该异常发送给另一个 线程,注册一个 "callback id" 将与您的异常一起传递...

关于堆栈跟踪,我不确定您能否轻松检索到它。由于它是作为回调启动的,您可能想知道使用的信号以及可以存储在回调处理程序中的信号。

我遇到了另一个类似的问题,但这次更难找到在哪里放置调用以拦截异常。

幸运的是,这次 Glib C 代码出现了一条非常具体的错误消息:

GLib-CRITICAL **: Source ID ... was not found when attempting to remove it`

Stack Overflow + grep 让我找到了实际的 C 函数,但我找不到绑定到这段代码的几个 Lablgtk 函数中的哪个是罪魁祸首。

所以我下载了 Glib 源代码,在代码中添加了一个显式分段错误,编译它并使用 LD_LIBRARY_PATH 强制加载我修改过的 Glib 版本。

然后我 运行 带有 gdb 的 OCaml 二进制文件,我得到了我的堆栈跟踪,以及调用 Lablgtk 函数的精确行号。然后是一个快速的 3 行补丁。

可以通过 "strict mode" 防止异常被自动捕获来避免像这样的黑客攻击(仍然比试图找到拦截调用的地方更快)。我仍然相信 Lablgtk 用户应该可以使用这样的开关,并希望它最终可用。