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

в 8:36, , рубрики: .net, ASP, stackoverflow, баг, копипаста, ненормальное программирование, Программирование

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

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

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

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

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

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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js