Created attachment 394 [details] Install.log При массовой печати документов "Реализация" через "Групповую обработку документов" 1С вылетает, НО если, после загрузки 1С открыть печатную форму "Реализации", посмотреть, закрыть, и попытаться провести массовую печать через "Групповую обработку документов", все начинает работать нормально. Этот баг висит уже давно и сильно мешает нам работать! - плохо. Для решения данной проблемы направляю Вам демо-конфигурацию - DataBase с нашими настройками: ftp://ftp.referent.ru/Citrix/Arhiv.tar.gz Используются и прилагаются доп. компоненты, зарегите 1CPP.dll и FormEx.dll Пользователь Администратор, пароля нет. В ЖД лежит ряд реализаций и документ "Ведомость выдачи документов клиенту". Откройте документ Ведомость, нажмите кнопку "Печать Документов", выберите любой принтер и нажмите кнопку "Выполнить" - 1С вылетает.
Created attachment 395 [details] wine.log
*** Bug 1363 has been marked as a duplicate of this bug. ***
Ошибка воспроизвелась. При нажатии на выполнить, вылетает в дебаг: err:syslevel:_EnterSysLevel (0x7eee0e60, level 2): Holding 0x7edc4ba0, level 3. Expect deadlock! err:syslevel:_EnterSysLevel (0x7eee0e60, level 2): Holding 0x7edc4ba0, level 3. Expect deadlock! err:syslevel:_EnterSysLevel (0x7eee0e60, level 2): Holding 0x7edc4ba0, level 3. Expect deadlock! err:syslevel:_CheckNotSysLevel Holding lock 0x7edc4ba0 level 3 wine: Unhandled exception 0x80000003 at address 0x7b88cdf0 (thread 0009), starting debugger... WineDbg starting on pid 0008 0x7b88cdf0 _CheckNotSysLevel+0x40 in kernel32: int $3 Wine-dbg>bt Backtrace: =>1 0x7b88cdf0 _CheckNotSysLevel+0x40() in kernel32 (0x00325804) 2 0x7ed93a30 in gdi32 (+0x43a30) (0x00325814) 3 0x7ed6c512 DeleteDC+0x22() in gdi32 (0x00325844) 4 0x5f4038c2 in mfc42 (+0x38c2) (0x00325864) 5 0x7800c9b8 in msvcrt (+0xc9b8) (0x00327840) 6 0x5f4023d8 in mfc42 (+0x23d8) (0x00327850) 7 0x5f4022ae in mfc42 (+0x22ae) (0x00327880) 8 0x5f402c25 in mfc42 (+0x2c25) (0x003278b0) 9 0x2502540e in moxel (+0x2540e) (0x00327908) 10 0x5f402976 in mfc42 (+0x2976) (0x00327958) 11 0x5f4029d7 in mfc42 (+0x29d7) (0x003279f0) 12 0x5f401cea in mfc42 (+0x1cea) (0x00327a10) 13 0x5f401c73 in mfc42 (+0x1c73) (0x00327a70) 14 0x5f401bfb in mfc42 (+0x1bfb) (0x00327a8c) 15 0x5f401bba in mfc42 (+0x1bba) (0x00327ab8) 16 0x7ee9c36a WINPROC_wrapper+0x1a() in user32 (0x00327ae8) 17 0x7ee9ca6e WINPROC_wrapper+0x71e() in user32 (0x00327b28) 18 0x7eea2081 in user32 (+0xb2081) (0x00327b68) 19 0x7ee647fa in user32 (+0x747fa) (0x00327bd8) 20 0x7ee67a02 in user32 (+0x77a02) (0x00327c38) 21 0x7ee67e1e SendMessageA+0x4e() in user32 (0x00327c78) 22 0x2a055cc5 in basic (+0x55cc5) (0x00000001) 23 0x00000000 (0x00000000)
Бутылка: 1c77-27, информационная база №1.
при вызове из BITMAP_SelectObject функции BITMAP_SetOwnerDC, выполняется создание нового bitmap, при этом: bitmap->funcs = dc->funcs если после этого посмотреть bitmap->funcs->pGetBitmapBits , то оно равно нулю. а падение происходит при вызове из PSDRV_Brush функции GetBitmapBits. В ней выполняется: if(bmp->funcs && bmp->funcs->pGetBitmapBits) { TRACE("Calling device specific BitmapBits\n"); ret = bmp->funcs->pGetBitmapBits(hbitmap, bits, count); } указатель pGetBitmapBits должен быть равен нулю, а на момент выполнение туда попадает случайное значение
При предварительном просмотре всё нормально печатается, при этом функция PSDRV_Brush не вызывается.
функция PSDRV_Brush падает при вызове PSDRV_WritePatternDict. При отключении PSDRV_WritePatternDict PSDRV_Brush завершается успешно, вызывающая её PSDRV_PatBlt тоже завершается успешно,а падает значительно выше.
При добавлении строк, служащих только для вывода информации стало падать даже после предварительноко просмотра. Падает на функции PSDRV_WritePatternDict().
изначально в функцию предаются очень странные значения bitmap: bmWidth=2112886257 bmHeight=10, bmBitsPixel=50 bmPlanes=28196, bmWidthBytes=3305028 Хоть данная функция и содержит потенциальные ошибки, но дело не в ней. Ещё до её вызова в область стека, где хранится bitmap попадают случайные значения
Падает потому, что в функции _CheckNotSysLevel стоит вызов DbgBreakPoint(), которая определена как: void WINAPI DbgBreakPoint(void) { kill(getpid(), SIGTRAP); } если в этом месте не вызывать DbgBreakPoint(), то при печати 1с не падает, но в консоль постоянно(даже после печати) поступают сообщения: err:syslevel:_EnterSysLevel (0x7edab160, level 2): Holding 0x7ec80640, level 3. Expect deadlock! Отулючать данную проверку нельзя, надо разобраться почему в этом месте она не проходит. Не проходит она при вызове из функции DeleteDC()
При вызове _EnterSysLevel() происходит блокировка критической секции. Если не был вызван _LeaveSysLevel, то при вызове _CheckNotSysLevel процесс принудительно завершается Подозрительно в этом плане выглядит функция GDI_GetObjPtr. Вначале выполняется _EnterSysLevel( &GDI_level ); , а _LeaveSysLevel выполняется только в случае неправильного хендла if (!ptr) { _LeaveSysLevel( &GDI_level ); WARN( "Invalid handle %p\n", handle ); }
Потому что Leave выполняется из GDI_ReleaseObj который обязан вызвать каждый. Скорее всего дело в непарности GDI_GetObjPtr/GDI_ReleaseObj в каком-то месте.
Падение происходит потому, что в функции GetBitmapBits программа не доходит до GDI_ReleaseObj. А происходит это потому, что вызывается: if(bmp->funcs && bmp->funcs->pGetBitmapBits) { TRACE("Calling device specific BitmapBits\n"); ret = bmp->funcs->pGetBitmapBits(hbitmap, bits, count); } на первых страницах pGetBitmapBits=NULL. Потот туда каким-то образом попадает случайное число, программа переходит по данному адресу, и падает. т.е если pGetBitmapBits остаётся равным NULL, то всё работает. НО: При предварительном просмотре pGetBitmapBits не равен NULL. указатель имеет вполне определённое постоянное значение: bm->funcs->pGetBitmapBits=0x7e7ae495
при повторном запуске адрес этот изменяется, но принадлежит он функции X11DRV_GetBitmapBits. Т.е если был включен предварительный просмотр, то при печати используется функция копирования от графического драйвера
Память перезаписывает функция внутри oleaut32.dll ConnectionPointImpl_Construct+0x8d [/srv/vitperov/Projects/wine/dlls/oleaut32/connpt.c:114] Возможно память до этого случайно освобождается, а данная функция просто пишет поверх освободившегося куска памяти.
функция BITMAP_SetOwnerDC ставит функции обработки для данного bitmap. в случае если bitmap->funcs == 0 она берёт из из DC: bitmap->funcs = dc->funcs; Но, если там уже что-то есть, то новые функции функции обработки остаются старыми. Если там каким-то чудом оказывается на месте pGetBitmapBits записан 0, то печать работает нормально. если же там другое значение, то программа переходит по этому адресу и вылетает. Думаю если в данном месте принудительно обновлять функции, то проблема исчезнет. Но всё-же нужно узнать откуда в bitmap->funcs появляются такие значения
В общем делаем такой хак, некогда больше заниматься. Планируем проверить поведение SetOwnerDC в винде в случае уже имеющегося funcs, ну и конечно стоит попытаться выяснить что же там происходит, чей это адрес.
пытался выяснить куда указывает старый адрес funcs. смотрел отдельные функции в funcs - там просто случайные числа (по указанным адресам перехода просто попадаем в середину какой-то функции). Cкорее всего это освобождённая память т.к значения там остаются постоянные, и изменяются только перед падением В последнее время бага отказывается воспроизводится (падает 1 раз из 20) даже при откате всех внесённых изменений. Странно то, что в funcs в переменной pGetBitmapBits всегда 0, поэтому всё работает. Притом соседние функции не нулевые. Т.к в последнее время почти невозмножно заставить программу падать, то предлагаю сделать предложенное изменение и протестировать результат. Если бага всё же появится, то разбираться дальше
патч уже вошёл в новую сборку. Сейчас всё должно работать