Вверх ↑
Ответов: 3889
Рейтинг: 362
#1: 2011-06-29 11:04:17 ЛС | профиль | цитата
nesco писал(а):
А что творится при вынесении переменной в область глобальных переменных класса

Вынес. Это замаскировало баг в менеджере памяти для hiWinExec. Теперь вылетает в разных местах менеджер памяти для hiCharset Первый же вылет сразу изобличает неисправность именно механизмов операций с памятью: строка 121, GetMem(buffer, 2*BufLen);
Что-то мне подсказывает, что после маскировки уязвимых мест и тут, они обнаружатся и в hiStrList. И так - во всех компонентах, неявно использующих динамическое выделение памяти в этом "несчастливом" потоке. Переделывать все компоненты - нонсенс. Менеджер памяти тоже вряд ли кто-то будет исправлять, так что...

------------ Дoбавленo в 08.42:
Что интересно, если заменить в схеме WinExec на что-нибудь, вылеты в Charset прекращаются. То есть цепная реакция начинается именно с него. Что-то в нём портит структуру данных менеджера динамической памяти и дальше любая операция по удалению или выделению ячеек в контексте этого же потока приводит к фатальным ошибкам. Если же давать ему больше времени на исполнение вызванного приложения, то выполняется меньше его экземпляров и вероятность вылета обратно пропорциональна длине периода и производительности компьютера.

Было подозрение, что более одного потока вызывают гарантированный сбой уже в самом начале отработки WinExec, при сокращении периода вызова до 200 мсек, потоков бывало более 50, пока не начинало вылетать. А при большем периоде иногда вылетает уже на 3-м. То есть какой-то этап WinExec гарантированно портит структуры менеджера памяти. При меньшем периоде успевает запуститься больше потоков, пока не доходит до этого этапа. При большем периоде до него доходит уже на первых нескольких. При одном потоке он сам себе не враг, так что до порчи памяти вообще не доходит. Что это за этап можно догадаться по тому, что один единственный tasklist в менеджере процессов зависает навечно, в гордом одиночестве. Программа падает, он так и останется невидимо висеть (ибо вывод его направлен был в поток нашего приложения). Если заменить его на несуществующую консольную команду, то всё равно вылетает, но ничего висеть не остаётся. WinExec с пустым полем FileName отрабатывает очень быстро и, естественно, не вылетает.
------------ Дoбавленo в 11.04:
Есть мнение, что tasklist остаётся висеть потому, что не успел до конца отдать свой консольный вывод т.к. вызвавший его поток с WinExec вылетает раньше.
карма: 1

0