Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

stack overflow question

jvandeven
New Contributor I
1,766 Views

I recently encountered the stack over-flow error: Unhandled exception at 0x000007fef5cc94a1 in SIDD.exe: 0xC0000005: Access violation writing location 0x0000000000210ea0. when running some code through the VS debugger.  I am running IVF13.0.1 through VS 2010. Is there an analysis tool for determining at any time while debugging code how much of the stack is allocated to each of the variables that are loaded at that time?  Such a tool would help me identify which variables it would be most sensible to allocate to the heap to address this type of problem.

Many thanks,

Justin.

0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,766 Views
It might well be a stack problem. Easy way to find out. In the Fortran project properties, under Optimization, set "Heap Arrays" to 0. If you are building from the command line, add /heap-arrays . See what happens.

View solution in original post

0 Kudos
11 Replies
Steven_L_Intel1
Employee
1,766 Views
Why do you think this is a stack overflow? Usually the symptom of that is an explicit stack overflow error. (Not always, though.) I don't know of a ready way to determine the amount of stack used. Often the stack overflow occurs when an array temporary copy is made, and there's nothing you can ask about that. The most useful thing is knowing exactly where in the routine the overflow occurred - that usually is a good clue.
0 Kudos
jvandeven
New Contributor I
1,766 Views
The error code suggested to me that the problem was to do with memory allocation, and it goes away if I reduce memory requirements. That said, I tried increasing the (stack) memory allocation with the \F compiler option, but that did not resolve the issue, so the problem may be something else. My code is crashing when a specific subroutine is called. I am unable to walk the code past the initial line of the subroutine. I had thought that this may be due to a poorly defined variable passed to the subroutine, but omitting all but two integer variables from the list of variables passed to/from the subroutine did not help in any way. I am otherwise unsure how to proceed. Justin.
0 Kudos
Steven_L_Intel1
Employee
1,766 Views
It reads to me more like in a difference in expectations between caller and callee. Is an explicit interface for the called routine visible to the caller? Please show the declaration of the called routine and of all its arguments.
0 Kudos
jvandeven
New Contributor I
1,766 Views
Hi Steve - you must get tired of replying to non-programmers like me. I am not sure what you mean by an "explicit interface for the called routine visible to the caller". I provide the declaration of the called routine and all its arguments below, and the code that calls this routine. Both of these subroutines are in the same module. Global variables are contained in the modules: "global", "global_ParamStore", and "global_f1". CODE FROM THE CALLER ROUTINE: [fortran] SUBROUTINE c_soln(xx, ndim_inner, training_state, leisure, labour, prwage1, prwage2, emp1, emp2, training_choice, training_gain, opt_out, pens_takeup, & ri_am1, pc_am1, pcemp_am1, isa_am1, u, val, dv, dv2, upper_u) !******************************************************************************* ! ! Routine to solve for utility maximising consumption using Euler conditions ! !******************************************************************************* USE global USE global_ParamStore USE global_f1 !USE solve_Euler USE solve_ValCalls integer(4), intent(in) :: ndim_inner, training_choice, opt_out, pens_takeup, emp1, emp2 real(8), intent(in) :: xx(ndim_inner), training_state, leisure, labour, prwage1, prwage2, training_gain real(8), intent(in) :: ri_am1, pc_am1, pcemp_am1, isa_am1 real(8), intent(out) :: u, val, dv, dv2, upper_u ! local variables integer(4) :: pen_receive, nexp_c(nexp_d), n_exp, ii, flag_start real(8) :: lab_inc, bl_all, bu_all, pen_cost, isa_cost real(8) :: x_exp(max_prob, ndim_a), y_exp(max_prob), prob_exp(max_prob), Rpstt_exp(max_prob), ptbmr_exp(max_prob), mpc_exp(max_prob) real(8) :: vat0(max_prob), vat1(max_prob) real(8) :: A0, B0, C0 !****************************************************** ! begin code !****************************************************** !****************************************************** ! initialise variables !****************************************************** u = 0.0 val = 0.0 dv = 0.0 dv2 = 0.0 x_exp = 0.0_8 upper_u = 0.0 !****************************************************** ! initialise expectations !****************************************************** call exp_xs(x_exp, vat0, vat1, y_exp, pen_cost, isa_cost, Rpstt_exp, ptbmr_exp, mpc_exp, pen_receive, prob_exp, nexp_c, n_exp, ndim_inner, xx, & training_state, training_choice, training_gain, opt_out, pens_takeup, prwage1, prwage2, emp1, emp2, labour, & ri_am1, pc_am1, pcemp_am1, isa_am1, lab_inc) [/fortran] CODE OF THE CALLED ROUTINE: [fortran] SUBROUTINE exp_xs(x_exp, vat0, vat1, y_exp, pen_cost, isa_cost, Rpstt_exp, ptbmr_exp, mpc_exp, pen_receive, prob_exp, nexp_c, n_exp, ndim_inner, xx, & training_state, training_choice, training_gain, opt_out, pens_takeup, prwage1, prwage2, emp1, emp2, labour, & ri_am1, pc_am1, pcemp_am1, isa_am1, lab_inc) !************************************************************* ! ! Routine to augment probabilities and expectations for income ! - not done for period prior to mandatory retirement ! as expectation depends on wealth ! !************************************************************* USE global USE global_ParamStore USE global_f1 USE tax_preps_mod USE analysis_tools integer(4) :: pen_receive, ndim_inner, n_exp, training_choice, pens_takeup, nexp_c(nexp_d), opt_out, emp1, emp2 real(8) :: x_exp(max_prob, ndim_a), prob_exp(max_prob), ri_am1, pc_am1, pcemp_am1, isa_am1, training_gain real(8) :: y_exp(max_prob), Rpstt_exp(max_prob), ptbmr_exp(max_prob), mpc_exp(max_prob) real(8) :: training_state, prwage1, prwage2, labour, xx(ndim_inner), lab_inc, pen_cost, isa_cost real(8) :: vat0(max_prob), vat1(max_prob) [/fortran]
0 Kudos
Steven_L_Intel1
Employee
1,766 Views
If both of these routines are in a module, then that provides the explicit interface. (For a discussion on that topic, see here, but don't bother clicking on the links in the article because they are broken - will fix them when I can.) I don't spot a problem in the code you posted - in the called routine are there perhaps local variables (not part of the argument list) that are declared with array dimensions, such as somename(arg) where "arg" is a routine argument? And no, I don't get tired of replying to non-programmers. Actually, they're probably the easiest to reply to!
0 Kudos
jvandeven
New Contributor I
1,766 Views
" in the called routine are there perhaps local variables (not part of the argument list) that are declared with array dimensions, such as somename(arg) where "arg" is a routine argument?" There are a few: [fortran] real(8) :: prob_exp0(nexp_g0), w_exp0(nexp_g0), OP_exp0(nexp_g0), PP_exp0(nexp_g0), cp1_exp0(nexp_g0), cp2_exp0(nexp_g0), ob_exp0(nexp_g0) real(8) :: y_exp0(nexp_g0), Rpstt_exp0(nexp_g0), ptbmr_exp0(nexp_g0), mpc_exp0(nexp_g0), isa_exp0(nexp_g0) real(8) :: vat0_exp0(nexp_g0), vat1_exp0(nexp_g0), vat0_0, vat0_1, vat1_0 real(8) :: w_exp(max_prob), OP_exp(max_prob), PP_exp(max_prob), cp1_exp(max_prob), cp2_exp(max_prob), isa_exp(max_prob), ob_exp(max_prob) real(8) :: training_cost, tax_temp(9), taxinput(n_taxinput) [\fortran] but I have checked the (global) integer values nexp_g0, max_prob, and n_taxinput, and these are all assigned sensible numbers. This problem only arises when max_prob becomes large (15000 in the current case), which is why I thought it was a stack problem. I have also tried running the code through the Inspector tool, which didn't turn up any errors prior to the crash. Justin.
0 Kudos
mecej4
Honored Contributor III
1,766 Views
I think that there has been too much speculation in this thread as to the causes. Let us go back to the error message in the original post:Unhandled exception at 0x000007fef5cc94a1 in SIDD.exe: 0xC0000005: Access violation writing location 0x0000000000210ea0. That is the result of attempting to change memory that has been marked R/O. Both the program counter and the pointer to that memory are displayed. Using the debugger, or other methods, you can locate the line of code where that error occurred, and we can take things from there.
0 Kudos
Steven_L_Intel1
Employee
1,767 Views
It might well be a stack problem. Easy way to find out. In the Fortran project properties, under Optimization, set "Heap Arrays" to 0. If you are building from the command line, add /heap-arrays . See what happens.
0 Kudos
jvandeven
New Contributor I
1,766 Views
If I have understood the output correctly, the program counter refers to 0x000007fef5cc94a1. The debugger indicates dbghelp.dll!000007fef5cc94a1() at this location. A quick google search indicated that dbghelp is a windows help library, and that current versions of the library are rarely shipped. I downloaded and installed the most recent version of Microsoft Windows SDK (http://msdn.microsoft.com/en-US/windows/hardware/hh852363), and re-ran my program through the debugger. This returned the same error message, but with a counter of 7fefa8b94a1, which is also assocated with dbghelp.dll.
0 Kudos
jvandeven
New Contributor I
1,766 Views
I set "Heap Arrays" to 0 as Steve suggested, and the program now does not crash. So, I assume this is a problem with the stack - thanks for the useful tip to distinguish a stack overflow!
0 Kudos
Steven_L_Intel1
Employee
1,766 Views
Very good. I am fond of using Heap Arrays and have argued that it be the default - the equivalent in gfortran is the default. But it is a bit slower in benchmarks so it remains off by default.
0 Kudos
Reply