Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2010.10.31;
Скачать: [xml.tar.bz2];

Вниз

Как корректно прекратить отладку?   Найти похожие ветки 

 
Валигози ©   (2009-04-27 10:59) [0]

Моё приложение запускает другое приложение в режиме отладки (CreateProcess с флажками DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS).
Потом идёт сам цикл отладки (WaitForDebugEvent и ContinueDebugEvent).
И в определённый процесс времени нужно прекратить отладку с завершением отлаживаемого процесса, но не завершая при этом отладчик. TerminateProcess (+ закрытие хэндлов в ProcessInformation) отлаживаемый процесс завершает, однако видимо какие-то хэндлы всё же остаются открытыми, так как файл приложения (которое отлаживали) не доступен для модификации... :(
Как же всётаки корректно прекратить отладку?

В интернете нашёл максимум такой же вопрос, но без ответа: http://forum.codenet.ru/showthread.php?t=10408
На сайте microsoft, естественно, тоже ничего путного не нашёл: http://msdn.microsoft.com/en-us/library/ms681675(VS.85).aspx


 
Сергей М. ©   (2009-04-27 13:38) [1]


> видимо какие-то хэндлы всё же остаются открытыми


Ну так выясни какие конкретно..


 
clickmaker ©   (2009-04-27 13:44) [2]

а FatalExit() не поможет?


 
Валигози ©   (2009-04-27 15:10) [3]


> Сергей М. ©   (27.04.09 13:38) [1]
> > видимо какие-то хэндлы всё же остаются открытыми
> Ну так выясни какие конкретно..

Перечислить все открытые процессом хэндлы и сделать им всем CloseHandle? Странно, если проблема в этом... Тогда получается, что микрософты сделали жутко сырые функции отладки...


> clickmaker ©   (27.04.09 13:44) [2]
> а FatalExit() не поможет?

FatalExit завершает текущее приложение, а нужно чтобы приложение-отладчик завершило отлаживаемое приложение. Хотя конечно можно и извратнутся, подправив EIP (с помощью SetThreadContext), чтобы оно указывало на вход в функцию FatalExit :)))

Просто странно, что с этой проблемой (почти) никто не сталкивался (а если и сталкивался, то не решил её). Или может я слишком сумбурно объяснил. Я только недавно занялся темой отладки и постоянно наступаю на грабли... :(


 
Rouse_ ©   (2009-04-27 16:26) [4]

Останови основной поток, потом GetThreadContext, EIP выставб на адрес ExitProcess, SetThreadContext - запусти основной поток.


 
Валигози ©   (2009-04-27 17:44) [5]


> Rouse_ ©   (27.04.09 16:26) [4]
> Останови основной поток, потом GetThreadContext, EIP выставб
> на адрес ExitProcess, SetThreadContext - запусти основной
> поток.

Ну да, об этом я в предыдущем посте и писал, правда не о функции ExitProcess, а о функции FatalExit.
Но вобщем, как я понимаю, проблема не в том. На вид, процесс вроде убивается нормально (из диспетчера задач исчезает), но файл отлаживаемого приложения нельзя удалить, пока не завершить также и приложение-отладчик.

Я набросал урезанную версию отладчика, для экспериментов:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   FHProcess: THandle;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 PI: TProcessInformation;
 SI: TStartupInfo;
 DE: TDebugEvent;
 ContinueStatus: DWORD;
 BaseOfImage: Pointer;  
begin
 BaseOfImage:=nil;
 GetStartupInfo(SI);
 if CreateProcess(
      "C:\copy\Notepad.exe",
      nil,
      nil,
      nil,
      False,
      DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS,
      nil,
      nil,
      SI,
      PI) then
 begin
   FHProcess:=PI.hProcess;
   try

     while True do
     begin
       if not WaitForDebugEvent(DE, 100) then
       begin
         Application.ProcessMessages;
         Continue;
       end;
       
       ContinueStatus:=DBG_EXCEPTION_NOT_HANDLED;

       case de.dwDebugEventCode of
         EXIT_PROCESS_DEBUG_EVENT:
         begin
           ContinueDebugEvent(DE.dwProcessId, DE.dwThreadId, DBG_CONTINUE);
           Break;
         end;

         CREATE_PROCESS_DEBUG_EVENT:
         begin
           BaseOfImage:=DE.CreateProcessInfo.lpBaseOfImage;
         end;

         EXCEPTION_DEBUG_EVENT:
         begin
           if DE.Exception.ExceptionRecord.ExceptionCode=EXCEPTION_BREAKPOINT then
           begin
             ContinueStatus:=DBG_CONTINUE;
             // Обработка точки прерывания
           end;

         end;
       end;

       ContinueDebugEvent(DE.dwProcessId, DE.dwThreadId, ContinueStatus);
     end;
   finally
     FHProcess:=0;
     CloseHandle(PI.hProcess);
     CloseHandle(PI.hThread);
   end;
 end else RaiseLastWin32Error;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 if FHProcess<>0 then
 begin
   TerminateProcess(FHProcess, 999);
   FHProcess:=0;
 end;
end;

end.


На форме этого отладчика всего 2 кнопки. Button1 запускает отлаживаемое приложение, а Button2 завершает :)
Для экспериментов я взял стандартный блокнот, скопировав его из "C:\WINDOWS\Notepad.exe" в "C:\copy\Notepad.exe".
Так вот, если запустить блокнот кнопкой Button1, а потом его завершить кнопкой Button2, то после этого невозможно удалить файл "C:\copy\Notepad.exe", хотя в списках процессов он уже незначится... :(


 
Игорь Шевченко ©   (2009-04-27 18:11) [6]


> Так вот, если запустить блокнот кнопкой Button1, а потом
> его завершить кнопкой Button2, то после этого невозможно
> удалить файл "C:\copy\Notepad.exe", хотя в списках процессов
> он уже незначится... :(


А что говорит Process Explorer ?


> procedure TForm1.Button2Click(Sender: TObject);
> begin
>  if FHProcess<>0 then
>  begin
>    TerminateProcess(FHProcess, 999);
>    FHProcess:=0;
>  end;
> end;


TerminateProcess(FHProcess, 999);
CloseHandle(FHProcess);

?


 
Валигози ©   (2009-04-28 09:05) [7]


> Игорь Шевченко ©   (27.04.09 18:11) [6]
>
> А что говорит Process Explorer ?

Диспетчер задач? После нажатия Button2 процесс пропадает из диспетчера задач. Вобщем больше похоже на то, что я не до конца выполняю финализацию отладки (только вот как её правильно завершить?..).


> Игорь Шевченко ©   (27.04.09 18:11) [6]
>
> TerminateProcess(FHProcess, 999);
> CloseHandle(FHProcess);
>
> ?

FHProcess это просто копия PI.hProcess (присваивается после удачного CreateProcess) специально для того чтобы этот хэндл было видно в обработчике Button2 для вызова TerminateProcess. А сам хэндл PI.hProcess закрывается в любом случае в блоке try..finally..end.


 
Валигози ©   (2009-04-28 15:15) [8]

Эврика!!! Я нашёл! :)))
Действительно остаётся открытым один хэндл. Вот он: DE.CreateProcessInfo.hFile
Если в вышеприведённом примере произвести нижеприведённые ;) изменения, то файл отлаживаемого приложения, после завершения отладки ничем не лочится и легко удаляется...
CREATE_PROCESS_DEBUG_EVENT:
begin
 BaseOfImage:=DE.CreateProcessInfo.lpBaseOfImage;
 CloseHandle(DE.CreateProcessInfo.hFile);
end;



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2010.10.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.003 c
6-1228160302
uw
2008-12-01 22:38
2010.10.31
Подключение через VMware Network Adapter


2-1280660629
vegarulez
2010-08-01 15:03
2010.10.31
Вопрос про TRegExpr.


4-1240980041
ForumReader
2009-04-29 08:40
2010.10.31
Как получить список всех "дочек" элемента, если они одинаковы?


2-1281417193
И. Павел
2010-08-10 09:13
2010.10.31
Два почти одинаковых запроса выполняются по разному


15-1279830573
Юрий
2010-07-23 00:29
2010.10.31
С днем рождения ! 23 июля 2010 пятница





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский