Як правильно припинити відладку
Моя програма запускає іншу програму в режимі налагодження ( CreateProcess з прапорцями DEBUG_PROCESSorDEBUG_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
> мабуть якісь хендли все ж таки залишаються відкритими
Ну так з'ясуй які конкретно.
а FatalExit() не допоможе?
Просто дивно, що з цією проблемою (майже) ніхто не стикався (а якщо й стикався, то не вирішив її). Або може я надто сумбурно пояснив. Я тільки недавно зайнявся темою налагодження та постійно наступаю на граблі. :(
Я накидав урізану версію відладчика для експериментів: unit Unit1;
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;
в той час як True роблять почати якщо не WaitForDebugEvent(DE, 100), тоді почати Application.ProcessMessages; Продовжити; кінець;
case de.dwDebugEventCode of EXIT_PROCESS_DEBUG_EVENT: почати ContinueDebugEvent(DE.dwProcessId, DE.dwThreadId, DBG_CONTINUE); Перерва; кінець;
CREATE_PROCESS_DEBUG_EVENT: почати BaseOfImage:=DE.CreateProcessInfo.lpBaseOfImage; кінець;
EXCEPTION_DEBUG_EVENT: почати якщо DE.Exception.ExceptionRecord.ExceptionCode=EXCEPTION_BREAKPOINT тоді почати ContinueStatus:=DBG_CONTINUE; // Обробка точки прерывания кінець;
ContinueDebugEvent(DE.dwProcessId, DE.dwThreadId, ContinueStatus); кінець; нарешті FHProcess:=0; CloseHandle(PI.hProcess); CloseHandle(PI.hThread); кінець; end else RaiseLastWin32Error; кінець;
процедура TForm1.Button2Click(Відправник: TObject); почати якщо FHProcess<>0 тоді почати TerminateProcess(FHProcess, 999); FHProcess:=0; кінець; кінець;
А що говорить Process Explorer ?
> процедура TForm1.Button2Click(Відправник: TObject); > почати > якщо FHProcess<>0 тоді > почати > TerminateProcess(FHProcess, 999); > FHProcess:=0; > кінець; > кінець;