在Lablgtk中,只要回调中出现异常,就会自动捕获异常并在控制台中打印错误消息,例如:
(prog:12345) LablGTK-CRITICAL **: gtk_tree_model_foreach_func:
callback raised an exception
这没有给出堆栈跟踪,也没有关于异常的详细信息,因为它被捕获我无法自己检索这些信息。
我可以针对此案例启用更详细的日志记录信息吗?或者防止异常被自动捕获?
答案 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用户可以使用这样的开关,并希望它最终可用。