Bug 4394

Summary: 1С8.1: При закрытии вылетает в дамп
Product: WINE@Etersoft Reporter: Денис Баранов <baraka>
Component: ОбщееAssignee: Александр Морозов <amorozov>
Status: CLOSED FIXED QA Contact: Денис Баранов <baraka>
Severity: minor    
Priority: P4 CC: baraka, kondratyuk, lav, night, shpigor, sonner
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: All   
Whiteboard:
Заявки RT: Связано с:
Дата напоминания:
Bug Depends on: 6061    
Bug Blocks: 437, 5101    
Attachments: бектрейс

Description Денис Баранов 2009-10-25 20:46:04 MSK
Created attachment 1350 [details]
бектрейс

Если открыть 1С 8.1, зайти в документы> Авансовые отчеты>Распечатать любой отчет и сразу после этого закрыть 1С, то проходит запись дампа.
В приложении бэктрейс.
Comment 1 Денис Баранов 2009-10-25 20:48:12 MSK
Проявляется на WINE@Etersoft 1.0.11 eter11/eter6, на eter10 тоже.
Comment 2 Александр Морозов 2009-11-25 20:03:42 MSK
Воспроизвести можно в бутылке 1c81/1c81AccountingBase. При выборе базы надо выбрать "Торговля", после входа в базу выбираем Документы->Затраты->Авансовые отчеты, открываем авансовый отчёт, нажимаем кнопку "Авансовый отчет" внизу, нажимаем Ctrl-P, в появившемся окне OK, закрываем окно 1С.

Падает в BITMAP_DeleteObject при вызове funcs->pDeleteBitmap. В pDeleteBitmap находится какой-то мусор.

trace:bitmap:BITMAP_DeleteObject 0x3a4
trace:gdi:GDI_GetObjPtr (0x3a4): enter 1
trace:gdi:GDI_ReleaseObj (0x3a4): leave 1
trace:bitmap:BITMAP_DeleteObject funcs 0x3b51678
trace:bitmap:BITMAP_DeleteObject funcs->pDeleteBitmap 0x1
err:int:__wine_emulate_instruction instr=0x1 context=0x32f508 CS=0073 IP=0001
wine: Unhandled page fault on read access to 0x00000001 at address 0x1 (thread 0009), starting debugger...
preloader: Warning: failed to reserve range 00000000-00010000
WineDbg starting on pid 0008
Unhandled exception: page fault on read access to 0x00000001 in 32-bit code (0x00000001).
Register dump:
 CS:0073 SS:007b DS:007b ES:007b FS:0033 GS:003b
 EIP:00000001 ESP:0032f82c EBP:0032f8d8 EFLAGS:00210202(   - 00      - -RI1)
 EAX:000003a4 EBX:7eaffff4 ECX:00000000 EDX:00000001
 ESI:7ea70000 EDI:01601300
Stack dump:
0x0032f82c:  7ea8d45d 000003a4 7eb07f70 7eae8703
0x0032f83c:  7eae86b1 00000001 7bcca3e5 00000000
0x0032f84c:  0032f8f0 7bcca388 00000046 00000046
0x0032f85c:  7bcc9f80 7bcaeff4 0000001f 0032f898
0x0032f86c:  7bc35b24 7eaf09b0 0032f8f0 7eb08121
0x0032f87c:  7eaf0bf5 00000000 7bcca244 0000005d
Backtrace:
=>0 0x00000001 (0x0032f8d8)
  1 0x7eac471e DeleteObject+0x630(obj=0x3a4) [/home/amorozov/Projects/wine-eter-1.0.11/dlls/gdi32/gdiobj.c:837] in gdi32 (0x0032fa98)
  2 0x7ea8e205 BRUSH_DeleteObject+0x9d(handle=0x3a8) [/home/amorozov/Projects/wine-eter-1.0.11/dlls/gdi32/brush.c:424] in gdi32 (0x0032fad8)
  3 0x7eac471e DeleteObject+0x630(obj=0x3a8) [/home/amorozov/Projects/wine-eter-1.0.11/dlls/gdi32/gdiobj.c:837] in gdi32 (0x0032fc98)
0x00000001: -- no code accessible --
Comment 3 Александр Морозов 2009-12-02 14:33:23 MSK
Последовательность действий 1С такая:
BITMAP_SelectObject (0x6c, 0x2060)
  DC_InitDC (0x3b55f70)
    BRUSH_SelectObject (0x3a8, 0x2060)
      BITMAP_SetOwnerDC (0x3a4, 0x3b55f70)
DeleteDC (0x2060)
BITMAP_DeleteObject (0x3a4) - здесь происходит падение
0x3b55f70 - это указатель на DC, возвращаемый get_dc_ptr(0x2060)
Comment 4 Александр Морозов 2009-12-02 20:05:14 MSK
> Падает в BITMAP_DeleteObject при вызове funcs->pDeleteBitmap.
> В pDeleteBitmap находится какой-то мусор.
Область памяти, на которую указывает funcs, освобождается в функции DRIVER_release_driver, которую вызывает DeleteDC. Значение указателю funcs присваивается в функции BITMAP_SetOwnerDC, вызываемой до вызова DeleteDC.
Comment 5 Vitaly Lipatov 2009-12-02 22:17:57 MSK
(In reply to comment #3)
> Последовательность действий 1С такая:
> BITMAP_SelectObject (0x6c, 0x2060)
>   DC_InitDC (0x3b55f70)
>     BRUSH_SelectObject (0x3a8, 0x2060)
>       BITMAP_SetOwnerDC (0x3a4, 0x3b55f70)
> DeleteDC (0x2060)
> BITMAP_DeleteObject (0x3a4) - здесь происходит падение
> 0x3b55f70 - это указатель на DC, возвращаемый
> get_dc_ptr(0x2060)

Нужно проверить, падает ли в Windows удаление несуществующего объекта.
Также возможно нужно добавить обработчик падения и всё.

Comment 6 Александр Морозов 2009-12-03 12:46:33 MSK
> Нужно проверить, падает ли в Windows удаление
> несуществующего объекта.
Простой тест под WINE, делающий нечто подобное, не падает, хотя в нём и используется уже освобождённая память. Для того, чтобы он упал, надо, чтобы в этой памяти было записано что-то новое.
Подобное поведение может быть и в Windows. То есть если не упадёт, это ещё не значит, что так можно делать.

> Также возможно нужно добавить обработчик
> падения и всё.
Что за обработчик падения?
Comment 7 Александр Морозов 2009-12-03 13:05:25 MSK
(In reply to comment #6)
> > Нужно проверить, падает ли в Windows удаление
> > несуществующего объекта.
> Простой тест под WINE, делающий нечто
> подобное, не падает, хотя в нём и
> используется уже освобождённая память. Для
> того, чтобы он упал, надо, чтобы в этой
> памяти было записано что-то новое.
> Подобное поведение может быть и в Windows. То
> есть если не упадёт, это ещё не значит, что
> так можно делать.

Что-то я не про то ответил. При удалении несуществующего объекта простая программа не упала ни в Windows, ни в WINE.
Comment 8 Александр Морозов 2009-12-11 20:27:17 MSK
Существуют функции DRIVER_get_driver и DRIVER_release_driver, которые увеличивают и уменьшают число ссылок на структуру graphics_driver, содержащую структуру funcs, из-за преждевременного освобождения которой падает 1С. Использовал эти функции в функциях BITMAP_*, но проблему это не решило. При этом в добавленных логах можно увидеть, например, такое:
trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 55
trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 55
trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 55
trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 55
Хотя вроде бы такого быть не может, счётчик должен уменьшаться, если не вызывается DRIVER_get_driver.
Comment 9 Александр Морозов 2009-12-14 17:29:07 MSK
> trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 55
> trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 55
> trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 55
> trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 55

Разобрался с чем это связано, счётчик увеличивался в функции load_display_driver, которая вызывается из DRIVER_load_driver:

trace:driver:load_display_driver driver 0x11b928 funcs 0x11b938 count 66 (thread 9)
trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 65 (thread 9)
trace:driver:load_display_driver driver 0x11b928 funcs 0x11b938 count 66 (thread 9)
trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 65 (thread 9)
trace:driver:load_display_driver driver 0x11b928 funcs 0x11b938 count 66 (thread 9)
trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 65 (thread 9)
trace:driver:load_display_driver driver 0x11b928 funcs 0x11b938 count 66 (thread 9)
trace:driver:DRIVER_release_driver driver 0x11b928 funcs 0x11b938 count 65 (thread 9)
Comment 10 Александр Морозов 2009-12-14 21:24:09 MSK
> Существуют функции DRIVER_get_driver и DRIVER_release_driver,
> которые увеличивают и уменьшают число
> ссылок на структуру graphics_driver, содержащую
> структуру funcs, из-за преждевременного
> освобождения которой падает 1С.
> Использовал эти функции в функциях BITMAP_*, но
> проблему это не решило.

Разобрался, почему это не работало. Ссылка funcs может быть проинициализирована ещё и в CreateDIBSection, а не только в функциях BITMAP_*. Патч:
gdi32: Prevent freeing graphics_driver when it is used by bitmap object (eterbug #4394).
Comment 11 Andrey Vusik 2009-12-16 18:41:05 MSK
Принято.
1.0.12-eter1.2/1
Comment 12 Илья Шпигорь 2010-05-13 13:54:54 MSD
В eterhack откатил коммит:

commit c3cd0cfba9932e683fb6ddddb8fe63b2c0f01321
Author: Alexander Morozov <amorozov@etersoft.ru>

    gdi32: Prevent freeing graphics_driver when it is used by bitmap object (eterbug #4394).

Т.к. при сломал сборку wine:

bitmap.o: In function `BITMAP_SetOwnerDC':
/srv/shpigor/Projects/WINE/wine-eterhack/dlls/gdi32/bitmap.c:588: undefined
reference to `DRIVER_release_driver'
/srv/shpigor/Projects/WINE/wine-eterhack/dlls/gdi32/bitmap.c:589: undefined
reference to `DRIVER_get_driver'
/srv/shpigor/Projects/WINE/wine-eterhack/dlls/gdi32/bitmap.c:579: undefined
reference to `DRIVER_get_driver'
bitmap.o: In function `BITMAP_DeleteObject':
/srv/shpigor/Projects/WINE/wine-eterhack/dlls/gdi32/bitmap.c:675: undefined
reference to `DRIVER_release_driver'
dib.o: In function `CreateDIBSection':
/srv/shpigor/Projects/WINE/wine-eterhack/dlls/gdi32/dib.c:1351: undefined
reference to `DRIVER_get_driver'
Comment 13 Александр Морозов 2011-02-01 21:40:02 MSK
На текущем eterhack не воспроизводится
Comment 14 Денис Баранов 2011-02-23 18:49:18 MSK
Закрываю.