Исключения в обратных вызовах Lablgtk
В Lablgtk, когда в обратном вызове возникает исключение, оно автоматически перехватывается, и в консоли выводится сообщение об ошибке, например:
(prog:12345) LablGTK-CRITICAL **: gtk_tree_model_foreach_func:
callback raised an exception
Это не дает никакой трассировки стека и никакой информации об исключении, и, поскольку оно перехвачено, я не могу получить эту информацию самостоятельно.
Могу ли я включить более подробную информацию для регистрации в этом случае? Или предотвратить автоматическое обнаружение исключения?
2 ответа
Я думаю, что лучший способ сделать это - перехватить ваше исключение вручную и обработать его самостоятельно.
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)
в вашем коде.
Конечно, вы также можете с помощью этого метода отправить это исключение в другой поток, зарегистрировать "идентификатор обратного вызова", который будет передаваться вместе с вашим исключением...
Что касается трассировки стека, я не уверен, что вы сможете легко ее найти. Поскольку он запускается как обратный вызов, вы, вероятно, хотите знать используемый сигнал, который можно сохранить в обработчике обратного вызова.
У меня была другая похожая проблема, но на этот раз было сложнее найти, куда направить вызовы, чтобы перехватить исключение.
К счастью, на этот раз из кода Glib C пришло очень специфическое сообщение об ошибке:
GLib-CRITICAL **: Source ID ... was not found when attempting to remove it`
Переполнение стека + grep
привел меня к реальной функции C, но я не смог найти, какая из нескольких функций Lablgtk, связанных с этим кодом, была виновником.
Поэтому я скачал исходный код Glib, добавил к коду явную ошибку сегментации, скомпилировал ее и использовал LD_LIBRARY_PATH
заставить мою модифицированную версию Glib быть загруженной.
Затем я запустил бинарный файл OCaml с gdb
, и я получил свою трассировку стека с точным номером строки, где вызывается функция Lablgtk. И оттуда это был быстрый 3-строчный патч.
Подобных хаков (которые все же были быстрее, чем попытки найти место для перехвата вызова) можно избежать, если использовать "строгий режим", предотвращающий автоматическую перехват исключений. Я все еще верю, что такой переключатель должен быть доступен для пользователей Lablgtk, и надеюсь, что он в конечном итоге будет доступен.