Узнать кто создал поток
От: Aniskin  
Дата: 21.08.17 05:51
Оценка:
Использую стороннюю dll в многопоточном режиме. Эта dll создает свои потоки и делает из них callback вызовы в мой код. Хочется узнать, в каком моем потоке был создан поток в dll. Единственная моя идея — перехватывать CreateThread/ExitThread и самостоятельно ручками строить дерево потоков и анализировать его в callback функциях. Может быть есть более нативный метод?
Re: Узнать кто создал поток
От: CEMb  
Дата: 21.08.17 07:12
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Использую стороннюю dll в многопоточном режиме. Эта dll создает свои потоки и делает из них callback вызовы в мой код. Хочется узнать, в каком моем потоке был создан поток в dll. Единственная моя идея — перехватывать CreateThread/ExitThread и самостоятельно ручками строить дерево потоков и анализировать его в callback функциях. Может быть есть более нативный метод?


Скорее всего нет. В CreateThread никакой информации о текущем потоке никуда не передаётся. Но лучше посмотреть в исходники, может это и не так
Re[2]: Узнать кто создал поток
От: Aniskin  
Дата: 21.08.17 07:16
Оценка:
Deleted (неправильно понял ответ).
Отредактировано 21.08.2017 7:18 Aniskin . Предыдущая версия .
Re: Узнать кто создал поток
От: Alexander G Украина  
Дата: 21.08.17 12:01
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Использую стороннюю dll в многопоточном режиме. Эта dll создает свои потоки и делает из них callback вызовы в мой код. Хочется узнать, в каком моем потоке был создан поток в dll. Единственная моя идея — перехватывать CreateThread/ExitThread и самостоятельно ручками строить дерево потоков и анализировать его в callback функциях. Может быть есть более нативный метод?


Хм, а какую проблему позволило бы решить знание графа потоков?

В принципе, если гарантировать, что одновременно только один свой поток работает с той DLL одновременно, и Id этого потока записан в какой-то своей глобальной переменной, то, получив DLL_THREAD_ATTACH TLS-нотификацию, можно записать Id своего потока в TLS для DLL потока.
Русский военный корабль идёт ко дну!
Re[2]: Узнать кто создал поток
От: Aniskin  
Дата: 21.08.17 17:16
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Хм, а какую проблему позволило бы решить знание графа потоков?


Грубо говоря, я перехватываю в dll CreateFileW и мне нужно понять контекст текущей операции.

AG>В принципе, если гарантировать, что одновременно только один свой поток работает с той DLL одновременно


Как я написал в исходном сообщении, я использую стороннюю dll в многопоточном режиме.
Re: Узнать кто создал поток
От: mjau  
Дата: 21.08.17 17:37
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Использую стороннюю dll в многопоточном режиме. Эта dll создает свои потоки и делает из них callback вызовы в мой код. Хочется узнать, в каком моем потоке был создан поток в dll. Единственная моя идея — перехватывать CreateThread/ExitThread и самостоятельно ручками строить дерево потоков и анализировать его в callback функциях. Может быть есть более нативный метод?


Несколько странное желание, почему бы не хранить threadId стартовавшего потока в контексте операции?
Каждый, просыпаясь утром, должен задавать себе вопрос — что он может сегодня сделать, чтобы россиянства
Автор: Kerk
Дата: 21.08.22
в мире стало меньше.
Отредактировано 21.08.2017 17:39 mjau . Предыдущая версия .
Re[3]: Узнать кто создал поток
От: Alexander G Украина  
Дата: 21.08.17 18:04
Оценка:
Здравствуйте, Aniskin, Вы писали:

AG>>Хм, а какую проблему позволило бы решить знание графа потоков?


A>Грубо говоря, я перехватываю в dll CreateFileW и мне нужно понять контекст текущей операции.


Ясно, ну тогда может такой граф и поможет. А может и нет, если dll на самом деле использует тредпул и разные операции в том же её потоке.

За контекст вроде имени файла там точно нельзя зацепиться?
Русский военный корабль идёт ко дну!
Re: Узнать кто создал поток
От: ononim  
Дата: 21.08.17 18:32
Оценка:
A>Использую стороннюю dll в многопоточном режиме. Эта dll создает свои потоки и делает из них callback вызовы в мой код. Хочется узнать, в каком моем потоке был создан поток в dll. Единственная моя идея — перехватывать CreateThread/ExitThread и самостоятельно ручками строить дерево потоков и анализировать его в callback функциях. Может быть есть более нативный метод?
ExitThread хукать необязательно, можно просто открывать (дублицировать в себя) и ждать контролируемые потоки (RegisterWaitForSingleObject прям так и напрашивается)
Как много веселых ребят, и все делают велосипед...
Отредактировано 21.08.2017 18:40 ononim . Предыдущая версия .
Re[2]: Узнать кто создал поток
От: Aniskin  
Дата: 21.08.17 19:28
Оценка:
Здравствуйте, mjau, Вы писали:

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


A>>Использую стороннюю dll в многопоточном режиме. Эта dll создает свои потоки и делает из них callback вызовы в мой код. Хочется узнать, в каком моем потоке был создан поток в dll. Единственная моя идея — перехватывать CreateThread/ExitThread и самостоятельно ручками строить дерево потоков и анализировать его в callback функциях. Может быть есть более нативный метод?


M>Несколько странное желание, почему бы не хранить threadId стартовавшего потока в контексте операции?


Не совсем понял твой комментарий. Где и что хранить?

Вот запустил я N потоков, каждый из которых выполняет операцию OpN с использованием dll. Dll для каждой операции создает дополнительный поток, из которого вызывает некую callback функцию. В параметрах callback функции нет параметра, позволяющего мне идентифицировать мой исходный поток. Как мне его определить?
Re[4]: Узнать кто создал поток
От: Aniskin  
Дата: 21.08.17 19:34
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>За контекст вроде имени файла там точно нельзя зацепиться?


Нет, там очень общие функции. Типа ErrorHappens(Msg), и я должен знать, является ли операция, к которой относится этот callback вызов, silent или же я все же могу показать окно с ошибкой. Это просто пример, но суть примерно такая.
Re[3]: Узнать кто создал поток
От: mjau  
Дата: 22.08.17 05:08
Оценка:
Здравствуйте, Aniskin, Вы писали:


M>>Несколько странное желание, почему бы не хранить threadId стартовавшего потока в контексте операции?


A>Вот запустил я N потоков, каждый из которых выполняет операцию OpN с использованием dll. Dll для каждой операции создает дополнительный поток, из которого вызывает некую callback функцию. В параметрах callback функции нет параметра, позволяющего мне идентифицировать мой исходный поток. Как мне его определить?


А как вы определяете, к какой операции относится колбек?
Или длл строго однопоточная и одна операция происходит в один момент времени? В таком случае, идеологически правильно было бы завернуть dll в отдельный процесс для исключения разных веселых проблем с однопоточной dll в многопоточной среде.
В случае же одного процесса нет стандартных средств получить родителя потока, т.к. потоки не имеют иерархии, тут либо городить велосипеды, либо как вариант покопаться в TEB, но вероятность того, что там будет что-то подходящее, весьма мала.
Каждый, просыпаясь утром, должен задавать себе вопрос — что он может сегодня сделать, чтобы россиянства
Автор: Kerk
Дата: 21.08.22
в мире стало меньше.
Re[4]: Узнать кто создал поток
От: Aniskin  
Дата: 22.08.17 05:18
Оценка:
Здравствуйте, mjau, Вы писали:

M>А как вы определяете, к какой операции относится колбек?


Глобальный список из пар ThreadID-OpN

M>Или длл строго однопоточная и одна операция происходит в один момент времени?


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

M>тут либо городить велосипеды


Этим и занимаюсь.
Re[2]: Узнать кто создал поток
От: Alexander G Украина  
Дата: 22.08.17 06:56
Оценка:
Здравствуйте, ononim, Вы писали:

O>ExitThread хукать необязательно, можно просто открывать (дублицировать в себя) и ждать контролируемые потоки (RegisterWaitForSingleObject прям так и напрашивается)


Для отслеживания завершения потока достаточно контроля через DLL_THREAD_DETACH из DllMain либо TLS Callback, наверное

Решение на ожиданиях гипотетически подвержено гонке: поток уже завершился, и может быть новый поток с таким ID (практически нет, recycle там долгий).
Но зато оно справится с TerminateThread или прямым NtTerminateThread ( для психов, готовых поддерживать такие сценарии ).
Русский военный корабль идёт ко дну!
Отредактировано 22.08.2017 7:33 Alexander G . Предыдущая версия .
Re[5]: Узнать кто создал поток
От: mjau  
Дата: 22.08.17 07:06
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Dll позволяет работу в многопоточном режиме, просто потребностей у меня больше, чем предлагается.


Как можно похволить работу в многопоточном режиме без предоставления механизма связи запроса и ответа ?
Каждый, просыпаясь утром, должен задавать себе вопрос — что он может сегодня сделать, чтобы россиянства
Автор: Kerk
Дата: 21.08.22
в мире стало меньше.
Re[3]: Узнать кто создал поток
От: ononim  
Дата: 22.08.17 07:42
Оценка: 1 (1)
O>>ExitThread хукать необязательно, можно просто открывать (дублицировать в себя) и ждать контролируемые потоки (RegisterWaitForSingleObject прям так и напрашивается)
AG>Для отслеживания завершения потока достаточно контроля через DLL_THREAD_DETACH из DllMain либо TLS Callback, наверное
топикстартер не говорил что у него под рукой еще и своя длл есть. Впрочем FlsCallback()-у она не нужна

AG>Решение на ожиданиях гипотетически подвержено гонке: поток уже завершился, и может быть новый поток с таким ID (практически нет, recycle там долгий).

Нет. Пока есть хоть один незакрытый хэндл на поток, его ID не переюзают.

AG>Но зато оно справится с TerminateThread или прямым NtTerminateThread ( для психов, готовых поддерживать такие сценарии ).

Да
Как много веселых ребят, и все делают велосипед...
Отредактировано 22.08.2017 7:43 ononim . Предыдущая версия .
Re[6]: Узнать кто создал поток
От: Aniskin  
Дата: 22.08.17 07:43
Оценка:
Здравствуйте, mjau, Вы писали:

M>Как можно позволить работу в многопоточном режиме без предоставления механизма связи запроса и ответа ?


Сценарии бывают всякие разные. Одно из моих действий — перехват CreateFile и еще пары функций в dll. А в операции я не знаю, что будет передано в CreateFile.
Re[3]: Узнать кто создал поток
От: ononim  
Дата: 22.08.17 08:18
Оценка:
AG>>Хм, а какую проблему позволило бы решить знание графа потоков?
A>Грубо говоря, я перехватываю в dll CreateFileW и мне нужно понять контекст текущей операции.
Хреновая какаято архитектура. А если автор длл заюзал/решит заюзать thread pool?
Как много веселых ребят, и все делают велосипед...
Re[4]: Узнать кто создал поток
От: Aniskin  
Дата: 22.08.17 09:37
Оценка:
Здравствуйте, ononim, Вы писали:

O>Хреновая какаято архитектура.


Суть одной из проблем более детально — я в своей поделке TC4Shell использую (в том числе) стороннюю библиотеку unrar.dll для распаковки rar архивов. Грубо говоря я указываю ей "распакуй некоторые файлы в такую то директорию, которую выбрал пользователь". Соответственно, если пользователь выбрал, например, директорию Program Files, то при распаковке произойдет ERROR_ACCESS_DENIED, а мне вернется какой нибудь внутренний ERAR_ECREATE. А я хочу в этой ситуации спросить пользователя, не хочет ли он повысить права до админа (недавно создавал топик об этом). Если пользователь захочет, то повышаем, и вызываем CreateFile с админовыми правами. Но что бы это реализовать мне нужно перехватывать CreateFile. В тоже время ряд операций типа извлечения эскиза файла в Проводнике должны быть тихими без всякого UI. Это один из сценариев.

O>А если автор длл заюзал/решит заюзать thread pool?


Будет обидно и придется отказаться от своей затеи.
Re[5]: Узнать кто создал поток
От: ononim  
Дата: 22.08.17 09:55
Оценка:
A>Суть одной из проблем более детально — я в своей поделке TC4Shell использую (в том числе) стороннюю библиотеку unrar.dll для распаковки rar архивов. Грубо говоря я указываю ей "распакуй некоторые файлы в такую то директорию, которую выбрал пользователь". Соответственно, если пользователь выбрал, например, директорию Program Files, то при распаковке произойдет ERROR_ACCESS_DENIED, а мне вернется какой нибудь внутренний ERAR_ECREATE. А я хочу в этой ситуации спросить пользователя, не хочет ли он повысить права до админа (недавно создавал топик об этом). Если пользователь захочет, то повышаем, и вызываем CreateFile с админовыми правами. Но что бы это реализовать мне нужно перехватывать CreateFile. В тоже время ряд операций типа извлечения эскиза файла в Проводнике должны быть тихими без всякого UI. Это один из сценариев.
Я бы вынес все это дело в отдельный процесс. Если бы встал вопрос перфоманса изза задержки на его запуск — сделал бы этот процесс воркером, издыхающим только когда сдохнет его хозяин. Как вариант — COM сервер-ом.
Как много веселых ребят, и все делают велосипед...
Re[6]: Узнать кто создал поток
От: Aniskin  
Дата: 22.08.17 10:01
Оценка:
Здравствуйте, ononim, Вы писали:

O>Я бы вынес все это дело в отдельный процесс.


А в чем преимущество отдельного процесса?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.