Вход | Регистрация
 

Иногда зависает внешняя компонента на некоторых рабочих местах

Иногда зависает внешняя компонента на некоторых рабочих местах
Я
   TormozIT
 
23.07.21 - 07:20
Есть внешняя компонента https://github.com/tormozit/RDT_Common_1C/blob/master/AddInNative.cpp сделанная из шаблона.
Есть код ее создания

    Суффикс = "";
    Попытка
        ВК = Новый ("AddIn.ирОбщая.AddIn");
        Суффикс = "СломанОбщийКэш";
        ВК.PID();
    Исключение
        Это64битныйПроцесс = ирКэш.Это64битныйПроцессЛкс();
        ИмяМакета = "ВК";
        Если Это64битныйПроцесс Тогда
            ИмяМакета = ИмяМакета + "64";
        Иначе
            ИмяМакета = ИмяМакета + "32";
        КонецЕсли;
        Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
            ДвоичныеДанные = ирПортативный.ПолучитьМакет(ИмяМакета);
        Иначе
            ДвоичныеДанные = Обработки.ирПортативный.ПолучитьМакет(ИмяМакета);
        КонецЕсли;
        АдресКомпоненты = ПолучитьИмяВременногоФайла("dll");
        ДвоичныеДанные.Записать(АдресКомпоненты);
        //АдресКомпоненты = "D:\VC\Native_Comp_RDT\binWin32\AddInNative.dll"; // Для отладки
        Если Суффикс = "СломанОбщийКэш" Тогда
            // https://www.hostedredmine.com/issues/889213
            // Отказываемся от кэширования для всех сеансов. Так каждый сеанс будет хранить в кэше свой экземпляр компоненты
            Суффикс = ИдентификаторИзПредставленияЛкс(Новый УникальныйИдентификатор);
        КонецЕсли;
        Результат = ПодключитьВнешнююКомпоненту(АдресКомпоненты, "ирОбщая" + Суффикс, ТипВнешнейКомпоненты.Native);
        Если Не Результат Тогда
            ВызватьИсключение "Не удалось подключить внешнюю компоненту Общая";
        КонецЕсли;
        ВК = Новый ("AddIn.ирОбщая" + Суффикс + ".AddIn");
        //ВК.PID();
    КонецПопытки;
    Возврат ВК;

На небольшом проценте рабочих мест она вызывает умеренно стабильное зависание при подключении либо вызове методов.
Компоненту делал, опираясь на статью https://infostart.ru/public/184119/
У меня зависание не воспроизводится.
Отправил дамп зависания, предоставленный пользователем, в 1С.
Получил ответ:
------------------
По предоставленному дампу проблема возникает вне кода платформы.
Исправить поведение можно только пересмотрев реализацию внешней компоненты.
1. Есть сомнения, что версия указанного исходного кода соответствует версии в используемой внешней компоненте.
2. В дампе внешняя компонента упоминается дважды.
Есть загруженная копия, с которой работает основной поток.
И есть уже выгруженная копия, от которой остались остатки обратного вызова.
Это говорит о том, что зависание происходит при повторном обращении к компоненте.

Если ситуация у вас не воспроизводится, то можно предложить следующий вариант действий - предоставить пользователю тестовую версию компоненты, в которой :
- либо попробовать заглушить вызов часть методов: через несколько попыток с разными вариантами это даст понимание, что было вызвано в предыдущем перед зависанием вызове.
- либо добавить отладочный вывод, например в файл
Кроме этого есть вариант с удалённой отладкой: https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging?view=vs-2019

Про инициализацию:
подозреваю, что если вернуть компоненту к исходному состоянию шаблона (с пустыми реализациями методов), то ситуация у пользователя не повторится.

Замечание по коду:
"нельзя выделять память для возврата значений с помощью new или malloc, т.к. это приведет к утечке памяти и к нестабильности работы программы"
( https://its.1c.ru/db/metod8dev#content:3221:hdoc )
----------------

По поводу
«нельзя выделять память для возврата значений с помощью new»
Во всех примерах внешних компонент https://infostart.ru/public/184119/ приводится функция
GetClassObject() с оператором new.
Отчаянно пытался найти ее пример без использования оператора new, но не смог.

Научите правильно писать внешнюю компоненту или доказать, что я не виноват.
   TormozIT
 
1 - 23.07.21 - 09:37
По совету более опытных людей
1. Добавил опцию компиляции /Zc:threadSafeInit-
2. Заменил формирование возвращаемой функцией GetClassNames() строки с динамически выделяемой convToShortWchar() на статически выделяемую
static WcharWrapper s_names(g_kClassNames);
   Kassern
 
2 - 23.07.21 - 09:43
(1) помогло?
   TormozIT
 
3 - 23.07.21 - 19:07
(2) Судя по сообщению от пользователя, не помогло.
   Кирпич
 
4 - 24.07.21 - 07:57
"GetClassObject() с оператором new. Отчаянно пытался найти ее пример без использования оператора new, но не смог"

И не надо ничего искать. Это правильно. 
Принцип такой: всё что ты создаешь и удаляешь сам, на это память выделяй сам и без менеджера памяти 1с.
Вся память, которая будет выделена в значениях 1С tVariant (строки и двоичные данные) для передачи в 1с, должна быть выделена менеджером памяти 1С. Ибо удалять эти значения будет 1с, а не ты.
Если ты создашь строку tVariant, выделишь под нее память не менеджером 1с и вернешь эту tVariant в 1с, то 1с когда нибудь е попытается удалить, а памяти, из которой сделана твоя tVariant уже не будет и будет глюк.

Но у тебя просто виснет. Может дело и не в памяти. А что ВК вообще делает?
   TormozIT
 
5 - 24.07.21 - 10:41
(4) Ну собрано уже много диагностической информации. Вроде уже и сама тех. поддержка 1С перестала давить на тему кривой реализации ВК.
Общие признаки зависаний такие:
1.    ОС Windows 7 x64. На Win10 не виснет.
2.    Нет зависимости от файлового или клиент-серверого режима. Виснет в обоих вариантах.
3.    На 8.3.17 не зависает. На 8.3.18 и на 8.3.19 зависает.

Вот как выглядит ожидание потоков

0:000> !locks

CritSec ntdll!LdrpLoaderLock+0 at 00000000774b80d8
WaiterWoken        No
LockCount          1
RecursionCount     1
OwningThread       6520
EntryCount         0
ContentionCount    f
*** Locked

CritSec +57e6488 at 00000000057e6488
WaiterWoken        No
LockCount          0
RecursionCount     1
OwningThread       5744
EntryCount         0
ContentionCount    0
*** Locked

*** WARNING: Unable to verify checksum for v8_BE9A_8.dll
CritSec v8_BE9A_8!GetClassNames+1c3b0 at 000007fecce5d4e0
WaiterWoken        No
LockCount          1
RecursionCount     1
OwningThread       5744
EntryCount         0
ContentionCount    1
*** Locked

Scanned 16879 critical sections

0:000> ~~[6520] k

# Child-SP          RetAddr           Call Site
00 00000000`6003f6a8 00000000`773c2b08 ntdll!ZwWaitForSingleObject+0xa
01 00000000`6003f6b0 00000000`773bd261 ntdll!RtlpWaitOnCriticalSection+0xe8
02 00000000`6003f760 000007fe`cce4afb8 ntdll!RtlEnterCriticalSection+0xd1
03 (Inline Function) --------`-------- v8_BE9A_8!__acrt_lock_and_call::__l3::<lambda_5e887d1dcbef67a5eb4283622ba103bf>::operator()+0x7 [d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h @ 879]
04 00000000`6003f790 000007fe`cce4b12b v8_BE9A_8!__crt_seh_guarded_call<void>::operator()<<lambda_5e887d1dcbef67a5eb4283622ba103bf>,<lambda_4466841279450cc726390878d4a41900> & __ptr64,<lambda_341c25c0346d94847f1f3c463c57e077> >+0x1c [d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h @ 216]
05 (Inline Function) --------`-------- v8_BE9A_8!__acrt_lock_and_call+0x8a [d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h @ 881]
06 (Inline Function) --------`-------- v8_BE9A_8!construct_ptd+0xba [d:\th\minkernel\crts\ucrt\src\appcrt\internal\per_thread_data.cpp @ 116]
07 00000000`6003f7c0 000007fe`cce4b3f7 v8_BE9A_8!construct_ptd_array+0xc7 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\per_thread_data.cpp @ 127]
08 (Inline Function) --------`-------- v8_BE9A_8!get_ptd_head+0x56 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\per_thread_data.cpp @ 234]
09 (Inline Function) --------`-------- v8_BE9A_8!internal_getptd_noexit+0x5c [d:\th\minkernel\crts\ucrt\src\appcrt\internal\per_thread_data.cpp @ 246]
0a 00000000`6003f820 000007fe`cce46381 v8_BE9A_8!__acrt_getptd_noexit+0x6b [d:\th\minkernel\crts\ucrt\src\appcrt\internal\per_thread_data.cpp @ 257]
0b 00000000`6003f850 000007fe`cce4246e v8_BE9A_8!__acrt_thread_attach+0x9 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\initialization.cpp @ 297]
0c 00000000`6003f880 000007fe`cce41c29 v8_BE9A_8!__scrt_dllmain_crt_thread_attach+0x16 [f:\dd\vctools\crt\vcstartup\src\utility\utility.cpp @ 438]
0d 00000000`6003f8b0 000007fe`cce41e59 v8_BE9A_8!dllmain_crt_dispatch+0x2d [f:\dd\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 135]
0e 00000000`6003f8e0 00000000`773c83cc v8_BE9A_8!dllmain_dispatch+0x5d [f:\dd\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 190]
0f 00000000`6003f940 00000000`773d36bf ntdll!LdrpInitializeThread+0x17c
10 00000000`6003fa40 00000000`773d373e ntdll!LdrpInitialize+0x9f
11 00000000`6003fab0 00000000`00000000 ntdll!LdrInitializeThunk+0xe

0:000> ~~[5744] k

# Child-SP          RetAddr           Call Site
00 00000000`0012a9c8 00000000`773c2b08 ntdll!ZwWaitForSingleObject+0xa
01 00000000`0012a9d0 00000000`773bd261 ntdll!RtlpWaitOnCriticalSection+0xe8
02 00000000`0012aa80 00000000`7748e207 ntdll!RtlEnterCriticalSection+0xd1
03 00000000`0012aab0 00000000`7747ad7d ntdll!LdrpLoadDll+0x2c7
04 00000000`0012acb0 000007fe`fd02b39a ntdll!LdrLoadDll+0xed
05 00000000`0012ad20 000007fe`cce4b6c2 KERNELBASE!LoadLibraryExW+0x2a3
06 (Inline Function) --------`-------- v8_BE9A_8!try_load_library_from_system_directory+0x11 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\winapi_thunks.cpp @ 205]
07 (Inline Function) --------`-------- v8_BE9A_8!try_get_module+0x30 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\winapi_thunks.cpp @ 239]
08 (Inline Function) --------`-------- v8_BE9A_8!try_get_first_available_module+0x39 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\winapi_thunks.cpp @ 272]
09 (Inline Function) --------`-------- v8_BE9A_8!try_get_proc_address_from_first_available_module+0x39 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\winapi_thunks.cpp @ 290]
0a 00000000`0012ada0 000007fe`cce4bdcb v8_BE9A_8!try_get_function+0xa2 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\winapi_thunks.cpp @ 327]
0b (Inline Function) --------`-------- v8_BE9A_8!try_get_CompareStringEx+0x1f [d:\th\minkernel\crts\ucrt\src\appcrt\internal\winapi_thunks.cpp @ 378]
0c 00000000`0012adf0 000007fe`cce44755 v8_BE9A_8!__acrt_can_use_vista_locale_apis+0x23 [d:\th\minkernel\crts\ucrt\src\appcrt\internal\winapi_thunks.cpp @ 771]
0d 00000000`0012ae20 000007fe`cce44ecc v8_BE9A_8!_expandlocale+0x16d [d:\th\minkernel\crts\ucrt\src\appcrt\locale\wsetlocale.cpp @ 872]
0e 00000000`0012b0b0 000007fe`cce44076 v8_BE9A_8!_wsetlocale_nolock+0x1fc [d:\th\minkernel\crts\ucrt\src\appcrt\locale\wsetlocale.cpp @ 563]
0f (Inline Function) --------`-------- v8_BE9A_8!_wsetlocale::__l22::<lambda_2af78c5f5901b1372d98f9ab3177dfa6>::()::__l39::<lambda_30712929f77e709619002f448b6a9510>::operator()+0x31 [d:\th\minkernel\crts\ucrt\src\appcrt\locale\wsetlocale.cpp @ 459]
10 00000000`0012b2f0 000007fe`cce441e7 v8_BE9A_8!__crt_seh_guarded_call<void>::operator()<<lambda_d67e8342c384adda8f857579ab50b2ae>,<lambda_30712929f77e709619002f448b6a9510> & __ptr64,<lambda_4525336fd7e478d965fb7ca7a337cad8> >+0x4e [d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h @ 219]
11 (Inline Function) --------`-------- v8_BE9A_8!__acrt_lock_and_call+0x4f [d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h @ 881]
12 00000000`0012b320 000007fe`cce44011 v8_BE9A_8!<lambda_2af78c5f5901b1372d98f9ab3177dfa6>::operator()+0x83 [d:\th\minkernel\crts\ucrt\src\appcrt\locale\wsetlocale.cpp @ 488]
13 00000000`0012b380 000007fe`cce44ade v8_BE9A_8!__crt_seh_guarded_call<void>::operator()<<lambda_5df02c53a8f32f81fd64e5bbb78039f1>,<lambda_2af78c5f5901b1372d98f9ab3177dfa6> & __ptr64,<lambda_f51fe5fd7c79a33db34fc9310f277369> & __ptr64>+0x15 [d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h @ 219]
14 (Inline Function) --------`-------- v8_BE9A_8!__crt_call_and_cleanup+0x4c [d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h @ 232]
15 00000000`0012b3b0 00000001`0e2c9bb1 v8_BE9A_8!_wsetlocale+0x92 [d:\th\minkernel\crts\ucrt\src\appcrt\locale\wsetlocale.cpp @ 491]
   TormozIT
 
6 - 24.07.21 - 10:43
(4) > что ВК вообще делает?
Виснет просто на создании ВК, т.е. до "делает" дело обычно даже не доходит.
   TormozIT
 
7 - 24.07.21 - 10:47
Тут видео пошаговой отладки http://devtool1c.ucoz.ru/_fr/19/2021-07-23_17-2.mp4
   TormozIT
 
8 - 24.07.21 - 10:54
(6) Извиняюсь. Виснет при подключении ВК, а не при создании.
   Kassern
 
9 - 24.07.21 - 11:22
(8) у меня то же была проблема с зависанием компоненты. Причем код был типовой от конфы. А проблема была в том что, когда 1ска закрылась как нить аварийно, то по порт не освобождался, при повторном подключении 1ска ждала ответа от оборудования, а у него порт уже был заблокирован, исключения не происходило и 1ска висела до победного. Если зайти в оборудование и открыть порты, то все нормально отрабатывало. Может и тут какая нибудь блокировка срабатывает а 1ске ответ не приходит.
   TormozIT
 
10 - 24.07.21 - 11:25
(9) Твой пример должен одинаково работать на всех версиях платформы. У меня же есть четкий переход
8.3.17 - не виснет
8.3.18 - виснет
   Kassern
 
11 - 24.07.21 - 11:37
(10) 8.3.19.1229  пробовали?
   TormozIT
 
12 - 24.07.21 - 11:38
(11) Да и на 8.3.20 такая же беда
   TormozIT
 
13 - 24.07.21 - 11:40
Видимо в 8.3.18 что то изменили в механизме загрузки/создания внешних компонент, что как то связано с поддержкой старых ОС.
   Kassern
 
14 - 24.07.21 - 11:41
(13) повод обновиться до 10ки) На серверных виндах нормально отрабатывает?
   TormozIT
 
15 - 24.07.21 - 11:44
(14) У платформы 8.3.18 заявлена поддержка Win7 и выше. Поэтому у своей программы я написал также. Пользователь запускает и моя программа зависает. Пользователь ругает меня.
   TormozIT
 
16 - 24.07.21 - 11:46
(15) Точнее Win Vista и выше. Но думаю вистой уже пользуется никто.
   Kassern
 
17 - 24.07.21 - 11:47
(15) такая же проблема была при обновлении платформы на win2003 серверной. У платформы заявлено, а кластер не поднимается, предыдущая версия без проблем встает. Через время вышла еще новее версия платформы и она чудом встала.
   Kassern
 
18 - 24.07.21 - 11:47
(17) так же писали в поддержку, может они и поправили в следующем релизе.
   H A D G E H O G s
 
19 - 24.07.21 - 14:43
В 8.3.18 для поддержки async/wait они перекрутили работу с функциями. Это видно хотя бы по выросшему потреблению стэка.
Пиши в 1С, пусть там кого нибудь предадут анафеме.
   Гений 1С
 
20 - 24.07.21 - 15:51
(0) перепиши на NET C# без ВК, Гггг, что ты как маленький. В топку эти 1с-ВК
   TormozIT
 
21 - 24.07.21 - 21:21
(20) Гениально!
   Гений 1С
 
22 - 24.07.21 - 22:31
(21) ндык, я так и сделал
   Кирпич
 
23 - 25.07.21 - 15:05
попробуй добавить CoInitialize и CoUninitialize прикрутить куда нибудь. В Init и Done например.
   acht
 
24 - 25.07.21 - 17:35
(23) > CoInitialize 
В нативной компоненте? Ну-ну.
   Кирпич
 
25 - 25.07.21 - 19:45
(24) Сам ты нуну. У него там ShellExecute используется.
   Кирпич
 
26 - 25.07.21 - 19:53
Remarks

Because ShellExecuteEx can delegate execution to Shell extensions (data sources, context menu handlers, verb implementations) that are activated using Component Object Model (COM), COM should be initialized before ShellExecuteEx is called. Some Shell extensions require the COM single-threaded apartment (STA) type. In that case, COM should be initialized as shown here:

CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)

https://docs.microsoft.com/ru-ru/windows/win32/api/shellapi/nf-shellapi-shellexecuteexa
   Garykom
 
27 - 26.07.21 - 10:33
(0) твоя ВК случайно другие DLL через LoadLibrary не грузит?
   TormozIT
 
28 - 26.07.21 - 11:36
(27) нет. Она мегапростая.
   Garykom
 
29 - 26.07.21 - 11:37
(28) тогда очень странно
можно попробовать пересобрать ВК на других (более старых) версиях VS и окружения
   Garykom
 
30 - 26.07.21 - 11:38
В саму 1С исходники ВК для ревью послать
 
 
   Garykom
 
31 - 26.07.21 - 11:39
(30) в смысле разработчикам платформы 1С, чтобы глянули почему может падать
   Garykom
 
32 - 26.07.21 - 11:40
(31)+ по идее если падает то это или в платформе баг или в ВК или хз
но возможность использования ВК декларирована в платформе 1С
если "не работает" то по линии ИТС к разрабам платформы 1С логично
   Кирпич
 
33 - 26.07.21 - 12:05
Другие ВК работают? Работают. Значит дело в самой ВК. Shellapi наиболее вероятный источник глюков. Ибо там com. Больше там ничего подозрительного нет. Отключить shellapi и смотреть.
   Garykom
 
34 - 26.07.21 - 12:49
(33) лично я уже давно понял что от засовывания всего унутрь ВК надо отказываться
ВК должна быть минималистичной и поднимать http сервис на указанном порту и как клиент выступать к внешнему сервису, который все и будет делать и обратные вызовы если что пашут

и можно несколько сеансов 1С (со своими ВК) на один внешний сервис
   Garykom
 
35 - 26.07.21 - 12:50
(34)+ и да понятно что ВК должна уметь при необходимости поднять этот внешний сервис, который и реализует нужный функционал
   Garykom
 
36 - 26.07.21 - 12:50
(35)+ хотя это не обязательно ибо обычно можно напрямую из 1С с клиента/сервера
   TormozIT
 
37 - 26.07.21 - 15:37
(30) Так они уже давно посмотрели. Еще в (0) про это писал - ищи слова "Замечание по коду".
   Garykom
 
38 - 26.07.21 - 15:42
(37) "Замечание по коду:
"нельзя выделять память для возврата значений с помощью new или malloc, т.к. это приведет к утечке памяти и к нестабильности работы программы""

так эта проблема в коде исправлена?
   Garykom
 
39 - 26.07.21 - 15:43
Короче сделай как у меня - раздели ВК на две части и все
Внутри ВК надо чтобы падать было нечему, а внешняя хрень пусть хоть западается, главное чтобы перезапускалась
   TormozIT
 
40 - 26.07.21 - 15:56
(38) Конечно


Список тем форума
 
Прочитай, хотя бы, Митичкина "Разработка в системе 1С:Предприятие 8". Волшебник
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.