Куда подевался поток?
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 15.08.05 07:29
Оценка:
Провожу эксперимент:
1. В DLL_PROCESS_ATTACH создаю новый поток — создается и нормально работает.
2. Ставлю в DLL_PROCESS_DETACH breakpoint и вижу в отладчике, что процесса уже нет.

Куда он делся, и кто и в какой момент его убил?

Проект маленький, и никакие побочных процессов влияющих на потоки нет.
Перечитал Рихтера, но у него ничего по этому поводу нет, т.к вроде как все должно быть ОК.
Re: Куда подевался поток?
От: Amidlokos Россия  
Дата: 15.08.05 18:36
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Провожу эксперимент:

ATP>1. В DLL_PROCESS_ATTACH создаю новый поток — создается и нормально работает.
ATP>2. Ставлю в DLL_PROCESS_DETACH breakpoint и вижу в отладчике, что процесса уже нет.

ATP>Куда он делся, и кто и в какой момент его убил?


Спокойненько завершился пока DLL-ка стоит на бряке?

(не помню тонкостей организации многопоточных dll, не бейте, но о невозможности подобного в MSDN не сказано)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
WARNING: expression "to_be || !to_be" is always true
Re: Куда подевался поток?
От: Paul_de_Dupon  
Дата: 15.08.05 20:10
Оценка:
Нодо код посмотреть, но лучше потоки не создавать в аттаче, а еще лучше вообще их не создавать
Re: Куда подевался поток?
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 16.08.05 07:22
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

Рад что хоть кто-то сталкивался с такой же проблеммой.
Если нужен код, то он простейший, представте самый простой код который только может быть на эту тему
Если серьезно, то я упростил эксперимент до следующего:

Создаю в DLL всего один класс


//////////////////////////////////////////////////////////////////////
class CMessanger
{
    HANDLE                m_hMessageThread;

    static LRESULT CALLBACK MessageThreadWrapper (CMessanger* pThis);
    LRESULT                MessageThread ();

public:
    CMessanger(void);
    ~CMessanger(void);
};



//////////////////////////////////////////////////////////////////////
CMessanger::CMessanger(void)
{
    m_hMessageThread = ::CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)MessageThreadWrapper, NULL, 0, NULL);
}

CMessanger::~CMessanger(void)
{
    ::WaitForSingleObject (m_hMessageThread, INFINITE); // Когда здесь вызывается деструктор, то m_hMessageThread
                                                            // потока уже нет - проверено.

}



//////////////////////////////////////////////////////////////////////
LRESULT CALLBACK CMessanger::MessageThreadWrapper (CMessanger* pThis)
{
    return pThis->MessageThread ();
}



//////////////////////////////////////////////////////////////////////
LRESULT CMessanger::MessageThread ()
{
    while (1); // Как видно цикл вроде как безконечный, но вседаки мы от сюда выходим - кто-то убивает поток
}



У Рихтера написано, что C++ рантайм и DllMain — вызваются примерно из одного места и в одно и тоже время, т.к. эксперимент равнозначный.


Что я хочу сделать:
Мне нужно общаться с DLL котрая находится в другом процессе, и нет возможностей вызывать ее функции напрямую. Мне нужно пересылать ей команды, и получать от неев ответы, ил другие данные. Потоки как таковые мне не нужны. Нужно уметь общаться с такой DLL. Как это можно сделать? RPC м всякие тяжеловесный штуки не предлагать.
Re[2]: Куда подевался поток?
От: 0xfeefee  
Дата: 16.08.05 07:37
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

[]

была похожая проблема... времени разбираться не было.
решил просто — добавил в длл функцию типа Init() в которой и запускал процесс. вызывал её из ехе соответственно.
Re[3]: Куда подевался поток?
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 16.08.05 07:38
Оценка:
Здравствуйте, 0xfeefee, Вы писали:

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


0>[]


0>была похожая проблема... времени разбираться не было.

0>решил просто — добавил в длл функцию типа Init() в которой и запускал процесс. вызывал её из ехе соответственно.

Dll — в другом не подконтрольном процессе. Как мне там Init() вызвать?
Re[4]: Куда подевался поток?
От: 0xfeefee  
Дата: 16.08.05 07:48
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Здравствуйте, 0xfeefee, Вы писали:


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


0>>[]


0>>была похожая проблема... времени разбираться не было.

0>>решил просто — добавил в длл функцию типа Init() в которой и запускал процесс. вызывал её из ехе соответственно.

ATP> Dll — в другом не подконтрольном процессе. Как мне там Init() вызвать?


так же как и везде я так думаю...
::LoadLibrary() и ::GetProcAddress() никто не отменял
а какие проблемы?
Re[5]: Куда подевался поток?
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 16.08.05 10:36
Оценка:
Здравствуйте, 0xfeefee, Вы писали:

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


ATP>>Здравствуйте, 0xfeefee, Вы писали:


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


0>>>[]


0>>>была похожая проблема... времени разбираться не было.

0>>>решил просто — добавил в длл функцию типа Init() в которой и запускал процесс. вызывал её из ехе соответственно.

ATP>> Dll — в другом не подконтрольном процессе. Как мне там Init() вызвать?


0>так же как и везде я так думаю...

0>::LoadLibrary() и ::GetProcAddress() никто не отменял
0>а какие проблемы?

Проблемма в том, что ::LoadLibrary() и ::GetProcAddress() должен вызвать код из Exe, код это не мой, и доступа у меня к нему нет.
Re[2]: Куда подевался поток?
От: aik Австралия  
Дата: 16.08.05 14:54
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Рад что хоть кто-то сталкивался с такой же проблеммой.

ATP>Если нужен код, то он простейший, представте самый простой код который только может быть на эту тему
ATP>Если серьезно, то я упростил эксперимент до следующего:

ATP>Создаю в DLL всего один класс


...

Фигня, а не код. Пришли что нить компилируемое командной строкой типа "cl test.cpp user32.lib" или вроде того, иначе ни черта не понятно. Это код твоей DLL? Кто ее грузит и выгружает?

ATP>У Рихтера написано, что C++ рантайм и DllMain — вызваются примерно из одного места и в одно и тоже время, т.к. эксперимент равнозначный.


"Примерно" — это пять _DllMainCRTStartup инитит рантайм и затем вызывает твой DllMain.

ATP>Что я хочу сделать:

ATP>Мне нужно общаться с DLL котрая находится в другом процессе, и нет возможностей вызывать ее функции напрямую. Мне нужно пересылать ей команды, и получать от неев ответы, ил другие данные. Потоки как таковые мне не нужны. Нужно уметь общаться с такой DLL. Как это можно сделать? RPC м всякие тяжеловесный штуки не предлагать.

Ну хоть немножечка намекни как эта DLL вообще воспринимает что то снаружи, блин. У тебя ее хандл есть, или еще что? SendMessage используй, вот уж редкостная халява.
Re[3]: Куда подевался поток?
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 16.08.05 15:05
Оценка:
Здравствуйте, aik, Вы писали:


aik>Фигня, а не код. Пришли что нить компилируемое командной строкой типа "cl test.cpp user32.lib" или вроде того, иначе ни черта не понятно. Это код твоей DLL? Кто ее грузит и выгружает?


Создаешь проект пустой DLL и там просто создаешь глобальный экземпляр этого класса — и всею Куда проще?

aik>"Примерно" — это пять _DllMainCRTStartup инитит рантайм и затем вызывает твой DllMain.


Ну, да. Я имел ввиду, что он рантайма к рантайму это все может меняться и порядок не гарантирован.

aik>Ну хоть немножечка намекни как эта DLL вообще воспринимает что то снаружи, блин. У тебя ее хандл есть, или еще что? SendMessage используй, вот уж редкостная халява.


Ничего нет. Эти DLL подгружаются после вызова SetWindowsHookEx ко всем приложениям. В какой момент — это винда решает. Тоесть в момент запуска я еще могу как-то полать себе сообщения. Но вот с выгрузкой — ж...па полная. Поскольку DLL могут выгрузиться с приложение в любой момент а в DllMain в момент DETACH_PROCESS потоки уже убиты, то я и не могу их корректно завершить.
Re[6]: Куда подевался поток?
От: 0xfeefee  
Дата: 16.08.05 16:53
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Здравствуйте, 0xfeefee, Вы писали:


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


ATP>>>Здравствуйте, 0xfeefee, Вы писали:


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


0>>>>[]


0>>>>была похожая проблема... времени разбираться не было.

0>>>>решил просто — добавил в длл функцию типа Init() в которой и запускал процесс. вызывал её из ехе соответственно.

ATP>>> Dll — в другом не подконтрольном процессе. Как мне там Init() вызвать?


0>>так же как и везде я так думаю...

0>>::LoadLibrary() и ::GetProcAddress() никто не отменял
0>>а какие проблемы?

ATP>Проблемма в том, что ::LoadLibrary() и ::GetProcAddress() должен вызвать код из Exe, код это не мой, и доступа у меня к нему нет.


может поможет...

Regular DLLs that create threads should only do so in functions exported from the DLL and called by client applications. Furthermore, no MFC DLL -- neither Extension nor Regular -- should create an MFC thread in the DllMain or RawDllMain function. This ensures that the thread will not be created in the middle of any critical startup code.

The recommended solution for MFC DLLs that need to create a thread when the DLL starts is to add a specific exported initialization function and create the thread in it. Applications that use the DLL would need to call this function sometime during startup, most likely during the application's InitInstance if it uses MFC. Or, if the application is loading the DLL explicitly, the application should call the initialization function immediately after the call to load the library.

The practice of exporting an initialization function for a DLL is not uncommon. Nevertheless, there may be situations where DLLs created with earlier versions of MFC are being ported but the client application cannot be changed to include a call to an initialization function. The alternative to an initialization function is to create the thread in one of the pre- existing exported functions. Any of the DLL's exported functions that require a running thread should be responsible for first checking to see if that thread exists and then creating it if it does not.


если уж есть необходимость стартовать поток — стартуйте его в известной функции, но не в мэйне...
Re[4]: Куда подевался поток?
От: rus blood Россия  
Дата: 17.08.05 05:27
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Ничего нет. Эти DLL подгружаются после вызова SetWindowsHookEx ко всем приложениям. В какой момент — это винда решает. Тоесть в момент запуска я еще могу как-то полать себе сообщения. Но вот с выгрузкой — ж...па полная. Поскольку DLL могут выгрузиться с приложение в любой момент а в DllMain в момент DETACH_PROCESS потоки уже убиты, то я и не могу их корректно завершить.


Почему бы твоей хуковой процедуре не ловить сообщение об уничтожении top-level окна своего приложения?
Аналогично, если нужно управлять своей dll извне, можно рассылать broadcast-сообщения.
Имею скафандр — готов путешествовать!
Re[5]: Куда подевался поток?
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 17.08.05 07:00
Оценка:
Здравствуйте, rus blood, Вы писали:

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


ATP>>Ничего нет. Эти DLL подгружаются после вызова SetWindowsHookEx ко всем приложениям. В какой момент — это винда решает. Тоесть в момент запуска я еще могу как-то полать себе сообщения. Но вот с выгрузкой — ж...па полная. Поскольку DLL могут выгрузиться с приложение в любой момент а в DllMain в момент DETACH_PROCESS потоки уже убиты, то я и не могу их корректно завершить.


RB>Почему бы твоей хуковой процедуре не ловить сообщение об уничтожении top-level окна своего приложения?

RB>Аналогично, если нужно управлять своей dll извне, можно рассылать broadcast-сообщения.

Сейчас так и делаю, но это не надежно, т.к DLL внедряется во многие процессы у которых нет окон, а повлиять на то куда ана будет внедряться — нельзя.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.