2
0
Эх сурвалжийг харах

* explicitly unmask SIGSEGV, SIGILL, SIGBUS and SIGFPE at the start
of a new thread (should fix #9073)

git-svn-id: trunk@8265 -

Jonas Maebe 18 жил өмнө
parent
commit
4457538435

+ 1 - 1
rtl/darwin/pthread.inc

@@ -62,7 +62,7 @@ function  pthread_cond_init(_para1:Ppthread_cond_t;_para2:Ppthread_condattr_t):c
 function  pthread_cond_signal(_para1:Ppthread_cond_t):cint;cdecl;external 'c' name 'pthread_cond_signal';
 function  pthread_cond_wait(_para1:Ppthread_cond_t;_para2:Ppthread_mutex_t):cint;cdecl;external 'c' name 'pthread_cond_wait';
 function pthread_kill(__thread:pthread_t; __signo:cint):cint;cdecl;external 'c';
-
+function pthread_sigmask(how: cint; nset: psigset; oset: psigset): cint; cdecl; external 'c';
 
 // not yet implemented in Mac OS X 10.4.8!
 // function sem_init(__sem:Psem_t; __pshared:cint;__value:cuint):cint;cdecl; external 'c' name 'sem_init';

+ 1 - 0
rtl/freebsd/pthread.inc

@@ -63,6 +63,7 @@ function pthread_cond_init(_para1:Ppthread_cond_t;_para2:Ppthread_condattr_t):ci
 function pthread_cond_signal(_para1:Ppthread_cond_t):cint;cdecl;external;
 function pthread_cond_wait(_para1:Ppthread_cond_t;_para2:Ppthread_mutex_t):cint;cdecl;external;
 function pthread_kill(__thread:pthread_t; __signo:cint):cint;cdecl;external;
+function pthread_sigmask(how: cint; nset: psigset; oset: psigset): cint; cdecl; external;
 
 function sem_init(__sem:Psem_t; __pshared:cint;__value:dword):cint;cdecl; external;
 function sem_destroy(__sem:Psem_t):cint;cdecl;external ;

+ 16 - 10
rtl/linux/pthread.inc

@@ -34,6 +34,13 @@ Type
    TSemaphore = sem_t;
    PSemaphore = ^TSemaphore;
 
+{$ifndef FPC_USE_LIBC}
+   tlibc_sigset = array[0..(1024 div 32)-1] of cuLong;
+   plibc_sigset = ^tlibc_sigset;
+{$else not FPC_USE_LIBC}
+   tlibc_sigset = tsigset;
+   plibc_sigset = psigset;
+{$endif not FPC_USE_LIBC}
 
      TThreadPriority = (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical);
 
@@ -44,12 +51,6 @@ Type
        THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL
      );
 
-{
-  type
-     psigset_t = ^sigset_t;
-     sigset_t = DWORD; // unsigned long 32 bits
-}
-
   const
      _POSIX_THREAD_THREADS_MAX = 64;
      PTHREAD_THREADS_MAX = 512;
@@ -127,6 +128,8 @@ Type
     function pthread_attr_getschedpolicy(__attr:ppthread_attr_t; __policy:plongint):longint;cdecl;external;
     function pthread_attr_setinheritsched(__attr:ppthread_attr_t; __inherit:longint):longint;cdecl;external;
     function pthread_attr_getinheritsched(__attr:ppthread_attr_t; __inherit:plongint):longint;cdecl;external;
+    function pthread_attr_setstacksize(p: ppthread_attr_t;s:size_t):cint;cdecl;external;
+    function pthread_attr_getstacksize(p: ppthread_attr_t;s:psize_t):cint;cdecl;external;
     function pthread_attr_setscope(__attr:ppthread_attr_t; __scope:longint):longint;cdecl;external;
     function pthread_attr_getscope(__attr:ppthread_attr_t; __scope:plongint):longint;cdecl;external;
     function pthread_setschedparam(__target_thread:pthread_t; __policy:longint; __param:psched_param):longint;cdecl;external;
@@ -159,11 +162,12 @@ Type
     procedure pthread_testcancel;cdecl;external;
 {    procedure _pthread_cleanup_push(__buffer:p_pthread_cleanup_buffer;__routine:t_pthread_cleanup_push_routine; __arg:pointer);cdecl;external; }
 {    procedure _pthread_cleanup_push_defer(__buffer:p_pthread_cleanup_buffer;__routine:t_pthread_cleanup_push_defer_routine; __arg:pointer);cdecl;external;}
-{    function pthread_sigmask(__how:longint; __newmask:psigset_t; __oldmask:psigset_t):longint;cdecl;external;}
+{    function pthread_sigmask(__how:longint; __newmask:plibc_sigset; __oldmask:plibc_sigset):longint;cdecl;external;}
     function pthread_kill(__thread:pthread_t; __signo:longint):longint;cdecl;external;
-{    function sigwait(__set:psigset_t; __sig:plongint):longint;cdecl;external;}
+{    function sigwait(__set:plibc_sigset; __sig:plongint):longint;cdecl;external;}
     function pthread_atfork(__prepare:tprocedure ; __parent:tprocedure ; __child:tprocedure ):longint;cdecl;external;
     procedure pthread_kill_other_threads_np;cdecl;external;
+    function pthread_sigmask(how: cint; nset: plibc_sigset; oset: plibc_sigset): cint; cdecl; external;
 
     function sem_init (__sem:Psem_t; __pshared:longint; __value:dword):longint;cdecl;external;
     function sem_destroy  (__sem:Psem_t):longint;cdecl;external;
@@ -227,11 +231,12 @@ Var
     pthread_testcancel : Procedure ;cdecl;
 {    _pthread_cleanup_push : procedure (__buffer:p_pthread_cleanup_buffer;__routine:t_pthread_cleanup_push_routine; __arg:pointer);cdecl;}
 {    _pthread_cleanup_push_defer : procedure (__buffer:p_pthread_cleanup_buffer;__routine:t_pthread_cleanup_push_defer_routine; __arg:pointer);cdecl;}
-{    pthread_sigmask : Function(__how:longint; __newmask:psigset_t; __oldmask:psigset_t):longint;cdecl;}
+{    pthread_sigmask : Function(__how:longint; __newmask:plibc_sigset; __oldmask:plibc_sigset):longint;cdecl;}
     pthread_kill : Function(__thread:pthread_t; __signo:longint):longint;cdecl;
-{    sigwait : Function(__set:psigset_t; __sig:plongint):longint;cdecl;}
+{    sigwait : Function(__set:plibc_sigset; __sig:plongint):longint;cdecl;}
     pthread_atfork : Function(__prepare:tprocedure ; __parent:tprocedure ; __child:tprocedure ):longint;cdecl;
     pthread_kill_other_threads_np : procedure;cdecl;
+    pthread_sigmask: Function(how: cint; nset: plibc_sigset; oset: plibc_sigset): cint;
 
     sem_init     :   function (__sem:Psem_t; __pshared:longint; __value:dword):longint;cdecl;
     sem_destroy  :   function (__sem:Psem_t):longint;cdecl;
@@ -308,6 +313,7 @@ begin
   Pointer(pthread_kill)  := dlsym(PthreadDLL,'pthread_kill');
   Pointer(pthread_atfork):= dlsym(PthreadDLL,'pthread_atfork');
   Pointer(pthread_kill_other_threads_np) := dlsym(PthreadDLL,'pthread_kill_other_threads_np');
+  Pointer(pthread_sigmask) := dlsym(PthreadDLL,'pthread_sigmask');
   Pointer(sem_init     ) := dlsym(PthreadDLL,'sem_init');
   Pointer(sem_destroy  ) := dlsym(PthreadDLL,'sem_destroy');
   Pointer(sem_close    ) := dlsym(PthreadDLL,'sem_close');

+ 1 - 0
rtl/solaris/pthread.inc

@@ -99,6 +99,7 @@ function  pthread_cond_init(_para1:Ppthread_cond_t;_para2:Ppthread_condattr_t):c
 function  pthread_cond_signal(_para1:Ppthread_cond_t):cint;cdecl;external 'c' name 'pthread_cond_signal';
 function  pthread_cond_wait(_para1:Ppthread_cond_t;_para2:Ppthread_mutex_t):cint;cdecl;external 'c' name 'pthread_cond_wait';
 function pthread_kill(__thread:pthread_t; __signo:cint):cint;cdecl;external 'c';
+function pthread_sigmask(how: cint; nset: psigset; oset: psigset): cint; cdecl; external 'c';
 
 function sem_init(__sem:Psem_t; __pshared:cint;__value:cuint):cint;cdecl; external 'c' name 'sem_init';
 function sem_destroy(__sem:Psem_t):cint;cdecl;external 'c' name 'sem_destroy';

+ 23 - 1
rtl/unix/cthreads.pp

@@ -3,7 +3,7 @@
     Copyright (c) 2002 by Peter Vreman,
     member of the Free Pascal development team.
 
-    Linux (pthreads) threading support implementation
+    pthreads threading support implementation
 
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
@@ -184,6 +184,10 @@ Type  PINTRTLEvent = ^TINTRTLEvent;
     function ThreadMain(param : pointer) : pointer;cdecl;
       var
         ti : tthreadinfo;
+        nset: tsigset;
+{$if defined(linux) and not defined(FPC_USE_LIBC)}
+        nlibcset: tlibc_sigset;
+{$endif linux/no FPC_USE_LIBC}
 {$ifdef DEBUG_MT}
         // in here, don't use write/writeln before having called
         // InitThread! I wonder if anyone ever debugged these routines,
@@ -198,6 +202,24 @@ Type  PINTRTLEvent = ^TINTRTLEvent;
         s := 'New thread started, initing threadvars'#10;
         fpwrite(0,s[1],length(s));
 {$endif DEBUG_MT}
+        { unblock all signals we are interested in (may be blocked by }
+        { default in new threads on some OSes, see #9073)             }
+        fpsigemptyset(nset);
+        fpsigaddset(nset,SIGSEGV);
+        fpsigaddset(nset,SIGBUS);
+        fpsigaddset(nset,SIGFPE);
+        fpsigaddset(nset,SIGILL);
+{$if defined(linux) and not defined(FPC_USE_LIBC)}
+        { sigset_t has a different size for linux/kernel and linux/libc }
+        fillchar(nlibcset,sizeof(nlibcset),0);
+        if (sizeof(nlibcset)>sizeof(nset)) then
+          move(nset,nlibcset,sizeof(nset))
+        else
+          move(nset,nlibcset,sizeof(nlibcset));
+        pthread_sigmask(SIG_UNBLOCK,@nlibcset,nil);
+{$else linux}
+        pthread_sigmask(SIG_UNBLOCK,@nset,nil);
+{$endif linux}
         { Allocate local thread vars, this must be the first thing,
           because the exception management and io depends on threadvars }
         CAllocateThreadVars;