1

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

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

这没有提供堆栈跟踪,也没有关于异常的详细信息,并且由于它被捕获,我自己无法检索此信息。

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

4

2 回答 2

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 版本。

然后我运行了 OCaml 二进制文件gdb,我得到了我的堆栈跟踪,其中包含调用 Lablgtk 函数的精确行号。从那里开始,它是一个快速的 3 行补丁。

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

于 2015-03-20T10:25:20.920 回答
1

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

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

假设是您的自定义异常打印机,您可以通过在代码中val my_exn_printer : exn -> unit替换~callback:fby来简单地打印回调异常。~callback:(callback_print_exn f)

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

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

于 2015-03-16T14:47:33.683 回答