Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.10.31;
Скачать: CL | DM;

Вниз

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

 
Валигози ©   (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 вся ветка

Текущий архив: 2010.10.31;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.01 c
2-1281027372
Intranull
2010-08-05 20:56
2010.10.31
Назначение горячих клавиш для окна созданного на winapi


2-1281113383
nik9632
2010-08-06 20:49
2010.10.31
Ищу удачный вариант участка кода программы


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


2-1281008416
Irisss
2010-08-05 15:40
2010.10.31
Две панели в TaskBar


15-1279991329
SaveVideo
2010-07-24 21:08
2010.10.31
Не получается сохранить это видео