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 用户应该可以使用这样的开关,并希望它最终可用。
在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 用户应该可以使用这样的开关,并希望它最终可用。