Lablgtk回调中的例外情况

时间:2015-03-12 17:38:09

标签: exception gtk ocaml lablgtk

在Lablgtk中,只要回调中出现异常,就会自动捕获异常并在控制台中打印错误消息,例如:

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

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

我可以针对此案例启用更详细的日志记录信息吗?或者防止异常被自动捕获?

2 个答案:

答案 0 :(得分:1)

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

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)即可打印回调例外。

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

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

答案 1 :(得分:1)

我有另一个类似的问题,但是这一次很难找到将拦截异常的调用放在哪里。

幸运的是,这次来自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行补丁。

像这样的黑客(通常比试图找到拦截呼叫的位置更快)可以通过严格的模式来避免"防止异常被自动捕获。我仍然相信Lablgtk用户可以使用这样的开关,并希望它最终可用。