секунда WTF (lock)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.01.17 20:02
Оценка:
Всем привет. Думаю, что на минутку не тянет, потому секунда.

namespace System.Threading
{
    static class Monitor
    {
        public static void Enter(object obj, ref bool locked)
        {
            Console.WriteLine("Enter");
        }
        public static void Exit(object obj)
        {
            Console.WriteLine("Exit");
        }
    }
}

namespace MonitorEnterTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var syncRoot = new object();
            lock (syncRoot)
            {

            }

            Console.WriteLine("Press any key!!!");
            Console.ReadKey();
        }
    }
}


Вопросы:
* что должно быть напечатано в консоли по теории?
* у кого что на практике?

З.Ы. на моей машине и на ideone результаты отличаются. Я бы не писал, если бы результат был стабилен и совпадал с аналогичным много лет назад (может быть около 10и) с поправкой на изменившуюся сигнатуру Enter(object, bool&).

З.Ы.2 Правильные ответы не знаю.
Отредактировано 30.01.2017 18:40 AndrewVK . Предыдущая версия .
async
Re: секунда WTF (lock)
От: Слава  
Дата: 27.01.17 21:01
Оценка:
Здравствуйте, samius, Вы писали:

S>Всем привет. Думаю, что на минутку не тянет, потому секунда.


S>З.Ы.2 Правильные ответы не знаю.


А где вызовы-то?
Re: секунда WTF (lock)
От: fddima  
Дата: 27.01.17 21:16
Оценка: 22 (2) +1
Здравствуйте, samius, Вы писали:

S>* что должно быть напечатано в консоли по теории?

S>* у кого что на практике?
А х.з. что там в теории.
Учитывая что в C# компиляторе очень любят позднее связывание, то твои собственные Enter/Exit должны быть вызваны.
Ну понятно, что если взять код как есть — то только Enter (т.к. enter не устанавливает locked = true).
[OFF] А какие возможности-то открываются :)
От: fddima  
Дата: 27.01.17 21:31
Оценка: 15 (2)
Здравствуйте, fddima, Вы писали:

Собственно на основе этого можно poor-man's lock logger прикрутить (естественно для текущей сборки).
Хотя я как бы и знал о возможности делать подобные извраты — никогда не делал.

1. Прийдется добавить в файл проекта ручками — студия зачем-то заботливо нас от этого огораживает:
    <Reference Include="mscorlib">
      <Aliases>global,mscorlib</Aliases>
    </Reference>


2.
extern alias mscorlib;
using System;

namespace System.Threading
{
    static class Monitor
    {
        public static void Enter(object obj, ref bool locked)
        {
            Console.WriteLine("Enter");
            mscorlib::System.Threading.Monitor.Enter(obj, ref locked);
        }
        public static void Exit(object obj)
        {
            mscorlib::System.Threading.Monitor.Exit(obj);
            Console.WriteLine("Exit");
        }
    }
}

namespace MonitorEnterTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var syncRoot = new object();
            lock (syncRoot)
            {

            }

            Console.WriteLine("Press any key!!!");
            Console.ReadKey();
        }
    }
}


PS: VS2015U3

UPD: Ну вариант с "happy debug" предложенный практически изначально — я промолчу.
Отредактировано 27.01.2017 21:34 Mystic Artifact . Предыдущая версия . Еще …
Отредактировано 27.01.2017 21:32 Mystic Artifact . Предыдущая версия .
Отредактировано 27.01.2017 21:31 Mystic Artifact . Предыдущая версия .
Re[2]: секунда WTF (lock)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.01.17 04:01
Оценка:
Здравствуйте, Слава, Вы писали:

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


С>А где вызовы-то?

Вызовы подставляет компилятор
Re[2]: секунда WTF (lock)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.01.17 04:03
Оценка:
Здравствуйте, fddima, Вы писали:

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


S>>* что должно быть напечатано в консоли по теории?

S>>* у кого что на практике?
F> А х.з. что там в теории.
F> Учитывая что в C# компиляторе очень любят позднее связывание, то твои собственные Enter/Exit должны быть вызваны.
Да, была на это надежда. Но ideone не пишет даже "Enter"

F> Ну понятно, что если взять код как есть — то только Enter (т.к. enter не устанавливает locked = true).

Ох, забыл я ночью его повернуть-то. Да, с ним теперь и "Exit" увидел. Благодарю.
Re: [OFF] А какие возможности-то открываются :)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.01.17 04:16
Оценка: 16 (1)
Здравствуйте, fddima, Вы писали:

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


F>Собственно на основе этого можно poor-man's lock logger прикрутить (естественно для текущей сборки).

F>Хотя я как бы и знал о возможности делать подобные извраты — никогда не делал.

F>1. Прийдется добавить в файл проекта ручками — студия зачем-то заботливо нас от этого огораживает:

F>
F>    <Reference Include="mscorlib">
F>      <Aliases>global,mscorlib</Aliases>
F>    </Reference>
F>


F>2.

F>[c#]
F>extern alias mscorlib;
F>using System;

F>namespace System.Threading

F>{
F> static class Monitor
F> {
F> public static void Enter(object obj, ref bool locked)
F> {
F> Console.WriteLine("Enter");
F> mscorlib::System.Threading.Monitor.Enter(obj, ref locked);
F> }
F> public static void Exit(object obj)
F> {
F> mscorlib::System.Threading.Monitor.Exit(obj);
F> Console.WriteLine("Exit");
F> }
F> }
F>}
Да, именно так и предполагалось использовать, только не для логов, а для рантайм проверки возможности дедлоков. (и даже больше, доказывания отсутствия возможности таковых при очередном захвате).
Из-за нестабильности эффекта вместо lock-а пришлось перейти на using, и все было ничего, пока компилятор не разрешил внутрь using-а вставлять await-ы. Теперь пришлось доказывать еще что из using-а выходит именно тот поток, что входил.

F>PS: VS2015U3

Аналогично

F>UPD: Ну вариант с "happy debug" предложенный практически изначально — я промолчу.

В заглавном сообщении меня интересовал именно факт вызова моих методов из под штатного lock-а. Понятно что без mscorlib или своего аналога это злая засада.
Re: секунда WTF (lock)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.01.17 04:24
Оценка:
Здравствуйте, samius, Вы писали:

S>З.Ы. на моей машине и на ideone результаты отличаются.


http://ideone.com/tR2ntD

Не заходит в мой Enter
Re[2]: секунда WTF (lock)
От: Sinix  
Дата: 28.01.17 07:07
Оценка: +1
Здравствуйте, samius, Вы писали:

S>http://ideone.com/tR2ntD


S>Не заходит в мой Enter

Потому что mono compiler. Стандартный enter вызывается.

Как по мне, это не WTF, а instant karma: использовал недокументированное поведение — вот тебе недокументированное поведение
Re[2]: секунда WTF (lock)
От: Sinix  
Дата: 28.01.17 07:13
Оценка: 15 (3)
Здравствуйте, fddima, Вы писали:

FF> Учитывая что в C# компиляторе очень любят позднее связывание, то твои собственные Enter/Exit должны быть вызваны.


Для таких вещей рекомендую tryroslyn. Местный класс вызывается, без [mscorlib].
Re[3]: секунда WTF (lock)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.01.17 08:15
Оценка:
Здравствуйте, Sinix, Вы писали:

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


S>>http://ideone.com/tR2ntD


S>>Не заходит в мой Enter

S>Потому что mono compiler. Стандартный enter вызывается.

S>Как по мне, это не WTF, а instant karma: использовал недокументированное поведение — вот тебе недокументированное поведение

Я не от хорошей жизни и нечего делать такое пытаюсь использовать. А от того, что у lock-а нет никаких инструментов для того что бы не наступить на помидоры. Скоро уж 20 лет как.
Re[4]: секунда WTF (lock)
От: Sinix  
Дата: 28.01.17 08:47
Оценка:
Здравствуйте, samius, Вы писали:

S>>Как по мне, это не WTF, а instant karma: использовал недокументированное поведение — вот тебе недокументированное поведение

S>Я не от хорошей жизни и нечего делать такое пытаюсь использовать. А от того, что у lock-а нет никаких инструментов для того что бы не наступить на помидоры. Скоро уж 20 лет как.

Да ладно? Сначала матчасть, затем на бгоневичнок. Порядок важен

Другое дело, что никакие инструменты не спасут, если целенаправленно пишется код, потенциально приводящий к дедлокам. Надо подход менять. В идеале — cps-style на await, на крайний случай — чужой опыт хождения по граблям.
Re[5]: секунда WTF (lock)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.01.17 09:01
Оценка: 8 (1)
Здравствуйте, Sinix, Вы писали:

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


S>>>Как по мне, это не WTF, а instant karma: использовал недокументированное поведение — вот тебе недокументированное поведение

S>>Я не от хорошей жизни и нечего делать такое пытаюсь использовать. А от того, что у lock-а нет никаких инструментов для того что бы не наступить на помидоры. Скоро уж 20 лет как.

S>Да ладно? Сначала матчасть, затем на бгоневичнок. Порядок важен

Этот инструмент не покажет потенциальный дедлок, а покажет только случившийся и пойманный на машине разработчика. Т.е. когда уже помидоры в смятку.

S>Другое дело, что никакие инструменты не спасут, если целенаправленно пишется код, потенциально приводящий к дедлокам. Надо подход менять. В идеале — cps-style на await, на крайний случай — чужой опыт хождения по граблям.

Да, я использую level-ы синкрутов, как по первой ссылке. Но даже при этом контроль времени выполнения при попытке захвата в неверном порядке не помешает. ИМХО. Уже на стадии прогона тестов я знаю что дедлока не будет.
И представь, я не занимаюсь целенаправленным достижением дедлоков, но контроль срабатывает довольно часто.
Re[3]: секунда WTF (lock)
От: Слава  
Дата: 28.01.17 09:35
Оценка:
Здравствуйте, samius, Вы писали:

С>>А где вызовы-то?

S>Вызовы подставляет компилятор

Как-то это не гарантировано.
Re[3]: секунда WTF (lock)
От: fddima  
Дата: 28.01.17 14:26
Оценка:
Здравствуйте, samius, Вы писали:

F>> Учитывая что в C# компиляторе очень любят позднее связывание, то твои собственные Enter/Exit должны быть вызваны.

S>Да, была на это надежда. Но ideone не пишет даже "Enter"
На ideone — mono небось? Если так — то, имхо, это косяк в mcs и ориентироваться следует на рослин.
Re[6]: секунда WTF (lock)
От: Sinix  
Дата: 28.01.17 14:33
Оценка: 8 (1) +1
Здравствуйте, samius, Вы писали:


S>>Да ладно? Сначала матчасть, затем на бгоневичнок. Порядок важен

S>Этот инструмент не покажет потенциальный дедлок, а покажет только случившийся и пойманный на машине разработчика. Т.е. когда уже помидоры в смятку.
А, это тоже есть. Было, в смысле. Typemock Racer, CHESS, Jinx — их популярность как бы намекает на актуальность проблемы и эффективность инструментов. Серьёзно, написать корректно сразу — на порядки выгодней, чем надеяться поймать гейзенбаги тестированием.


S>Да, я использую level-ы синкрутов, как по первой ссылке. Но даже при этом контроль времени выполнения при попытке захвата в неверном порядке не помешает. ИМХО. Уже на стадии прогона тестов я знаю что дедлока не будет.

Неа. Ты знаешь, что дедлок не воспроизводится с некоторой вероятностью, не больше того. С учётом того, что дедлоки уже ловились раньше, как ты пишешь — не самая обнадёживающая информация

Вероятность конечно можно повысить — собирать зависимые локи (один lock берётся внутри другого) за всё время выполнения процесса и искать петли в графе зависимостей. К сожалению, это не спасёт от десятков прочих ошибок типа неявного разделяемого состояния, обращения к ресурсу вне локов, использования thread-local-переменных или блокировок вперемешку с async. Выгодней сразу свести разделяемое состояние к минимуму и по минимуму же использовать примитивы синхронизации. Меньше мест, где можно ошибиться — меньше ошибок — профит.

Ну и перехватывать локи, разумеется не через хак с компилятором, а с Fody/PostSharp. И не только Monitor.*, но и спинлоки, wait handles и тыды. Надёжней будет. Собственно, уже.

S>И представь, я не занимаюсь целенаправленным достижением дедлоков, но контроль срабатывает довольно часто.

Ну, бардак в проекте, без обид. Я за 10 лет сталкивался с неожиданными дедлоками ровно два раза. Оба раза товарищ разработчик считал, что большие красные буквы в мануале — это не для него.
Re[7]: секунда WTF (lock)
От: fddima  
Дата: 28.01.17 15:20
Оценка: 9 (2) +1
Здравствуйте, Sinix, Вы писали:

S>Ну и перехватывать локи, разумеется не через хак с компилятором, а с Fody/PostSharp. И не только Monitor.*, но и спинлоки, wait handles и тыды. Надёжней будет. Собственно, уже.

Я в целом согласен, что PostSharp — более универсальное решение, которое не должно быть подвержено флюктуациям компилятора. Зато потенциально может страдать кучей других проблем связанных с переписыванием кода.

Но и назвать это хаком — не могу. Компилятор ведь не работает с какой-то конкретной версией mscorlib, а то и сам mscorlib компилирует => ему не на что опираться. Я впервые подобное с удивлением обнаружил в Nemerle. Оказывается — повсеместная практика.
Ну и для полноты картины: WellKnownMember-ы.
Re[8]: секунда WTF (lock)
От: Sinix  
Дата: 28.01.17 15:36
Оценка: +1
Здравствуйте, fddima, Вы писали:

F> Я в целом согласен, что PostSharp — более универсальное решение, которое не должно быть подвержено флюктуациям компилятора. Зато потенциально может страдать кучей других проблем связанных с переписыванием кода.


Ну так чисто для тестирования, в продакшн такое выпускать — мазохистов нет


F> Но и назвать это хаком — не могу.

Именно что хак, контракт не зафиксирован и меняется от редакции к редакции. В отличие от linq, AsyncTaskMethodBuilder или .GetEnumerator().


F> Ну и для полноты картины: WellKnownMember-ы.

Там не всё. Expression tree нет, Array.Create (или как там его) нет, Formattable нет, Dictionary нет, String.Concat нет, StructLayout нет. Это первое вспомнившееся.
Re[9]: секунда WTF (lock)
От: fddima  
Дата: 28.01.17 16:20
Оценка: 51 (2)
Здравствуйте, Sinix, Вы писали:

F>> Ну и для полноты картины: WellKnownMember-ы.

S>Там не всё. Expression tree нет, Array.Create (или как там его) нет, Formattable нет, Dictionary нет, String.Concat нет, StructLayout нет. Это первое вспомнившееся.
StructLayoutAttribute — это тип, и он соответственно в WellKnownTypes.
Есть ещё SpecialType и SpecialMember. Вот вокруг них как раз почудить не выйдет.

PS: А Dictionary — зачем там?
Отредактировано 28.01.2017 16:21 Mystic Artifact . Предыдущая версия .
Re[10]: секунда WTF (lock)
От: Sinix  
Дата: 28.01.17 16:26
Оценка: 14 (2)
Здравствуйте, fddima, Вы писали:

F> PS: А Dictionary — зачем там?

http://stackoverflow.com/questions/3366376/are-net-switch-statements-hashed-or-indexed
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.