Исключения в обратных вызовах 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, и надеюсь, что он в конечном итоге будет доступен.

Другие вопросы по тегам