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

Debugging runtime subscript out of range errors

van_der_merwe__ben
New Contributor II
2,464 Views
I am using Visual Studio 2005 SP1 with Intel Fortran 10.0.027 in an application that contains C++, C and Fortran. All Fortran files are compiled with debug information using the settings provided below.

At some point I get a runtime error of the sort:

Visual Fortran run-time error
forrtl: severe(408): fort: (3): Subscript #1 of the array CINDEX has value -32 which is less than the lower bound of 1

That is great! I want to know that so I can debug it and find out what is happening. If I click ok on the error dialog box then I end up in the debugger but the stack reads:

> libifcoremdd.dll!20dd4d22()
[Frames below may be incorrect and/or missing, no symbols loaded for libifcoremdd.dll]

And the frames below are indeed not meaningful since Intel (unlike Microsoft) does not provide any PDB files which would allow you to get a full stack.

Is there a way to find out where that error is happening? Get a stack? I have tried making it skip over some assembly in libifcoremdd language to see if I can get it to return from the call and give me a stack, but no luck with that.

I can search for CINDEX in my files and use conditional breakpoints, except it is used numerous times in over 33 files.

The range check runtime errors used to (perhaps only the old Compaq compiler did it and and Intel doesnt do it?) pop up a nice huge big dialog box that also gave you the stack. Is there any way to get that behavior again or find out where this error is happening (other than recompiling it all under Compaq which I still have)? Is libifcoremdd.pdb perhaps available somehow?

Any suggestions would be very helpful.

(I could send this directly to premier support but only one contact can be listed on permier support and that person is not necessarily in the office. It would be really nice if you were not limited to one contact per company. That policy seems inconsistent with actually supporting the people who need it.)

/Zi
/Od
/W1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /c
/nologo /warn:nofileopt /Qzero /Qsave /align:rec1byte
/check:bounds
/iface:mixed_str_len_arg
/include:"c:PROGRA~1intelcompilerfortran100~1.027ia32Include"
/Fomobj32dxlib
/module:mobj32dxlib
/include:..Pfincludes /include:
/check:bounds /debug:full /dbglibs /warn:declarations /compile_only /define:"KLIB" /dll /threads /assume:byterecl /libs:dll
/define:KIFORTRAN

0 Kudos
7 Replies
Steven_L_Intel1
Employee
2,464 Views
Do you not see a stack frame for your code in the stack display? You do not need PDB info since none of the intervening frames are relevant.
0 Kudos
jimdempseyatthecove
Honored Contributor III
2,464 Views

First, is there a console window also displaying the subscript error? If so, check it for file name and line number.

Second, when stuck in the DLL, try stepping out of the subroutine. Often that will work. If you can keep stepping out, eventually you will get back to your code and you will find what call caused the error.

Jim Dempsey

0 Kudos
van_der_merwe__ben
New Contributor II
2,464 Views
The stack entries below libifcoewmss are clearly incorrect. (x.dll does not even contain any Fortran code)

The debugger shows this:

libifcoremdd.dll!20dd4d22()
[Frames below may be incorrect and/or missing, no symbols loaded for libifcoremdd.dll]
> x.dll!ClassRequiresDestruction(x * * t=0x00000000) Line 102 + 0x9 bytesC++
x.dll!HVector::Resize(int NewSize=54, int NewCapacity=81) Line 334 + 0x7 bytesC++
x.dll!HVector::ExpandBy(int N=-1, int At=24) Line 502C++
x.dll!HHashVector::Remove(x * const & Value=0xc445f659, unsigned char removeAll=',', unsigned char allowHashing=0) Line 374C++
00000040()
libifcoremdd.dll!20e56da5()
ntdll.dll!_RtlAllocateHeap@12() + 0xfc2 bytes
ntdll.dll!_RtlpCoalesceFreeBlocks@16() + 0x126b bytes

0 Kudos
van_der_merwe__ben
New Contributor II
2,464 Views
This is a windows application, so there is no console.
The Visual Studio output window contains nothing relevant about the crash other than:

"xxx.exe has triggered a breakpoint"

Trying to step out of the assembly language shown for libifcore causes the application to terminate.

Any ideas, please?
0 Kudos
van_der_merwe__ben
New Contributor II
2,464 Views
Here is a work around for anyone else who runs into this:

When this hit, go to the top of the stack, you will see assembly language for libifcoremdd.dll. If you look a little above the current execute point, you will see this:

20DD4CFB mov esp,ebp
20DD4CFD pop ebp
20DD4CFE ret

Set the debugger to the first line (using set next statement), even though it will complain about it being in a different routine. Now execute the "mov esp, ebp" instruction. As soon as you do it will enable the debugger to have another go at deciphering the stack and may see a partial stack that helps to narrow down the problem. You can also continue to execute assembly instructions because after about a half a dozen it will exit libifcoremdd.dll and you will be back in your code on the offending line.

(If course if we libifcoremdd.pdb, you would see the full correct stack right away....)
0 Kudos
Steven_L_Intel1
Employee
2,464 Views
With a Windows application, the diagnostic should appear in a message box. It may be behind the Visual Studio window.
0 Kudos
jimdempseyatthecove
Honored Contributor III
2,464 Views

Have you by chance overloaded new/delete? (either in your Fortran or C++ code)

It appears as if _RtlAllocateHeap@12 is calling libifcoremdd.dll???

This may be done inadvertantly (e.g. unfortunate choice of function name in your code). Or it may be by design. You will have to do some detective work to determine what is going on.

At the break, double click on the call stack entry for ntdll.dll!_RtlAllocateHeap@12. This should show you where you return to in that routine. Then look at the call immediately above the return point. This will a call into libifcoremdd.dll. Your program is hosed at this time so mucking around isn't going to hurt anything. If the call is using a register or registersfor address calculation then look further back in the code to find a point where the register is loaded. If a register is not being used then life is a little easier. Your stack is hosed, but it will not hurt to set the next instruction (right click on line in Dissassembly window) to the place that will reissue the call using Step Into to get intolivifcoremdd.dll. Once there you can see where it takes you. Hopefully has a symbolic name. And that name may help you diagnose the problem.

As an alternate method, you might have some luck placing a break point in ntdll.dll!_RtlpCoalesceFreeBlocks@16

It is hopefully not called too many times before you get the problem call.

The stack may be traceable from there. You may need to count how many times you must continue from that break point to get the error. Then rerun continuing that number-1 times. Then examine the call stack.

It is likely the call stack will show you additional ntdll.dll entries. the CoalesceFreeBlocks may be done out of necessity or it may be done pre-emptively. If pre-emptively, then when you are at the iteration where the call will fail then use Set Next Statement to bypass the call (being careful that the stack is not messed up with calling arguments to the function). Once you Set Next Statement after the call, use Step Out. You (hopefully) will make it back to the call to RtlpCoalesceFreeBlocks. Then use Step Out until the call stack shows your code.

This is not as difficult to do as it seems.

Good luck

Jim Dempsey

Jim Dempsey

0 Kudos
Reply