Задача: есть поток1 и поток2, которые работают по следующей схеме: ...есть переменная Ready=0 ...поток1 стартует поток2 и засыпает пока Ready не будет 1 ...поток2 нормально работает, инициализирует некоторую крит. секцию, после инициализации делает Ready=1 ...поток2 крутится в вечном цикле, каждая итерация которого обёрнута в EnterCriticalSection+LeaveCriticalSection ...вдруг поток1 просыпается (т.к Ready=1) и вызывает свою процедуру, обёрнутую в EnterCriticalSection+LeaveCriticalSection с той же к/с, что и поток2 ...поток2 на очередном витке цикла пытается сделать EnterCriticalSection и умирает (этого быть не должно). Описание ошибки: Access Violation: Write on Address 00000000. GetLastError и try+except не работают, т.к. Винда СРАЗУ ЖЕ убивает приложение без вопросов. Попытался логировать события (записывал содержимое структуры RTL_CRITICAL_SECTION): Код (Text): 9:19:29 ... before enter: DebugInfo = 14C250 LockCount = -1 RecursionCount = 0 OwningThread = 0 LockSemaphore = 0 Reserved = 0 9:19:29 ... after enter : DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 0 Reserved = 0 9:19:29 ... before leave: DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 0 Reserved = 0 9:19:29 ... after leave : DebugInfo = 14C250 LockCount = -1 RecursionCount = 0 OwningThread = 0 LockSemaphore = 0 Reserved = 0 9:19:29 ... before enter: DebugInfo = 14C250 LockCount = -1 RecursionCount = 0 OwningThread = 0 LockSemaphore = 0 Reserved = 0 9:19:29 ... after enter : DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 0 Reserved = 0 9:19:29 ... before leave: DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 0 Reserved = 0 9:19:29 ... after leave : DebugInfo = 14C250 LockCount = -1 RecursionCount = 0 OwningThread = 0 LockSemaphore = 0 Reserved = 0 9:19:29 ... before enter: DebugInfo = 14C250 LockCount = -1 RecursionCount = 0 OwningThread = 0 LockSemaphore = 0 Reserved = 0 9:19:29 ... after enter : DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 0 Reserved = 0 9:19:29 ... before leave: DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 0 Reserved = 0 9:19:29 ... after leave : DebugInfo = 14C250 LockCount = -1 RecursionCount = 0 OwningThread = 0 LockSemaphore = 0 Reserved = 0 9:19:29 ... before enter: DebugInfo = 14C250 LockCount = -1 RecursionCount = 0 OwningThread = 0 LockSemaphore = 0 Reserved = 0 9:19:29 ... after enter : DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 0 Reserved = 0 9:19:29 ... before enter: DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 0 Reserved = 0 9:19:29 ... before leave: DebugInfo = 14C250 LockCount = 1 RecursionCount = 1 OwningThread = 5A4 LockSemaphore = 764 Reserved = 0 9:19:29 ... after enter : DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = AA0 LockSemaphore = 764 Reserved = 0 9:19:29 ... after leave : DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = AA0 LockSemaphore = 764 Reserved = 0 9:19:29 ... before enter: DebugInfo = 14C250 LockCount = 0 RecursionCount = 1 OwningThread = AA0 LockSemaphore = 764 Reserved = 0 (before enter и after enter - вызываются соответственно перед и после EnterCriticalSection, before leave и after leave - аналогично для LeaveCriticalSection). Видно, что поток1 ещё не вышел из к/с, как в неё попытался зайти поток2. before enter поток2 вызвал, а вот after enter - уже нет (приложение завершилось). Вопрос1: почему поток2 вместо ожидания умирает? Вопрос2: чем это лечится?
Мало поможет, т.к.: 1) Delphi 2) кода много В общем можно смотреть схему работы и лог в посте №#1. Ответы на основные возможные вопросы: ...InitializeCriticalSection делаю 1 раз (на старте 2го потока, первый в это время спит). ...Все вызовы EnterCriticalSection и LeaveCriticalSection парные - пока 1ый поток не войдёт в к/с, всё просто супер. ...Оба потока в одном процессе =). ...Ни один из потоков не может войти в к/с 2 раза подряд. ...Других синхронизирующих примитивов / общих переменных у них нет. З.Ы.: если что - смотрите исходники, но я думаю, что это не метод...
LordBublicXIII Скорее всего умирает основной поток, поскольку в dpr нет try\except (что весьма странно, т.к. в вызываемых функциях LoadResource и Resources[0]=GetRes предусмотрена генерация исключений). Копаться в этой "корявой путаннице" лень, но похоже у тебя просто Path не инициализирована - вот на LoadResource или Resources[0] и валится PS: нафига выносить инициализацию в отд.модуль, чтобы потом забыть ее вызвать ?!
leo, спасибо что дал мне пинка под зад! Я нашёл косяк - в LoadResource вместо Код (Text): if l < idx then надо было поставить Код (Text): if l <= idx then (иначе при первом же обращении получается выход за границы массива). Вся фишка была в том, что Delphi при отладке многопоточного приложения многократно кидала меня из потока в поток, а ошибка вылетела не в том потоке, который реально вызвал ошибку, а в том, который в этот момент пытался в лезть в крит. секцию. Прошу прощения, господа, что отнял ваше драгоценное время по своей тупости. Если модерам не сложно, тему можно удалить ФПЕНЬ!
LordBublicXIII Не поленился пройтись отладчиком. Так и есть - элементарная ошибка в LoadResource: Код (Text): l := Length(ResList); if l < idx then //!!! должно быть <=, иначе ResList = Nil и кранты :) PS: Прежде чем строить хитроумные версии, нужно элементарно пройтись отладчиком и посмотреть где валится... PS: Эх, не успел...
LordBublicXIII В сообщении об ошибке указывается ее адрес - запускаешь прогу заново, переходишь по этому адресу и смотришь в чем м.б. дело