Browse Source

* added CheckInitialStkLen() function which checks whether the given stack size value is valid on the OS when creating a thread, fixing stack checking

git-svn-id: trunk@1722 -
tom_at_work 19 years ago
parent
commit
1b4b42fdd6

+ 5 - 0
rtl/beos/system.pp

@@ -519,6 +519,11 @@ begin
   OpenStdIO(StdErr,fmOutput,StdErrorHandle);
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
+
 begin
 { Setup heap }
   zero:=0;

+ 5 - 1
rtl/bsd/system.pp

@@ -242,11 +242,15 @@ begin
  GetProcessID := SizeUInt (fpGetPID);
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
 
 Begin
   IsConsole := TRUE;
   IsLibrary := FALSE;
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := Sptr - StackLength;
   { Set up signals handlers }
   InstallSignals;

+ 5 - 1
rtl/gba/system.pp

@@ -245,11 +245,15 @@ begin
  GetProcessID := SizeUInt (fpGetPID);
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
 
 Begin
 ///-F-///  IsConsole := TRUE;
 ///-F-///  IsLibrary := FALSE;
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := Sptr - StackLength;
   { Set up signals handlers }
   InstallSignals;

+ 6 - 1
rtl/go32v2/system.pp

@@ -610,10 +610,15 @@ begin
  GetProcessID := SizeUInt (Go32_info_block.pid);
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
+
 var
   temp_int : tseginfo;
 Begin
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := __stkbottom;
   { To be set if this is a GUI or console application }
   IsConsole := TRUE;

+ 11 - 1
rtl/inc/system.inc

@@ -45,7 +45,17 @@ var
   emptychar : char;public name 'FPC_EMPTYCHAR';
   initialstklen : SizeUint;external name '__stklen';
 
-
+{ checks whether the given suggested size for the stack of the current
+ thread is acceptable. If this is the case, returns it unaltered. 
+ Otherwise it should return an acceptable value.
+ 
+ Operating systems that automatically expand their stack on demand, should 
+ simply return a very large value.
+ Operating systems which do not have a possibility to retrieve stack size
+ information, should simply return the given stklen value (This is the default 
+ implementation).
+}
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt; forward;
 
 {****************************************************************************
                     Include processor specific routines

+ 1 - 1
rtl/inc/thread.inc

@@ -32,7 +32,7 @@ Var
         InOutRes:=0;
         // ErrNo:=0;
         { Stack checking }
-        StackLength:=stklen;
+        StackLength:= CheckInitialStkLen(stkLen);
         StackBottom:=Sptr - StackLength;
         ThreadID := CurrentTM.GetCurrentThreadID();
       end;

+ 3 - 1
rtl/linux/osdefs.inc

@@ -33,4 +33,6 @@
   {$endif}
 {$endif}
 
-
+{$if defined(cpupowerpc) or defined(cpupowerpc64) or defined(cpux86)}
+  {$DEFINE has_ugetrlimit}
+{$endif}

+ 15 - 1
rtl/linux/ossysc.inc

@@ -458,7 +458,6 @@ begin
   FPsigprocmask:=do_syscall(syscall_nr_rt_sigprocmask,TSysParam(how),TSysParam(nset),TSysParam(oset),TSysParam(8));
 end;
 
-
 Function FpNanoSleep(req : ptimespec;rem : ptimespec):cint; [public, alias : 'FPC_SYSC_NANOSLEEP'];
 begin
   FpNanoSleep:=Do_SysCall(syscall_nr_nanosleep,TSysParam(req),TSysParam(rem));
@@ -473,3 +472,18 @@ begin
  fpgettimeofday:=do_syscall(syscall_nr_gettimeofday,TSysParam(tp),TSysParam(tzp));
 end;
 
+
+function FpGetRLimit(resource : cInt; rlim : PRLimit) : cInt;
+begin
+  FpGetRLimit := do_syscall(syscall_nr_getrlimit, 
+    TSysParam(resource), TSysParam(@rlim));
+end;
+
+{$ifdef HAS_UGETRLIMIT}
+function fpugetrlimit(resource : cInt; rlim : PRLimit) : cInt;
+begin
+  FpUGetRLimit := do_syscall(syscall_nr_ugetrlimit,
+    syscall_nr_getrlimit, 
+    TSysParam(resource), TSysParam(@rlim));
+end;
+{$endif}

+ 22 - 0
rtl/linux/ostypes.inc

@@ -309,6 +309,28 @@ CONST
   F_SetOwn = 8;
   F_GetOwn = 9;
 
+{ getrlimit/ugetrlimit resource parameter constants }
+const
+  RLIMIT_CPU = 0;       { CPU time in ms  }
+  RLIMIT_FSIZE = 1;     { Maximum filesize  }
+  RLIMIT_DATA = 2;      { max data size  }
+  RLIMIT_STACK = 3;     { max stack size  }
+  RLIMIT_CORE = 4;      { max core file size  }
+  RLIMIT_RSS = 5;       { max resident set size  }
+  RLIMIT_NPROC = 6;     { max number of processes  }
+  RLIMIT_NOFILE = 7;    { max number of open files  }
+  RLIMIT_MEMLOCK = 8;   { max locked-in-memory address space  }
+  RLIMIT_AS = 9;        { address space limit(?)  }
+  RLIMIT_LOCKS = 10;    { maximum file locks held  }
+
+type
+  rlim_t = cULong;
+  PRLimit = ^TRLimit;
+  TRLimit = record
+    rlim_cur : rlim_t;
+    rlim_max : rlim_t;
+  end;
+
     {*************************************************************************}
     {                               SIGNALS                                   }
     {*************************************************************************}

+ 18 - 1
rtl/linux/system.pp

@@ -231,12 +231,29 @@ begin
  GetProcessID := SizeUInt (fpGetPID);
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+var
+  limits : TRLimit;
+  success : boolean;
+begin
+  success := false;
+  fillchar(limits, sizeof(limits), 0);
+  {$ifdef has_ugetrlimit}
+  success := fpugetrlimit(RLIMIT_STACK, @limits)=0;
+  {$endif}
+  if (not success) then
+    success := fpgetrlimit(RLIMIT_STACK, @limits)=0;
+  if (success) and (limits.rlim_cur < stklen) then
+    result := limits.rlim_cur
+  else
+    result := stklen;
+end;
 
 Begin
   SysResetFPU;
   IsConsole := TRUE;
   IsLibrary := FALSE;
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(initialStkLen);
   StackBottom := Sptr - StackLength;
   { Set up signals handlers }
   InstallSignals;

+ 6 - 1
rtl/macos/system.pp

@@ -476,6 +476,11 @@ begin
 {$WARNING To be implemented - using GetProcessInformation???}
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
+
 var
   resHdl: Mac_Handle;
   isFolder, hadAlias, leafIsAlias: Boolean;
@@ -509,7 +514,7 @@ begin
   { To be set if this is a library and not a program  }
   IsLibrary := FALSE;
 
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := SPtr - StackLength;
   pathTranslation:= false;
 

+ 6 - 1
rtl/morphos/system.pp

@@ -301,12 +301,17 @@ begin
  GetProcessID:=SizeUInt(FindTask(NIL));
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
+
 
 begin
   SysResetFPU;
   IsConsole := TRUE;
   IsLibrary := FALSE;
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := Sptr - StackLength;
 { OS specific startup }
   MOS_ambMsg:=nil;

+ 4 - 1
rtl/netwlibc/system.pp

@@ -509,7 +509,10 @@ begin
 end;
 
 
-
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
 {*****************************************************************************
                          SystemUnit Initialization
 *****************************************************************************}

+ 5 - 0
rtl/palmos/system.pp

@@ -104,6 +104,11 @@ begin
  GetProcessID := 1;
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
+
 begin
    ExitCode:=0;
 end.

+ 5 - 1
rtl/solaris/system.pp

@@ -206,11 +206,15 @@ begin
  GetProcessID := SizeUInt (fpGetPID);
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
 
 Begin
   IsConsole := TRUE;
   IsLibrary := FALSE;
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := Sptr - StackLength;
 { Set up signals handlers }
   InstallSignals;

+ 4 - 0
rtl/unix/oscdeclh.inc

@@ -86,6 +86,10 @@ Type TGrpArr = Array [0..0] of TGid;            { C style array workarounds}
     Function  fpReadLink           (name,linkname:pchar;maxlen:size_t):cint;  cdecl; external clib name 'readlink';
     Function  FpUmask       (cmask : TMode): TMode; cdecl; external clib name 'umask';
     function  fpsettimeofday(tp:ptimeval;tzp:ptimezone):cint; cdecl; external clib name 'settimeofday';
+    function FpGetRLimit(resource : cInt; rlim : PRLimit) : cInt; cdecl; external clib name 'getrlimit';
+    {$ifdef HAS_UGETRLIMIT}
+    function FpGetRLimit(resource : cInt; rlim : PRLimit) : cInt; cdecl; external clib name 'ugetrlimit';
+    {$endif}
 
 {$ifdef linux}
 {$ifndef FPC_IS_SYSTEM}

+ 4 - 0
rtl/watcom/system.pp

@@ -1489,6 +1489,10 @@ begin
  GetProcessID := 1;
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
 
 var
   temp_int : tseginfo;

+ 5 - 1
rtl/win32/system.pp

@@ -1118,13 +1118,17 @@ begin
  GetProcessID := ProcessID;
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
 
 const
    Exe_entry_code : pointer = @Exe_entry;
    Dll_entry_code : pointer = @Dll_entry;
 
 begin
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := Sptr - StackLength;
   { get some helpful informations }
   GetStartupInfo(@startupinfo);

+ 5 - 1
rtl/win64/system.pp

@@ -1067,13 +1067,17 @@ begin
  GetProcessID := ProcessID;
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
 
 const
    Exe_entry_code : pointer = @Exe_entry;
    Dll_entry_code : pointer = @Dll_entry;
 
 begin
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := Sptr - StackLength;
   { get some helpful informations }
   GetStartupInfo(@startupinfo);

+ 6 - 1
rtl/wince/system.pp

@@ -1635,12 +1635,17 @@ begin
  GetProcessID := ProcessID;
 end;
 
+function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
+begin
+  result := stklen;
+end;
+
 const
    Exe_entry_code : pointer = @Exe_entry;
    Dll_entry_code : pointer = @Dll_entry;
 
 begin
-  StackLength := InitialStkLen;
+  StackLength := CheckInitialStkLen(InitialStkLen);
   StackBottom := Sptr - StackLength;
   { Enable FPU exceptions }
   _controlfp(1, $0008001F);