OpenMutex in Windows 7 vs 10
От: CyberDemon Россия  
Дата: 02.03.18 13:21
Оценка:
Долго ковырял косячину и, вроде бы, решил вопрос. Но костылем. Хотелось бы понять, как теперь жить

Имеем процесс, стартующий as admin и делающий следующее:

mutex = CreateMutex(NULL, TRUE, name);
// some processing
ReleaseMutex(mutex);


И процесс, стартующий после первого все равно как (обычный юзер или as admin):
mutex = OpenMutex(SYNCHRONIZE | MUTANT_QUERY_STATE, FALSE, name);
//...
DWORD res = WaitForSingleObject(mutex, INFINITE);
//...
ReleaseMutex(mutex)


Все работает отлично в Windows 10, 7 (у себя проверял). Но вдруг начали появляться юзеры с проблемами в 7.
Выяснил, что во втором процессе Wait вешается навечно. То есть, mutex открыт, ошибок нет, но залочить его не можем.
Костыль выглядит так:
// if Windows 7
mutex = CreateMutex(NULL, FALSE, name);


Я что-то где-то не так сделал или что?
Re: OpenMutex in Windows 7 vs 10
От: okman Беларусь https://searchinform.ru/
Дата: 02.03.18 14:46
Оценка: 4 (1)
Здравствуйте, CyberDemon, Вы писали:

CD>...

CD>Я что-то где-то не так сделал или что?

Проверка ошибок везде есть? Т.е. что CreateMutex и OpenMutex возвращают не NULL

Проверяется ли после успешного CreateMutex, что это создание нового мьютекса, а
не открытие уже существующего (т.е. что GetLastError() != ERROR_ALREADY_EXISTS)?

Если это открытие, то ReleaseMutex делать нельзя, т.к. не мы его захватили.
Т.е. более точная последовательность действий примерно такая:

Вызываем CreateMutex с флагом bInitialOwner = TRUE.
Если успех, вызываем GetLastError(). Если там ERROR_ALREADY_EXISTS, значит,
мьютекс уже существует, надо делать WaitForSingleObject и ждать, пока
он освободится. И только когда освободится, можно выполнять свою работу и
потом освобождать его через ReleaseMutex.

Второе приложение делает примерно то же самое, только у него OpenMutex
вместо CreateMutex (хотя на самом деле CreateMutex можно и там, и там).
Re[2]: OpenMutex in Windows 7 vs 10
От: CyberDemon Россия  
Дата: 02.03.18 15:47
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, CyberDemon, Вы писали:


CD>>...

CD>>Я что-то где-то не так сделал или что?

O>Проверка ошибок везде есть? Т.е. что CreateMutex и OpenMutex возвращают не NULL


Да, конечно, это все проверяется. И перед Wait на NULL тоже проверка есть.

O>Проверяется ли после успешного CreateMutex, что это создание нового мьютекса, а

O>не открытие уже существующего (т.е. что GetLastError() != ERROR_ALREADY_EXISTS)?

O>Если это открытие, то ReleaseMutex делать нельзя, т.к. не мы его захватили.

O>Т.е. более точная последовательность действий примерно такая:

Основное приложение (которое админ) первое создает mutex, его в системе быть не может.

O>Вызываем CreateMutex с флагом bInitialOwner = TRUE.

O>Если успех, вызываем GetLastError(). Если там ERROR_ALREADY_EXISTS, значит,
O>мьютекс уже существует, надо делать WaitForSingleObject и ждать, пока
O>он освободится. И только когда освободится, можно выполнять свою работу и
O>потом освобождать его через ReleaseMutex.

Хотя и нереальная ситуация, но я таки попробую.
Re[2]: OpenMutex in Windows 7 vs 10
От: CyberDemon Россия  
Дата: 02.03.18 15:52
Оценка:
Здравствуйте, okman, Вы писали:

Еще раз перечитал свое первое сообщение и понял, что, возможно, я немного криво написал про костыль.
CreateMutex без InitialOwner = FALSE я делаю во втором процессе. А первый все так же с TRUE.
То есть, CreateMutex вместо OpenMutex — это и есть костыль.
Re[3]: OpenMutex in Windows 7 vs 10
От: IID Россия  
Дата: 05.03.18 13:27
Оценка:
Здравствуйте, CyberDemon, Вы писали:

CD>Основное приложение (которое админ) первое создает mutex, его в системе быть не может.


основное приложение могло не запуститься или сдохнуть (или закрыть мьютекс)
kalsarikännit
Re[4]: OpenMutex in Windows 7 vs 10
От: CyberDemon Россия  
Дата: 05.03.18 13:41
Оценка:
Здравствуйте, IID, Вы писали:

IID>основное приложение могло не запуститься или сдохнуть (или закрыть мьютекс)

Если не запустится основное, не запустится и "клиент". Специфика.
Закрыть раньше времени оно его не может. Это точно.
Сдохнуть может, но это уже другой вопрос и эта ситуация, очевидно, легко наблюдается.
Re: OpenMutex in Windows 7 vs 10
От: Alexander G Украина  
Дата: 29.03.18 12:58
Оценка:
Здравствуйте, CyberDemon, Вы писали:

CD>Я что-то где-то не так сделал или что?


Можно попросить пользователя сдампать оба процесса.
(Это может таск менеджер, который по Ctrl+Shift+ESC, или Ctr+Alt+Del -> Task Manager. Если включён UAC, то чтобы добраться до адмиских процессов, нажать там Show All Processes)

Затем оба дампа открыть в WinDbg и вызвать
!handle 0 0xf Mutant

Напишет все хендлы мьютексов, с подробной информацией, можно будет проверить:
* Тот же самый ли мьютекс в разных процессах
* Занят ли мьютекс или свободен
* Если мьютекс занят, то кем (вдруг Mutant Owner — третий процесс, например, другая копия пользовательского процесса)

Из тех же дампов по !analyze -v
* По колл стеку понять, действительно ли пользовательский процесс ждёт
* По колл стеку понять, действительно ли сервис прошел свой ReleaseMutex
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.