Программа вылетает на XPutImage в отдельном потоке (В Lenny. В Etch работает)

Модератор: Модераторы разделов

MiK13
Сообщения: 1289
ОС: Linux Debian

Программа вылетает на XPutImage в отдельном потоке

Сообщение MiK13 »

Пишу программу, которая должна непрерывно выводить информацию а экран. Вывод произвожу через XPutImage, предварительно подготовив в двумерном массиве "иоображение" того, что должно быть выведено. На своём компе отладил -- всё работает. Пошёл проверять на "рабочем" -- сразу после запуска программа вылетает. Опыта написания иксовыъ приложений пока нет. До этого писал только с svgalib, но на новом компе (пройессор Geode LX) svgalib не идёт. Да и инсы удалось запустить только после того, как на 4-м диске нашёл пакет xserver-xorg-video-geode.
Программа такая:

Код:

... int main(int argc, char *argv[]) { ... // Инициализация ... // иксов bi=XCreateImage(display, vis, 24, ZPixmap, 0, im1.b, WIDTH_MIN, HEIGHT_MIN, 32, WIDTH_MIN*4); // Пока не знаю, нужно ли заполнять чем-нибудь структуру vis bi->red_mask =0xFF0000; // Не знаю bi->green_mask=0xFF00; // нужны ли bi->blue_mask =0xFF; // эти строки XInitImage(bi); pthread_attr_init(&attr); pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM); pthread_create(&pid,&attr,out_graph,0); /************ Цикл получения и обработки ошибок ************/ while(1) { XNextEvent(display,&report); // Взять очередное событие из очереди switch(report.type) { ... } } void *out_graph(void *arg) { ... // Описание внутренних переменных while(1) { ... // "Рисование" изоюражение в массиве im1 XPutImage(display,window, gc, bi, 0,0, 30,5, 740, 556); usleep(10000); } }

Сначала думал, что проблема в новом процессоре (GEODE LX), т.к. на моём основном Celeron'е программа работала.
Пришёл домой -- запускаю на Athlon'е -- аналогичная картина: после запуска програииа завершается а на экране остаётся:

Код: Выделить всё

$ ./osc
osc: ../../src/xcb_io.c:228: _XSend: Assertion `!dpy->xcb->request_extra' failed.
Аварийный останов

Когда из функции out_graf убрал вызов XPutImage(... то программа стала работать и из основного тела вызов этой функции (по нажатию клавиши) проходит без проблем
Возникла даже мысль про процессоры AMD, т.к. на работе проверял ещё на серверном Pentium'е.
Но на уже староватом Duron'е 750, на котором стоит Etch r0 программа работает почти нормально (почти -- потому, что не всегда сразу реагирует на клавиатуру. Но нажатия не теряет)
Подозреваю, что причина в конкуренции за вывод в окно, т.к. программа иногда может и запуститься и будет нормально выводить картинку из потока. Но только до того, пока не попробуешь что-то сделать в основной части программы.
Как мне решить эту проблему?

P.S. Гуглинг по xcb_io.c выдал довольно много ссылок с похожими сообщениями, более того, было даже сообщение:
On Fedora 8, the new X11 is breaking programs like nmrDraw from NMRPipe.
The program runs fine under Fedora 7 but fails under Fedora 8 with the error...

nmrdraw: xcb_io.c:285: _XAllocID: Assertion `!(dpy->flags & (1L << 3))' failed.
Abort
т.е., как я понял, под 7-й Федорой программа работала, а под более новой 8-й работать не захотела.
Но сообщение там было другое и, позоже, автор проблему тоже не решил.
Спасибо сказали:
MiK13
Сообщения: 1289
ОС: Linux Debian

Re: Программа вылетает на XPutImage в отдельном потоке

Сообщение MiK13 »

Немного изменил программу, работающую в отдельном потоке -- перед циклом while(1) добавил sleep на пол секунды.
Программа стала запускаться стабильно. Но только до нажатия какой-нибудь клавиши.
В основном теле программы у меня обрабатываются три клавиши:
Esc -- завершение
F5 -- изменение на 1 цвета фона (красного канала) и очистка экрана.
F9 -- вывод основной картинки (тот же, что и в отдельном потоке, сделал для проверки)
Программа вылетает если паралельно с выводом картинки (по XPutImage) очищать экран по

Код: Выделить всё

SetWindowBackground(display, window, cw );
XClearWindow( display, window );
Причём, вылетает тем скорее, чем чаще выполнять эту очиству.
Понятно, что в реальной ситуации такого не будет, но я бы не беспокоился, если бы программа на рабочем компьютере (с GEODE LX) не вылетала при единичном нажатии клавишей, причём даже тех, которые не вызывают никаких действий с окном, а только выводят информацию по printf.

Дома проверял на двух машинах
Duron-750 МГц, Ehch r0. Ядро 2.6.18-4-K7 (из дистрибутива). Заставить программу вылететь не удалось даже после тысячи нажатий F5 с частотой 50 Гц.
Athlon 64. Проверял в нескольких системах и с разными ядрами.
RIPLinux 7.8. Запустилась только 32-битная версия. Работала стабильно.
Ubuntu 8.10 для i386 (ядро 2.6.27*). Вылетала довольно быстро (тот же файл, что стабильно работал на Дюроне)
Ubuntu 8.10 для amd64. Вылетала довольно быстро. Запускалась только 64-битная версия.
Debian Lenny amd64 (ядро 2.6.26). Аналогично Ubuntu. Но запускались как 32-битная, так и 64-битная версии.
Во всех случаях программа завершалась с сообщением, о котором говорил в предыдущем посте.
Debian Etch r6 amd64. Тут запускалась только 64-битная версия. И работала заметно дольше.
Проверял с ядрами 2.6.18 и 2.6.24 (который в дистрибутиве). Впечатление, что с ядром 2.6.18 программа работала дольше. И сообщение о завершении было (но бывали и другие):

Код: Выделить всё

X Error of failed request:  BadLength (poly request too large or internal Xlib length error)
  Major opcode of failed request:  30 (X_ChangeActivePointerGrab)
  Serial number of failed request:  722
  Current serial number in output stream:  723

Общее впечатление -- чем более новое ядро и более новый Linux, там быстрее вылетает программа.
Спасибо сказали: