Есть определенная библиотека с большим количеством классов, которая используется в большом проекте в большом числе многих разных мест. Исходного кода библиотеки нет, а для проекта есть.
Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного.
Как это сделать с минимальным количеством гемора, есть идеи?
Здравствуйте, Codealot, Вы писали:
C>Есть определенная библиотека с большим количеством классов, которая используется в большом проекте в большом числе многих разных мест. Исходного кода библиотеки нет, а для проекта есть. C>Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного. C>Как это сделать с минимальным количеством гемора, есть идеи?
С минимальным — не знаю, но есть геморрный путь.
Главный поток и только его пометить ThreadStatic меткой. В каждом методе, обращающимся к коду библиотеки, на входе сделать проверку метки. И за каждым await, если он есть. Task.ContinueWith аналогично.
Здравствуйте, Codealot, Вы писали:
C>Есть определенная библиотека с большим количеством классов, которая используется в большом проекте в большом числе многих разных мест. Исходного кода библиотеки нет, а для проекта есть. C>Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного.
C>Как это сделать с минимальным количеством гемора, есть идеи?
Создаешь conditional breakpoints на все методы API, в качестве условия пишешь что-то типа Threading.CurrentThread.ID != MainThreadID (непомню как там это точно в .NET'e)
Здравствуйте, Muxa, Вы писали:
M>Создаешь conditional breakpoints на все методы API, в качестве условия пишешь что-то типа Threading.CurrentThread.ID != MainThreadID (непомню как там это точно в .NET'e)
Примерно то же самое, что вручную искать все вызовы и писать там проверки. Только еще и тормозить будет адово.
Здравствуйте, Codealot, Вы писали:
C>Примерно то же самое, что вручную искать все вызовы и писать там проверки. Только еще и тормозить будет адово.
зачем вручную? Удаляешь рефку на либу и компилятор сам подскажет. Останется только кликать в строчку с багом и Ctrl+V проверку.
C>Примерно то же самое, что вручную искать все вызовы и писать там проверки.
Брэйкпоинты не на вызовы, а на сами методы API, я имел в виду.
C>Только еще и тормозить будет адово.
это да
Здравствуйте, Codealot, Вы писали:
C>А PostSharp умееть инжектить в каждый метод в сборке? Пока нашел только для тех, которые помечены атрибутом.
Конечно умеет. https://doc.postsharp.net/xml-multicasting
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Codealot, Вы писали:
C>Там написано, как применить ко всем методам в типе. А надо — ко всем методам всех типов в сборке, которых очень много. https://doc.postsharp.net/iaspectprovider
???
Здравствуйте, Codealot, Вы писали:
C>Здравствуйте, romangr, Вы писали:
C>А PostSharp умееть инжектить в каждый метод в сборке? Пока нашел только для тех, которые помечены атрибутом.
Умеет.
1. Делаете свой атрибут — MyCustomAspect, наследуете его от MethodInterceptionAspect
2. Применяете его к своей сборке, и в AttributeTargetAssemblies указываете внешнюю сборку
Здравствуйте, Codealot, Вы писали:
C>Как это сделать с минимальным количеством гемора, есть идеи?
Если подойдет в рантайме, то:
1. взять профилятор и запустить приложение, потом в снепшоте найти все вызовы, собрать их вместе и посмотреть откуда звалось (dotTrace так умеет)
2. написать метод, который оборачивает вызов искомого метода и проверяет тред, потом с помощью какого-нибудь тула заменить все вызовы (в ReSharper-e фича Search with Pattern заменит все вызовы без проблем), возможно, в студии тоже есть что-то подобное. В крайнем случае можно регекспами.
Если читая код, то можно взять ReSharper, позвать Incoming calls — получится дерево вызовов. Дальше походить по нему руками, но это намного удобнее, чем по коду. Если при этом еще и помечать места, про которые точно известно, из какого треда они зовутся, то так можно все вычистить.
Здравствуйте, Codealot, Вы писали: C>Там написано, как применить ко всем методам в типе. А надо — ко всем методам всех типов в сборке, которых очень много.
Там можно использовать wildcard при указании имени типа.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Codealot, Вы писали:
C>Вариант, но чем и как?
Придется немного кода написать — перебрать все типы/ методы. Можно поверх рослина, можно плагином в решарперу, можно Mono.Cecil.
Здравствуйте, qxWork, Вы писали:
W>Придется немного кода написать — перебрать все типы/ методы. Можно поверх рослина, можно плагином в решарперу, можно Mono.Cecil.
Здравствуйте, romangr, Вы писали:
C>>Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного. R>Брать Mono.Cecil или PostSharp и инжектить в каждый метод либы код по проверке Thread.ManagedThreadId
A library for patching, replacing and decorating .NET methods during runtime.
If you develop in C# and your code is loaded as a module/plugin into a host application, you can use Harmony to alter the functionality of all the available assemblies of that application. Where other patch libraries simply allow you to replace the original method, Harmony goes one step further and gives you:
A way to keep the original method intact Execute your code before and/or after the original method
Modify the original with IL code processors
Multiple Harmony patches co-exist and don't conflict with each other
Здравствуйте, Codealot, Вы писали: C>Это хорошо, но есть еще проблема — оно дружит с интероп-методами?
Думаю нет. А у вас в сборке есть интероп-методы, которые напрямую вызываются из других сборок?
Вообще, за время между перыым ответом про postSharp и сейчас уже можно было проверить все возможности
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Думаю нет. А у вас в сборке есть интероп-методы, которые напрямую вызываются из других сборок?
Есть COM interop интефейсы, которые используются напрямую.
S>Вообще, за время между перыым ответом про postSharp и сейчас уже можно было проверить все возможности
Учитывая число всех вариантов, которые здесь уже предложили — вряд ли.