отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 30.10.19 21:44
Оценка:
Есть определенная библиотека с большим количеством классов, которая используется в большом проекте в большом числе многих разных мест. Исходного кода библиотеки нет, а для проекта есть.
Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного.
Как это сделать с минимальным количеством гемора, есть идеи?
Ад пуст, все бесы здесь.
Re: отловить все вызовы не из главного треда
От: samius Япония http://sams-tricks.blogspot.com
Дата: 30.10.19 23:23
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Есть определенная библиотека с большим количеством классов, которая используется в большом проекте в большом числе многих разных мест. Исходного кода библиотеки нет, а для проекта есть.

C>Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного.
C>Как это сделать с минимальным количеством гемора, есть идеи?

С минимальным — не знаю, но есть геморрный путь.
Главный поток и только его пометить ThreadStatic меткой. В каждом методе, обращающимся к коду библиотеки, на входе сделать проверку метки. И за каждым await, если он есть. Task.ContinueWith аналогично.
Re[2]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 30.10.19 23:46
Оценка:
Здравствуйте, samius, Вы писали:

S>В каждом методе, обращающимся к коду библиотеки, на входе сделать проверку метки.


Да, сильно геморный.
Ад пуст, все бесы здесь.
Re: отловить все вызовы не из главного треда
От: romangr Россия  
Дата: 31.10.19 06:12
Оценка: 1 (1) +1
Здравствуйте, Codealot, Вы писали:

C>Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного.


Брать Mono.Cecil или PostSharp и инжектить в каждый метод либы код по проверке Thread.ManagedThreadId
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re[2]: отловить все вызовы не из главного треда
От: Sharov Россия  
Дата: 31.10.19 11:01
Оценка:
Здравствуйте, romangr, Вы писали:

R>Брать Mono.Cecil или PostSharp и инжектить в каждый метод либы код по проверке Thread.ManagedThreadId


Как это поможет отичить главнй поток от неглавного?
Кодом людям нужно помогать!
Re[3]: отловить все вызовы не из главного треда
От: romangr Россия  
Дата: 31.10.19 11:22
Оценка: 5 (1)
Здравствуйте, Sharov, Вы писали:

S>Как это поможет отичить главнй поток от неглавного?


При старте программы записываем в удобное место id главного потока, затем сравниваем
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re: отловить все вызовы не из главного треда
От: Mr.Delphist  
Дата: 31.10.19 16:39
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Есть определенная библиотека с большим количеством классов, которая используется в большом проекте в большом числе многих разных мест. Исходного кода библиотеки нет, а для проекта есть.

C>Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного.

Задача для compile-time или run-time?
Re[2]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 31.10.19 17:32
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Задача для compile-time или run-time?


Да без разницы, главное найти места.
Ад пуст, все бесы здесь.
Re: отловить все вызовы не из главного треда
От: Muxa  
Дата: 31.10.19 18:33
Оценка: +1 :)
C>Как это сделать с минимальным количеством гемора, есть идеи?
Создаешь conditional breakpoints на все методы API, в качестве условия пишешь что-то типа Threading.CurrentThread.ID != MainThreadID (непомню как там это точно в .NET'e)
Re[2]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 31.10.19 18:53
Оценка:
Здравствуйте, Muxa, Вы писали:

M>Создаешь conditional breakpoints на все методы API, в качестве условия пишешь что-то типа Threading.CurrentThread.ID != MainThreadID (непомню как там это точно в .NET'e)


Примерно то же самое, что вручную искать все вызовы и писать там проверки. Только еще и тормозить будет адово.
Ад пуст, все бесы здесь.
Re[3]: отловить все вызовы не из главного треда
От: samius Япония http://sams-tricks.blogspot.com
Дата: 31.10.19 18:56
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Примерно то же самое, что вручную искать все вызовы и писать там проверки. Только еще и тормозить будет адово.

зачем вручную? Удаляешь рефку на либу и компилятор сам подскажет. Останется только кликать в строчку с багом и Ctrl+V проверку.
Re[3]: отловить все вызовы не из главного треда
От: Muxa  
Дата: 31.10.19 19:13
Оценка:
C>Примерно то же самое, что вручную искать все вызовы и писать там проверки.
Брэйкпоинты не на вызовы, а на сами методы API, я имел в виду.

C>Только еще и тормозить будет адово.

это да
Re[2]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 31.10.19 19:58
Оценка:
Здравствуйте, romangr, Вы писали:

R>Брать Mono.Cecil или PostSharp и инжектить в каждый метод либы код по проверке Thread.ManagedThreadId


А PostSharp умееть инжектить в каждый метод в сборке? Пока нашел только для тех, которые помечены атрибутом.
Ад пуст, все бесы здесь.
Re[4]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 31.10.19 19:58
Оценка:
Здравствуйте, samius, Вы писали:

S>Останется только кликать в строчку с багом и Ctrl+V проверку.


Ага, для всех сотен строчек. Плюс наведенные ошибки компилятора, которые надо отсеивать.
Ад пуст, все бесы здесь.
Re[4]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 31.10.19 20:24
Оценка:
Здравствуйте, Muxa, Вы писали:

M>Брэйкпоинты не на вызовы, а на сами методы API, я имел в виду.


А, понял. Но их там сотни, если не тысячи. Я задолбаюсь.
Ад пуст, все бесы здесь.
Re[3]: отловить все вызовы не из главного треда
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.11.19 04:53
Оценка:
Здравствуйте, Codealot, Вы писали:

C>А PostSharp умееть инжектить в каждый метод в сборке? Пока нашел только для тех, которые помечены атрибутом.

Конечно умеет.
https://doc.postsharp.net/xml-multicasting
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 01.11.19 05:09
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Конечно умеет.

S>https://doc.postsharp.net/xml-multicasting

Там написано, как применить ко всем методам в типе. А надо — ко всем методам всех типов в сборке, которых очень много.
Ад пуст, все бесы здесь.
Re[5]: отловить все вызовы не из главного треда
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.11.19 05:23
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Там написано, как применить ко всем методам в типе. А надо — ко всем методам всех типов в сборке, которых очень много.

https://doc.postsharp.net/iaspectprovider
???
Re[3]: отловить все вызовы не из главного треда
От: romangr Россия  
Дата: 01.11.19 05:44
Оценка: 5 (1)
Здравствуйте, Codealot, Вы писали:

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


C>А PostSharp умееть инжектить в каждый метод в сборке? Пока нашел только для тех, которые помечены атрибутом.


Умеет.
1. Делаете свой атрибут — MyCustomAspect, наследуете его от MethodInterceptionAspect
2. Применяете его к своей сборке, и в AttributeTargetAssemblies указываете внешнюю сборку
[assembly: MyCustomAspect(AttributeTargetAssemblies="externallib")]

Или то же самое но через XML.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re: отловить все вызовы не из главного треда
От: qxWork Голландия http://www.jetbrains.com/company/people/Coox_Sergey.html
Дата: 01.11.19 07:14
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Как это сделать с минимальным количеством гемора, есть идеи?


Если подойдет в рантайме, то:
1. взять профилятор и запустить приложение, потом в снепшоте найти все вызовы, собрать их вместе и посмотреть откуда звалось (dotTrace так умеет)
2. написать метод, который оборачивает вызов искомого метода и проверяет тред, потом с помощью какого-нибудь тула заменить все вызовы (в ReSharper-e фича Search with Pattern заменит все вызовы без проблем), возможно, в студии тоже есть что-то подобное. В крайнем случае можно регекспами.

Если читая код, то можно взять ReSharper, позвать Incoming calls — получится дерево вызовов. Дальше походить по нему руками, но это намного удобнее, чем по коду. Если при этом еще и помечать места, про которые точно известно, из какого треда они зовутся, то так можно все вычистить.
Re[2]: отловить все вызовы не из главного треда
От: qxWork Голландия http://www.jetbrains.com/company/people/Coox_Sergey.html
Дата: 01.11.19 07:15
Оценка:
Здравствуйте, qxWork, Вы писали:

черт, пропустил про "все вызовы, всех методов всех типов".
Сгенерить сборку-wrapper с проверкой и звать ее не вариант?
Re[5]: отловить все вызовы не из главного треда
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.11.19 08:14
Оценка:
Здравствуйте, Codealot, Вы писали:
C>Там написано, как применить ко всем методам в типе. А надо — ко всем методам всех типов в сборке, которых очень много.
Там можно использовать wildcard при указании имени типа.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: отловить все вызовы не из главного треда
От: Muxa  
Дата: 01.11.19 09:00
Оценка:
M>>Брэйкпоинты не на вызовы, а на сами методы API, я имел в виду.

C>А, понял. Но их там сотни, если не тысячи. Я задолбаюсь.


Напиши макрос
Re[3]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 01.11.19 15:46
Оценка:
Здравствуйте, qxWork, Вы писали:

W>Сгенерить сборку-wrapper с проверкой и звать ее не вариант?


Вариант, но чем и как?
Ад пуст, все бесы здесь.
Re[6]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 01.11.19 15:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Там можно использовать wildcard при указании имени типа.


Это хорошо, но есть еще проблема — оно дружит с интероп-методами?
Ад пуст, все бесы здесь.
Re[4]: отловить все вызовы не из главного треда
От: qxWork Голландия http://www.jetbrains.com/company/people/Coox_Sergey.html
Дата: 01.11.19 16:14
Оценка:
Здравствуйте, Codealot, Вы писали:

C>Вариант, но чем и как?

Придется немного кода написать — перебрать все типы/ методы. Можно поверх рослина, можно плагином в решарперу, можно Mono.Cecil.
Re[5]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 01.11.19 19:43
Оценка:
Здравствуйте, qxWork, Вы писали:

W>Придется немного кода написать — перебрать все типы/ методы. Можно поверх рослина, можно плагином в решарперу, можно Mono.Cecil.


На самом деле, всё намного сложнее.
Ад пуст, все бесы здесь.
Re[2]: отловить все вызовы не из главного треда
От: alexzzzz  
Дата: 01.11.19 23:14
Оценка: 3 (1) +1
Здравствуйте, romangr, Вы писали:

C>>Задача: отловить все вызовы всех методов этой библиотеки, которые совершаются из любых тредов кроме главного.

R>Брать Mono.Cecil или PostSharp и инжектить в каждый метод либы код по проверке Thread.ManagedThreadId

https://github.com/pardeike/Harmony

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:

Re[7]: отловить все вызовы не из главного треда
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.11.19 10:19
Оценка:
Здравствуйте, Codealot, Вы писали:
C>Это хорошо, но есть еще проблема — оно дружит с интероп-методами?
Думаю нет. А у вас в сборке есть интероп-методы, которые напрямую вызываются из других сборок?
Вообще, за время между перыым ответом про postSharp и сейчас уже можно было проверить все возможности
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: отловить все вызовы не из главного треда
От: Codealot Земля  
Дата: 02.11.19 17:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Думаю нет. А у вас в сборке есть интероп-методы, которые напрямую вызываются из других сборок?


Есть COM interop интефейсы, которые используются напрямую.

S>Вообще, за время между перыым ответом про postSharp и сейчас уже можно было проверить все возможности


Учитывая число всех вариантов, которые здесь уже предложили — вряд ли.
Ад пуст, все бесы здесь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.