Here's a sample code snippet that throws an exception to another thread. It uses SuspendThreadto stop the stream, GetThreadContextto read the registers of the threads, changes EIP(instruction pointer), uses SetThreadContext, and then ResumeThreadto restart the stream. He works!
Unit UKilThread
Well packaged for reuse, which provides the procedure AbortThread():
unit UKillThread;
interface
uses Classes, Windows, SysUtils;
procedure AbortThread(const Th: TThread);
implementation
type EThreadAbort = class(EAbort);
procedure RaizeThreadAbort;
begin
raise EThreadAbort.Create('Thread was aborted using AbortThread()');
end;
procedure AbortThread(const Th: TThread);
const AlignAt = SizeOf(DWORD);
var Block:array[0..SizeOf(_CONTEXT)+512] of Byte;
ThContext: PContext;
begin
SuspendThread(Th.Handle);
ZeroMemory(@Block, SizeOf(Block));
ThContext := PContext(((Integer(@Block) + AlignAt - 1) div AlignAt) * AlignAt);
ThContext.ContextFlags := CONTEXT_FULL;
if not GetThreadContext(Th.Handle, ThContext^) then
RaiseLastOSError;
ThContext.Eip := Cardinal(@RaizeThreadAbort);
SetThreadContext(Th.Handle, ThContext^);
ResumeThread(Th.Handle);
end;
end.
Demo project
Here's how to use AbortThread:
program Project23;
{$APPTYPE CONSOLE}
uses
SysUtils,
Classes,
Windows,
UKillThread;
var Th: TThread;
type
TTestThread = class(TThread)
public
procedure Execute;override;
end;
{ TTestTrehad }
procedure TTestThread.Execute;
var N: Integer;
begin
try
N := 1;
while not Terminated do
begin
WriteLn(N);
Inc(N);
Sleep(1000);
end;
except on E:Exception do
WriteLn(E.ClassName + ' / ' + E.Message);
end;
end;
begin
Th := TTestThread.Create(False);
WriteLn('Press ENTER to raize exception in Thread');
ReadLn;
AbortThread(Th);
WriteLn('Press ENTER to exit');
ReadLn;
end.
Renouncement
, , , . Terminate - Terminated (.. ), TerminateThread(). .NET Thread.Abort(). , .NET, , :
- ,
EAbort - . . , EAbort . - .
finally . try-finally, , , , . - ,
EnterCriticalSection try-finally, . MSDN EnterCriticalSection : "If a thread terminates while it has ownership of a critical section, the state of the critical section is undefined.". , , "", , , , .