- PVSM.RU - https://www.pvsm.ru -

Как ошибка из 2009 вызывает конфликт Docker for Windows и Razer Synapse

Сегодня мне попался весьма любопытный баг: Docker for Windows не запустится, если у вас запущена панель управления драйвером Razer Synapse.

Но интереснее всего то, почему так случилось…

Как ошибка из 2009 вызывает конфликт Docker for Windows и Razer Synapse - 1

Оба приложения написаны так, что можно одновременно запустить только один экземпляр. Для этого они создают глобальный мьютекс, используя в качестве ключа GUID сборки .NET, да?

Но увы, они делают это неправильно, и более того — одинаково неправильно. Ошибочный код выглядит примерно так:

string.Format("Global{0}", (object) Assembly.GetExecutingAssembly().GetType().GUID);

Идея заключается в том, чтобы получить GUID исполняемой сборки и создать на его основе мьютекс, который не даст запустить больше одного экземпляра.

Но должно быть не так. Там не должно быть вызова GetType().

В этом варианте возвращается не GUID конкретной сборки, а GUID встроенного в .NET типа, который описывает сборки как таковые — System.Reflection.RuntimeAssembly.

Поэтому, когда они создают мьютексы, они используют не GUID из их собственного кода, а GUID из внутренностей .NET. И для обоих приложений этот GUID будет одинаковым.

Как же это случилось? Забавно, но мы в точности знаем, как. Всему виной Stackoverflow!

Еще в 2009 году пользователь c ником Nathan задал вопрос — "как получить GUID выполняемой сборки? [1]". Через 12 минут ему ответил пользователь Cerebrus, но в его ответе была ошибка.

Спустя год и месяц, пользователь Yoopergeek указывает на ошибку. Cerebrus возвращается спустя еще три года и исправляет свой ответ — но удалить его уже нельзя, потому что ответ был помечен как «принятый».

Таким образом, ошибка в ответе на вопрос в 2009 году вызывала баг, просуществовавший как минимум до марта 2018.

Домашнее задание для всех программистов, читающих данный пост: подумайте, как бы вы обнаружили такой баг в своем приложении? Вы копипастите код, он вроде работает, но вы даже не догадываетесь, что на самом деле он сломан: вы же не запускаете две программы с одинаковой ошибкой одновременно. О проблеме вам станет известно, только когда пользователи начнут жаловаться.

Как можно было бы поменять процесс разработки, чтобы обнаруживать подобные ошибки до релиза?

Автор: Андрей

Источник [2]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/347045

Ссылки в тексте:

[1] как получить GUID выполняемой сборки?: https://stackoverflow.com/questions/502303/how-do-i-programmatically-get-the-guid-of-an-application-in-net2-0

[2] Источник: https://habr.com/ru/post/488834/?utm_source=habrahabr&utm_medium=rss&utm_campaign=488834