Browse Source

+ Win64 SEH: install a top-level exception handler around thread functions. This was a missing puzzle piece of SEH support. Now behavior of unhandled exceptions in non-main threads is consistent with that of main thread, and, in general, behavior of SEH-enabled RTL is consistent with one without SEH.

git-svn-id: trunk@23482 -
sergei 12 years ago
parent
commit
6788fd6433
2 changed files with 20 additions and 13 deletions
  1. 5 0
      rtl/win/systhrd.inc
  2. 15 13
      rtl/win64/system.pp

+ 5 - 0
rtl/win/systhrd.inc

@@ -225,7 +225,12 @@ var
 {$ifdef DEBUG_MT}
 {$ifdef DEBUG_MT}
         writeln('Jumping to thread function of thread ',Win32GetCurrentThreadId);
         writeln('Jumping to thread function of thread ',Win32GetCurrentThreadId);
 {$endif DEBUG_MT}
 {$endif DEBUG_MT}
+{$ifdef FPC_USE_WIN64_SEH}
+        { use special 'top-level' exception handler around the thread function }
+        ThreadMain:=main_wrapper(ti.p,pointer(ti.f));
+{$else FPC_USE_WIN64_SEH}
         ThreadMain:=ti.f(ti.p);
         ThreadMain:=ti.f(ti.p);
+{$endif FPC_USE_WIN64_SEH}
       end;
       end;
 
 
 
 

+ 15 - 13
rtl/win64/system.pp

@@ -125,6 +125,19 @@ implementation
 var
 var
   SysInstance : qword;public;
   SysInstance : qword;public;
 
 
+{$ifdef FPC_USE_WIN64_SEH}
+function main_wrapper(arg: Pointer; proc: Pointer): ptrint; assembler; nostackframe;
+asm
+    subq   $40, %rsp
+.seh_stackalloc 40
+.seh_endprologue
+    call   %rdx             { "arg" is passed in %rcx }
+    nop                     { this nop is critical for exception handling }
+    addq   $40, %rsp
+.seh_handler __FPC_default_handler,@except,@unwind
+end;
+{$endif FPC_USE_WIN64_SEH}
+
 { include system independent routines }
 { include system independent routines }
 {$I system.inc}
 {$I system.inc}
 
 
@@ -179,18 +192,6 @@ var
     to check if the call stack can be written on exceptions }
     to check if the call stack can be written on exceptions }
   _SS : Cardinal;
   _SS : Cardinal;
 
 
-{$ifdef FPC_USE_WIN64_SEH}
-procedure main_wrapper(p: TProcedure); assembler; nostackframe;
-asm
-    subq   $40, %rsp
-.seh_stackalloc 40
-.seh_endprologue
-    call   %rcx
-    nop                     { this nop is critical for exception handling }
-    addq   $40, %rsp
-.seh_handler __FPC_default_handler,@except,@unwind
-end;
-{$endif FPC_USE_WIN64_SEH}
 
 
 
 
 procedure Exe_entry;[public,alias:'_FPC_EXE_Entry'];
 procedure Exe_entry;[public,alias:'_FPC_EXE_Entry'];
@@ -209,7 +210,8 @@ procedure Exe_entry;[public,alias:'_FPC_EXE_Entry'];
         movq %rbp,%rsi
         movq %rbp,%rsi
         xorq %rbp,%rbp
         xorq %rbp,%rbp
 {$ifdef FPC_USE_WIN64_SEH}
 {$ifdef FPC_USE_WIN64_SEH}
-        lea  PASCALMAIN(%rip),%rcx
+        xor  %rcx,%rcx
+        lea  PASCALMAIN(%rip),%rdx
         call main_wrapper
         call main_wrapper
 {$else FPC_USE_WIN64_SEH}
 {$else FPC_USE_WIN64_SEH}
         call PASCALMAIN
         call PASCALMAIN