Чрезвычайно случайные сбои Pango

Как следует из названия, я столкнулся с некоторыми странными сбоями, очевидно, вызванными Pango или связанными с ним.

Моя программа работает корректно, все делает вовремя, никаких странных визуальных глюков или каких-либо других ошибок, НО такого рода ошибки приводят, как правило, к краху. Иногда он просто генерирует исключение и продолжает работу, но примерно 10% этих исключений заканчиваются сбоем, не говоря уже о том, что я понятия не имею, что может быть причиной этого.

Вот несколько логов разных попыток:

Самый распространенный:

(App:23224): Pango-CRITICAL **: pango_layout_set_width: assertion 'layout != NULL' failed

(App:23224): Pango-CRITICAL **: pango_layout_get_width: assertion 'layout != NULL' failed

(App:23224): Pango-CRITICAL **: pango_layout_get_extents: assertion 'layout != NULL' failed

(App:23224): Pango-CRITICAL **: pango_layout_is_wrapped: assertion 'layout != NULL' failed

(App:23224): Pango-CRITICAL **: pango_layout_is_ellipsized: assertion 'layout != NULL' failed
./Def:822: Warning: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
  Gtk.main()

(App:23224): Pango-CRITICAL **: pango_layout_get_extents: assertion 'layout != NULL' failed

Более или менее распространенный...

(App:22385): Pango-CRITICAL **: pango_layout_is_wrapped: assertion 'layout != NULL' failed

(App:22385): Pango-CRITICAL **: pango_layout_is_ellipsized: assertion 'layout != NULL' failed
./Def:820: Warning: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
  Gtk.main()

(App:22385): Pango-CRITICAL **: pango_layout_get_extents: assertion 'layout != NULL' failed

И самое странное:

Pango:ERROR:/build/buildd/pango1.0-1.36.3/./pango/pango-layout.c:3916:pango_layout_check_lines: assertion failed: (!layout->log_attrs)

Последнюю видел только 1 раз, остальные ошибки вроде обычные.

По иронии судьбы, последний появился, когда мое приложение было еще живо в течение рекордного времени, а затем эта ошибка внезапно закончилась, даже без "общих" ошибок...

Любые идеи, что может происходить?

Как я уже говорил, мое приложение работает как надо, пока одна из вышеперечисленных ошибок не завершит его.

Больше информации:

  1. Мое приложение является многопоточным, но эта ошибка, похоже, не связана с потоками... иначе что-то еще должно жаловаться!

person PythonNoob    schedule 04.12.2016    source источник
comment
Нам нужно было бы увидеть какой-то код. Вы можете использовать G_DEBUG=fatal-warnings для прерывания работы gdb всякий раз, когда появляется предупреждение для помощи в отладке. У меня есть ощущение, что ваша попытка использовать GTK + с несколькими потоками вызывает это.   -  person andlabs    schedule 04.12.2016
comment
Я должен согласиться с andlabs, это сильно пахнет проблемами многопоточности.   -  person Jussi Kukkonen    schedule 05.12.2016
comment
Я думал так же, но у меня нет другой идеи постоянно следить за прогрессом и в то же время обновлять прогрессбар! Тем временем я посмотрю, обнаружит ли gdb что-то еще...   -  person PythonNoob    schedule 05.12.2016
comment
Поделитесь значением через потоки, используя базовый тип C. GTK (как и большинство наборов инструментов) не является потокобезопасным, поэтому попытка обновить виджет вне основного потока может вызвать странные проблемы.   -  person liberforce    schedule 05.12.2016
comment
Я не совсем понимаю ваш комментарий ... Если я поделюсь своим значением, что на самом деле возможно, я все равно не смогу обновлять свой ProgressBar, потому что мне нужно будет настроить монитор с циклом, который будет постоянно обновлять мой ProgressBar, вызывая зависание Gtk.main(), и это также замораживало бы мой виджет, поэтому ProgressBar от 0% до 100% был бы бесполезен...   -  person PythonNoob    schedule 06.12.2016
comment
Решение найдено. Хотели бы вы проголосовать за него, чтобы люди могли легко его увидеть?   -  person PythonNoob    schedule 06.12.2016


Ответы (1)


Что ж, после довольно длительного исследования я нашел Это, это и Это.

Все они были полезны. Первый - это ссылка на другой вопрос SO по той же теме, второй - это ссылка на официальный сайт GNOME для разработчиков, где я нашел информацию о любопытной Gdk функции: Gdk.threads_add_idle, а третий - это ссылка на ошибку отчет из вышеупомянутой функции Gdk, потому что в Python она запрашивает 3 аргумента, тогда как в C запрашивает только 2, но там поясняется, почему она запрашивает 3.

Это было несложно исправить после того, как я обнаружил Gdk.threads_add_idle.

Мне просто нужно было переместить все мои вызовы Gtk в функции и во втором потоке заменить все эти вызовы на Gdk.threads_add_idle(priority, function, data), где priority должно быть GLib.PRIORITY_DEFAULT_IDLE, а function должна быть функцией, содержащей все вызовы Gtk.

data это необязательный аргумент. Он должен содержать все дополнительные данные, которые вы хотели бы передать function.

person PythonNoob    schedule 06.12.2016