Укажите отработанное время

Отработанное время:
Продуктивное время:
Bug 1911 - написать тест для функции BITMAP_SetOwnerDC   Make a simular bug
Summary: написать тест для функции BITMAP_SetOwnerDC
Status: CLOSED INVALID
Alias: None
Product: WINE@Etersoft
Classification: Продукты (Products)
Component: Графика GDI / DIB / GDIPLUS (show other bugs)
Version: unspecified
Hardware: PC Linux
: P5 minor
Target Milestone: ---
Assignee: Sergei Novosyolov
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 1689 7389
  Show dependency treegraph
 
In work:
Reported: 2008-06-07 19:13 MSD by Виталий Перов
Modified: 2011-06-27 14:35 MSK (History)
3 users (show)

See Also:
Заявки RT:
Связано с:
Дата напоминания:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Виталий Перов 2008-06-07 19:13:54 MSD
функция BITMAP_SetOwnerDC служит для связывания bitmap с таблицей функций.

в случае если bitmap->funcs == 0 она берёт функции из из DC:
bitmap->funcs = dc->funcs;

Но, если там уже что-то есть, то остаются старые функции обработки изображения.

Необходимо выяснить (создать тест) как в этом случае ( когда bitmap->funcs не равны 0) поступает Windows.
Comment 1 Илья Шпигорь 2008-07-09 13:32:04 MSD
В ходе написания нужного теста был получен случай, когда wine однозначно и постоянно падает. 
Это происходит в функции SetDIBits на вызове dc->funcs->pSetDIBits:

    if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
    result = lines;
    if (bitmap->funcs)
    {
        if (bitmap->funcs != dc->funcs)
            ERR( "not supported: DDB bitmap %p not belonging to device %p\n", hbitmap, hdc );
        else if (dc->funcs->pSetDIBits)
        {
            result = dc->funcs->pSetDIBits( dc->physDev, hbitmap, startscan,                       lines, bits, info, coloruse );
        }
    }

wine: Unhandled page fault on read access to 0x00000000 at address 0x7e91365b (thread 0009), starting debugger...

В WINDOWS тест проходит нормально. 
Comment 2 Виталий Перов 2008-07-09 14:05:03 MSD
Если я правильно понял, то падает на:
result = dc->funcs->pSetDIBits( dc->physDev, hbitmap, startscan,   
                   lines, bits, info, coloruse );

А функции точно передаются не нулевые параметры?
Comment 3 Анатолий Лютин 2008-07-09 14:08:20 MSD
Я думаю, что в первую очередь надо проверить - заполняется ли указатель pSetDIBits, затем - указатель dc->funcs и только затем dc и нулевые параметры.
Comment 4 Анатолий Лютин 2008-07-09 14:09:20 MSD
Имеется ввиду - pSetDIBits - действительно ли необходимая функция...
Comment 5 Анатолий Лютин 2008-07-09 14:10:31 MSD
По dc->physDev так же возможны падения - я наталкивался пару раз, когда physDev заполнялся только NULL.
Comment 6 Илья Шпигорь 2008-07-09 14:24:30 MSD
В результате проверки получилось:

dc = 0x0011bd30
dc->funcs = 0x001183b0
dc->funcs->pSetDIBits = 0x7e91c7b0

Из переданных в функцию параметров, некоторые действительно имели нулевое значение:

dc->physDev = 0x0011bf00 hbitmap = 0x000001d4 startscan = 0x00000000 lines = 0x00000064 bits = 0x00000000 info = 0x00000000 coloruse = 0x00000000
Comment 7 Анатолий Лютин 2008-07-09 14:29:01 MSD
(In reply to comment #6)
> В результате проверки получилось:
> 
> dc = 0x0011bd30
> dc->funcs = 0x001183b0
> dc->funcs->pSetDIBits = 0x7e91c7b0
> 
> Из переданных в функцию параметров,
> некоторые действительно имели нулевое
> значение:
> 
> dc->physDev = 0x0011bf00 hbitmap = 0x000001d4 startscan = 0x00000000 lines =
> 0x00000064 bits = 0x00000000 info = 0x00000000 coloruse = 0x00000000
> 

Тогда похоже, что pSetDIBits падала из-за нулевого  const BITMAPINFO *info

Надеюсь я не обижу уточнением, что pSetDIBits == X11DRV_SetDIBits ? 
Comment 8 Анатолий Лютин 2008-07-09 14:29:31 MSD
Случайно не туда нажал, извините..
Comment 9 Vitaly Lipatov 2008-07-09 19:50:55 MSD
Понятно, что тест нужно писать для функции SetOwnerDC, которой передаётся объект типа BITMAP.

Также поскольку ошибка - read access, значит проблема не в нулевом указателе на функцию (был бы exec access), а в указателе на какие-то данные.

Также при каждом падении выводится backtrace, из которого понятно, в каком месте программы (и в какой строчке) произошло падение. С ним можно было бы меньше гадать, где именно падаем.
Comment 10 Илья Шпигорь 2008-07-11 11:15:38 MSD
В общем я разобрался почему происходит падение wine. Все из-за вызова ф-ции 
CreateDIBitmap и передачи ей CBM_INIT, с одновременным BITMAPINFO *data равным NULL. Что-нибудь вроде такого вызова: 

hbmp = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, NULL, DIB_RGB_COLORS);

После чего в ходе выполнения этот NULL передается ф-ции DIB_GetBitmapInfo. Она делает header->biSize, а header и есть этот параметр равный NULL. Все падает.

Конечно вряд ли кто-нибудь допустит такой вызов с CBM_INIT и NULL. Но можно на всякий случай сделать патч с праверкой header на NULL? В винде, все-таки, такой вызов проходит нормально.
Comment 11 Анатолий Лютин 2008-07-11 11:31:24 MSD
(In reply to comment #10)
> Конечно вряд ли кто-нибудь допустит такой
> вызов с CBM_INIT и NULL. Но можно на всякий случай
> сделать патч с праверкой header на NULL? В винде,
> все-таки, такой вызов проходит нормально.
> 

Отлично!

Наверное правильным будет сделать исправление к функции и сразу тест, показывающий, что функция что-то возвращает при таком сочетании параметров и не падает. То есть даже не надо todo_wine для таких случаев ставить и сразу его убирать. Надо сделать исправление с тестом и отослать одним файлом.
Comment 12 Илья Шпигорь 2008-07-11 12:50:07 MSD
С тестом для BITMAP_SetOwnerDC у меня ничего не получается. Практически все вызовы сопровождаются проверкой:

if (!bitmap->funcs && !BITMAP_SetOwnerDC( handle, dc ))

т.е. если bitmap->funcs уже есть то ф-ция даже не вызывается. 
Есть еще вызов в CreateDIBitmap, но перед ним handle создается заново, т.е. bitmap->funcs тоже 0.
Один вызов есть в BRUSH_SelectObject: 

BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );

но заранее задать brush->logbrush.lbHatch нельзя - объект внутренний. Опять же bitmap->funcs оказывается равен 0.
Comment 13 Виталий Перов 2008-07-31 14:18:44 MSD
Проверить требуется только то, как ведёт себя функция BITMAP_SetOwnerDC
Думаю можно создать bitmap, даже с пустым набором функций. А затем присвоить bitmap->funcs какое-нибудь значение. А затем проверить перезапишется ли оно после вызова BITMAP_SetOwnerDC.

Даже не обязательно "правильно" создавать bitmap и DC. Можно просто посмотреть код BITMAP_SetOwnerDC и вручную заполнить те поля, которые она использует
Comment 14 Виталий Перов 2008-07-31 14:22:00 MSD
Ой! что-то я не то написал. Известно, что использует BITMAP_SetOwnerDC в wine, но не извесно как она устоена в винде. Так что вручную заполнять bitmap и DC всё же не стоит
Comment 15 Анатолий Лютин 2008-07-31 15:01:41 MSD
(In reply to comment #14)
> Ой! что-то я не то написал. Известно, что
> использует BITMAP_SetOwnerDC в wine, но не извесно как
> она устоена в винде.

Т.к. она не маркирована WINAPI, то с 90% вероятностью такой функции в Win API нет.

> Так что вручную
> заполнять bitmap и DC всё же не стоит
> 

Comment 16 Vitaly Lipatov 2008-07-31 15:58:29 MSD
(In reply to comment #15)
> (In reply to comment #14)
> > Ой! что-то я не то написал. Известно, что
> > использует BITMAP_SetOwnerDC в wine, но не извесно как
> > она устоена в винде.
> 
> Т.к. она не маркирована WINAPI, то с 90%
> вероятностью такой функции в Win API нет.
Ну WINAPI это макрос, определяющий соглашение о вызове (calling convention) этой функции. В основном конечно все внешние функции его используют, но прямой связи с WinAPI таки нет.

Ну и конечно никой BITMAP_SetOwnerDC в Windows нет
Тестировать её можно через CreateDIBitmap или SelectObject, из которых она вызывается.

Но в общем оставим пока эту задачу.
Comment 17 Анатолий Лютин 2008-07-31 16:02:59 MSD
(In reply to comment #16)
> > Т.к. она не маркирована WINAPI, то с 90%
> > вероятностью такой функции в Win API нет.
> Ну WINAPI это макрос, определяющий соглашение
> о вызове (calling convention) этой функции. В
> основном конечно все внешние функции его
> используют, но прямой связи с WinAPI таки нет.

:)))
Конечно и ёжику понятно, что это соглашение о вызове. Я просто отметил закономерность, которую ты и указал:

>В
> основном конечно все внешние функции его
> используют, но прямой связи с WinAPI таки нет.

С таким же успехом я мог написать, что это название функции не соответствует принятому стилю именования функций Win32 API.
 
Comment 18 Vitaly Lipatov 2008-07-31 16:37:35 MSD
(In reply to comment #17)

> С таким же успехом я мог написать, что это
> название функции не соответствует
> принятому стилю именования функций Win32 API.
Ну скорее даже можно однозначно утверждать что функции с подобными префиксами - внутренние для библиотек проекта Wine и не экспортируются.
Comment 19 Виталий Перов 2008-08-01 13:07:51 MSD
> Ну и конечно никой BITMAP_SetOwnerDC в Windows нет
> Тестировать её можно через CreateDIBitmap или
> SelectObject, из которых она вызывается.
> 
Да, действительно! Я как-то сразу не заметил :(

Comment 20 Виталий Перов 2008-10-28 18:15:10 MSK
Да, тут я с самого начала был неправ:
Нельзя писать тест на не winapi-шную функцию