stack overflow question

stack overflow question

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.

12 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

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.

Steve - Intel Developer Support

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.

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.

Steve - Intel Developer Support

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:


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)


CODE OF THE CALLED ROUTINE:

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)

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!

Steve - Intel Developer Support

" 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.

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.

Best Reply

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.

Steve - Intel Developer Support

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.

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!

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.

Steve - Intel Developer Support

Laisser un commentaire

Veuillez ouvrir une session pour ajouter un commentaire. Pas encore membre ? Rejoignez-nous dès aujourd’hui