title: Stack overflow in Fortran 90
body: <p>I have written a fairly large program in Fortran 90. It has been working beautifully for quite a while, but today I tried to step it up a notch and increase the problem size (it is a research non-standard FE-solver, if that helps anyone...) Now I get the "stack overflow" error message and naturally the program terminates without giving me anything useful to work with.</p>
  
  <p>The program starts with setting up all relevant arrays and matrices, and after that is done it prints a few lines of stats regarding this to a log-file. Even with my new, larger problem, this works fine (albeit a little slow), but then it fails as the "number crunching" gets going.</p>
  
  <p>What confuses me is that everything at that point is already allocated (and that worked without errors). I'm not entirely sure what the stack is (Wikipedia and several treads here didn't do much since I have only a quite basic knowledge of the "behind the scenes" workings of a computer).</p>
  
  <p>Assume that I for instance have some arrays initialized as:</p>
  
  <pre><code>INTEGER,DIMENSION(64) :: IA
  REAL(8),DIMENSION(:,:),ALLOCATABLE :: AA, BB
  </code></pre>
  
  <p>which after some initialization routines (i.e. read input from file and such) are allocated as (I store some size-integers for easier passing to subroutines in IA of fixed size):</p>
  
  <pre><code>ALLOCATE( AA(N1,N2) , BB(N1,N2) )
  IA(1) = N1
  IA(2) = N2
  </code></pre>
  
  <p>This is basically what happens in the initial portion, and so far so good. But when I then call a subroutine</p>
  
  <pre><code>CALL ROUTINE_ONE(AA,BB,IA)
  </code></pre>
  
  <p>And the routine looks like (nothing fancy):</p>
  
  <pre><code>SUBROUTINE ROUTINE_ONE(AA,BB,IA)
  IMPLICIT NONE
  INTEGER,DIMENSION(64) :: IA
  REAL(8),DIMENSION(IA(1),IA(2)) :: AA, BB
  ...
  do lots of other stuff
  ...
  END SUBROUTINE ROUTINE_ONE
  </code></pre>
  
  <p>Now I get an error! The output to the screen says:</p>
  
  <pre><code>forrtl: severe (170): Program Exception - stack overflow
  </code></pre>
  
  <p>However, when I run the program with the debugger it breaks at line 419 in a file called <code>winsig.c</code> (not my file, but probably part of the compiler?). It seems to be part of a routine called <code>sigreterror:</code> and it is the default case that has been invoked, returning the text <code>Invalid signal or error</code>. There is a comment line attached to this which strangely says <code>/* should never happen, but compiler can't tell */</code> ...?</p>
  
  <p>So I guess my question is, why does this happen and what is actually happening? I thought that as long as I can allocate all the relevant memory I should be fine? Does the call to the subroutine make copies of the arguments, or just pointers to them? If the answer is copies then I can see where the problem might be, and if so: any ideas on how to get around it?</p>
  
  <p>The problem I try to solve is big, but not insane in any way. Standard FE-solvers can handle bigger problems than my current one. I run the program on a Dell PowerEdge 1850 and the OS is Microsoft Server 2008 R2 Enterprise. According to <code>systeminfo</code> at the <code>cmd</code> prompt I have 8GB of physical memory and almost 16GB virtual. As far as I understand the total of all my arrays and matrices should not add up to more than maybe 100MB - about 5.5M <code>integer(4)</code> and 2.5M <code>real(8)</code> (which according to me should be only about 44MB, but let's be fair and add another 50MB for overhead).</p>
  
  <p>I use the Intel Fortran compiler integrated with Microsoft Visual Studio 2008.</p>
  
  <hr>
  
  <p>Adding some actual source code to clarify a bit</p>
  
  <pre><code>! Update continuum state
  CALL UpdateContinuumState(iTask,iArray,posc,dof,dof_k,nodedof,elm,&amp;
                      bmtrx,detjac,w,mtrlprops,demtrx,dt,stress,strain,effstrain,&amp;
                      effstress,aa,fi,errmsg)
  </code></pre>
  
  <p>is the actual call to the routine. Big arrays are <code>posc</code>, <code>bmtrx</code> and <code>aa</code> - all other are at least an order of magnitude smaller (if not more). <code>posc</code> is <code>INTEGER(4)</code> and <code>bmtrx</code> and <code>aa</code> is <code>REAL(8)</code></p>
  
  <pre><code>SUBROUTINE UpdateContinuumState(iTask,iArray,posc,dof,dof_k,nodedof,elm,bmtrx,&amp;
                      detjac,w,mtrlprops,demtrx,dt,stress,strain,effstrain,&amp;
                      effstress,aa,fi,errmsg)
  
      IMPLICIT NONE
  
      !I/O
      INTEGER(4) :: iTask, errmsg
      INTEGER(4) :: iArray(64)
      INTEGER(4),DIMENSION(iArray(15),iArray(15),iArray(5)) :: posc
      INTEGER(4),DIMENSION(iArray(22),iArray(21)+1) :: nodedof
      INTEGER(4),DIMENSION(iArray(29),iArray(3)+2) :: elm
      REAL(8),DIMENSION(iArray(14)) :: dof, dof_k
      REAL(8),DIMENSION(iArray(12)*iArray(17),iArray(15)*iArray(5)) :: bmtrx
      REAL(8),DIMENSION(iArray(5)*iArray(17)) :: detjac
      REAL(8),DIMENSION(iArray(17)) :: w
      REAL(8),DIMENSION(iArray(23),iArray(19)) :: mtrlprops
      REAL(8),DIMENSION(iArray(8),iArray(8),iArray(23)) :: demtrx
      REAL(8) :: dt
      REAL(8),DIMENSION(2,iArray(12)*iArray(17)*iArray(5)) :: stress
      REAL(8),DIMENSION(iArray(12)*iArray(17)*iArray(5)) :: strain
      REAL(8),DIMENSION(2,iArray(17)*iArray(5)) :: effstrain, effstress
      REAL(8),DIMENSION(iArray(25)) :: aa
      REAL(8),DIMENSION(iArray(14)) :: fi 
  
      !Locals
      INTEGER(4) :: i, e, mtrl, i1, i2, j1, j2, k1, k2, dim, planetype, elmnodes, &amp;
          Nec, elmpnodes, Ndisp, Nstr, Ncomp, Ngpt, Ndofelm
      INTEGER(4),DIMENSION(iArray(15)) :: doflist
      REAL(8),DIMENSION(iArray(12)*iArray(17),iArray(15)) :: belm
      REAL(8),DIMENSION(iArray(17)) :: jelm
      REAL(8),DIMENSION(iArray(12)*iArray(17)*iArray(5)) :: dstrain
      REAL(8),DIMENSION(iArray(12)*iArray(17)) :: s
      REAL(8),DIMENSION(iArray(17)) :: ep, es, dep
      REAL(8),DIMENSION(iArray(15),iArray(15)) :: kelm
      REAL(8),DIMENSION(iArray(15)) :: felm
  
      dim       = iArray(1)
  ...
  </code></pre>
  
  <p>And it fails before the last line above.</p>