crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Процесс-невидимка, странное поведение функции OpenProcess
Iron Bug
  опции профиля:
сообщение 11.6.2010, 11:53
Сообщение #1


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Есть у меня в одной проге такой кусочек кода:

HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,id);
if(h == NULL) {
    бла-бла-бла... ругаемся, что процесса с таким идом нет
}

Тут id - уникальный идентификатор процесса. Цель кусочка - просто тупо проверить, жив ли "пациент".

Ну и, казалось бы, ничего особенного: если нет процесса и открыть его для чтения инфы о нём нельзя, то юзер получит сообщение об ошибке.
Ан-нет! Бывают недоразумения: процесс умер (правда, насильственной смертью - был остановлен дебаг или его прибили через диспетчер задач), а программа успешно "находит" его в списке живых (OpenProcess возвращает ненулевой хэндлер) и не выдаёт ошибку, хотя диспетчер задач его при этом не видит в упор, никто его не видит и вообще его как бы быть не должно.

Компилю msvc 8.0, всё происходит под вендой XP Pro.

Кто-нибудь с такой пакостью сталкивался?

Сообщение отредактировал Iron Bug - 11.6.2010, 11:55
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 11.6.2010, 16:34
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Оригинально, а если попробовать этому процессу какое-нибудь сообщение послать, что будет?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 11.6.2010, 19:22
Сообщение #3


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Litkevich Yuriy @ 11.6.2010, 19:34) *
Оригинально, а если попробовать этому процессу какое-нибудь сообщение послать, что будет?

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

кстати, вот кто-то тоже напоролся на такую "фишку" и привёл очень простой тест для такой фигни:

http://social.msdn.microsoft.com/Forums/en...0d-1821d22fb32c

он там запускал Notepad, записывал PID, убивал приложение и запускал прогу, которая юзала OpenProcess с этим идом и получала в ответ ненулевой хэндлер.
это то же самое практически, что у меня происходит, только в очень упрощённом варианте. и тоже система XP.

Сообщение отредактировал Iron Bug - 11.6.2010, 20:04
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 15.6.2010, 21:52
Сообщение #4


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Может это просто таким макаром работает "сборщик мусора" виндовый?
Процесс который вроде как умер не своей смертью винда по мере сил "закапывает", потому и получается, что когда "трупик" приложения еще не закопан, он и идентифицируется, но при этом "по бумагам" числится как без временно покинувший нас... :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
inviZ
  опции профиля:
сообщение 17.6.2010, 7:13
Сообщение #5


Студент
*

Группа: Новичок
Сообщений: 16
Регистрация: 5.6.2010
Пользователь №: 1781

Спасибо сказали: 4 раз(а)




Репутация:   1  


Ну в *nix-системах же существуют Zombie-процессы. Наверное и в Windows что-то подобное есть. Для того, чтобы была возможность вызвать функцию GetExitCodeProcess().
Соответственно, ее и используй для проверки того, завершен ли процесс. Если процесс не завершен, она вернет STILL_ACTIVE. И все дела.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 17.6.2010, 20:08
Сообщение #6


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата(inviZ @ 17.6.2010, 8:13) *
Если процесс не завершен, она вернет STILL_ACTIVE. И все дела.
А это хорошая мысля! Жаль, что у меня венды нет. Iron Bug с нетерпением жду описание результата экспериментов! :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 18.6.2010, 8:59
Сообщение #7


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Так оно и оказалось.
В общем так: если на процесс или на какой-либо из его потоков (ресурсов и т.п.) существуют открытые хэндлеры - то при его закрытии он фактически завершается, но информация о нём у системы остаётся. При этом запрос GetExitCodeProcess() возвращает код завершения процесса, отличный от STILL_ACTIVE. Если же все хэндлеры закрыты - то процесс нормально "умирает", OpenProcess возвращает NULL.

Вот маленький тест, который я написала ради проверки этой шняги:
Раскрывающийся текст
#include <tchar.h>
#include <iostream>
#include <string>
#include <windows.h>


int _tmain(int argc, _TCHAR* argv[])
{
    int id;
    STARTUPINFO si;
    ZeroMemory(&si,sizeof(si));
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi;
    char c = 0;
    std::cout << "Type 'q' then Enter to quit" << std::endl;
    while(c != 'q')
    {
        BOOL res = CreateProcess(L"C:\\Windows\\System32\\Notepad.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
        if(res)
        {
            DWORD pid = pi.dwProcessId;
            DWORD exit_code;
            std::cout << "Kill Kenny and press Enter... ";
            c = getchar();
            HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pid);
            if(h == NULL)
            {
                std::cout << "They killed Kenny!!!" << std::endl;
            }
            else
            {
                std::cout << "Mission failed! " << std::endl;
                GetExitCodeProcess(h,&exit_code);
                if(exit_code == STILL_ACTIVE)
                {
                    std::cout << "Kenny is ALIVE!!!" << std::endl;
                }
                else
                {
                    std::cout << "Exit code is " << exit_code << std::endl;
                }
                CloseHandle(h);
            }

            std::cout << "Shooting again!" << std::endl;
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);

            h = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pid);
            if(h == NULL)
            {
                std::cout << "They killed Kenny!!!" << std::endl;
            }
            else
            {
                std::cout << "Mission failed!" << std::endl;
                GetExitCodeProcess(h,&exit_code);
                if(exit_code == STILL_ACTIVE)
                {
                    std::cout << "Kenny is ALIVE!!!" << std::endl;
                }
                else
                {
                    std::cout << "Exit code is " << exit_code << std::endl;
                }
                CloseHandle(h);
            }
        }
    }
    std::cout << "press Enter to exit" << std::endl;
    getchar();
    return 0;
}


В тесте после вызова CreateProcess проверяется статус порождённого процесса, после этого закрывается хэндл процесса и хэндл потока (ресурсы освобождаются) и снова проверяется статус.

Сообщение отредактировал Iron Bug - 18.6.2010, 9:10
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 20.4.2024, 13:35