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

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

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



Оба приложения написаны так, что можно одновременно запустить только один экземпляр. Для этого они создают глобальный мьютекс, используя в качестве ключа 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 выполняемой сборки?". Через 12 минут ему ответил пользователь Cerebrus, но в его ответе была ошибка.

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

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

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

Как можно было бы поменять процесс разработки, чтобы обнаруживать подобные ошибки до релиза?
Источник: https://habr.com/ru/post/488834/


Интересные статьи

Интересные статьи

В этой серии статей мы подробно рассмотрим, почему и как недавно были внесены изменения в наши Условия обслуживания. Эта статья подробно опишет политику хранения неактивных образов,...
Задавались ли вы когда-нибудь вопросом о том, почему размер Docker-контейнера, содержащего всего одно приложение, может находиться в районе 400 Гб? Или, может быть, вас беспокоили немаленькие раз...
Ещё не успела отшуметь уязвимость BlueKeep (CVE-2019-0708) для старых версий ОС Windows, нацеленная на реализацию протокола RDP, как снова пора ставить патчи. Теперь в зону поражения попали всё н...
Мы рады рассказать, что теперь вы можете попробовать Windows Subsystem for Linux 2 установив Windows build 18917 в Insider Fast ring! В этой статье мы расскажем о том, как начать работу, о новых ...
Всем привет! Ооочень хочется прям сразу приступить к теме, но правильнее будет немного рассказать про мою историю: Вступление Я программист с опытом разработки frontend одностраничных приложен...