Форум: "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