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

Debugger not showing values of internal subprogram variables

Moonkyu_H_
Beginner
2,755 Views

Hi,

I've just noticed that my debugger was not always showing contents of internal subprogram variables.   I've made a few observations based on the test program below.

1. The local variables defined in the internal subprogram can be watched without any problem.

2. When the internal subprogram is within the external subroutine, none of the variables can be watched if they are defined in the calling subprogram.  In other words, I could not watch all the host associated variables.

3. If the internal subprogram is contained within the main program, I got mixed results for the host associated variables.  In the test program, I could watch array variable 'area' but not the integer 'nsize'.

Note that the program itself is working as intended.  I am having only debugger watching variable issue.  Is there any debugger setting that I can try to resolve this ?  

My system: Windows 7 64-bits SP1, Parallel Studio, XE 2016 Composer, VS Premium 2013, MS Visual C++ 2010 x64 redistributable, MS Visual C++ 2010 x86 redistributable, 

Thanks,

Moonkyu

 

 

Program Main

    IMPLICIT NONE
       
    INTEGER :: nsize
    REAl, DIMENSION(5) :: area = (/1.0, 2.0, 3.0, 4.0, 5.0/)
    REAL :: sum_area, ave_area, ave1_area, ave2_area
    
    sum_area=SUM(area)
    nsize=SIZE(area)
    ave_area=sum_area/nsize
    
    CALL find_ave1(ave1_area)
    
    CALL find_ave2(area, nsize, ave2_area)
    
    CONTAINS
    
    SUBROUTINE find_ave1(average)
        
        INTEGER :: i
        REAL :: average
        
        average = 0.0
        DO i = 1, nsize
        average = average + area(i)
        END DO
        average=average/nsize      
        
    END SUBROUTINE find_ave1
    
END PROGRAM

SUBROUTINE find_ave2 (array, nsize, average)
!   subroutine to find the average of the 'array'

    IMPLICIT NONE
    
    INTEGER :: nsize
    REAL :: array(nsize), sumval, average
    
    CALL find_sum
    average = sumval/nsize
        
    CONTAINS
    
    SUBROUTINE find_sum
!   internal subprogram to find the sum of 'array'    
    
    INTEGER :: i
    
    sumval = 0.0
    DO i=1, nsize
        sumval = sumval + array(i)
    END DO
    
    END SUBROUTINE

END SUBROUTINE find_ave2

 

0 Kudos
15 Replies
andrew_4619
Honored Contributor III
2,755 Views

for module variables you can watch modulename::varname  maybe in your case you can watch main::varname. Just a guess by the way.

0 Kudos
Moonkyu_H_
Beginner
2,755 Views

Thank you for the suggestion, but that didn't work.  

0 Kudos
Georg_Z_Intel
Employee
2,755 Views

Hello,

first, thank you for the test code! I tried it but I cannot directly reproduce your findings. Could you please also provide your build (compiler & linker) options? Furthermore, I assume you're also using the initial version of Intel(R) Parallel Studio XE 2016 and not the previous BETA? If you omit "/nologo" you should see:
Intel(R) Visual Fortran Compiler for applications running on IA-32, Version 16.0 Build 20150815

The locals window should only show the variables defined in the corresponding scope (stack frame). Inlining and optimizations, of course can mix that. So, compiling w/o any inlining (i.e. /Qipo or /Qip) and w/o optimizations (just use /Od) is required.

If I do so, I see that "area" (real, dim(5)) is visible within subroutine "find_ave1". All other locals shown are only defined within the respective scope (i.e. subroutine).

Should you still have different results I'd like to reproduce them on my system first before I head over to engineering for further discussion.

Thank you & best regards,

Georg Zitzlsberger

0 Kudos
Moonkyu_H_
Beginner
2,755 Views

Hi Georg,

Yes, I am using Intel Parallel Studio 2016 regular version, and I just confirmed the message below:

1>Intel(R) Visual Fortran Compiler for applications running on IA-32, Version 16.0 Build 20150815

So, I have two internal subroutines here, one of them is "find_ave1" contained in the "Main" and the other is "find_sum" in the subroutine "find_ave2".  As I said in the OP, the debugger behaviors are different depending where I am, either in the "find_ave1" or "find_sum".

1) When I am in the internal subroutine "find_ave1" (contained in the Main):

I can see the values of area(i), but not nsize.  Please note that both variables were defined in the host program which is "Main".  Now, if you change the Stack Frame to "Main", I can see the value for variable nsize too.  

2) When I am in the internal subroutine "find_sum" (contained in the subroutine "find_ave2"):  

Both variables "array" and "nsize" are not visible at all, regardless of the Stack Frame setting.  However, I could see the "sumval" if I set the Stack Frame to the calling routine which is "subroutine find_ave2".

Thank you for helping me.

Moonkyu

 

 

 

0 Kudos
Moonkyu_H_
Beginner
2,755 Views

Attached is the VS project.  Thanks

0 Kudos
Georg_Z_Intel
Employee
2,755 Views

Hello Moonkyu,

that's what I'm observing too and hence we should be aligned. I suspect this is a debug information concern for the compiler team and therefore I've created an internal ticket for this (DPD200575012).

One thing I'd like to clarify though:
If one subroutine calls another one you'll only see dummy arguments and locally declared variables in the "Locals" window (or common blocks if any). This means that for your example, array "AREA" shouldn't be visible within subroutine "find_ave1". Everything else is as expected.

Best regards,

Georg Zitzlsberger

0 Kudos
Moonkyu_H_
Beginner
2,755 Views

Hi Georg,

I am sure you are already very familiar with 'internal subprogram' which behaves quite differently from regular subprograms.  But just to clarify, all the variables in the internal subroutine, if neither explicitly defined within itself as locals nor connected through the formal arguments, are entities in its host scoping unit.  

I am not quite sure what you meant by saying the the array "AREA' shouldn't be visible within subroutine "find_ave1" and everything else is as expected.  I believe the debugger should be able to show the array AREA or any "host associated variables".   Were you mentioning the current limitation of the debugger ?

Thanks,

Moonkyu 

 

 

 

0 Kudos
Georg_Z_Intel
Employee
2,755 Views

Hello Moonkyu,

you're right. I'm too much into C and "internal subroutines" are something I was not aware of (directly).
I've changed the ticket accordingly to say:

find_ave1 is an internal subroutine to main and hence stopping in it should show the following locals:

! from main
    INTEGER :: nsize
    REAl, DIMENSION(5) :: area = (/1.0, 2.0, 3.0, 4.0, 5.0/)
    REAL :: sum_area, ave_area, ave1_area, ave2_area
! from find_ave1
        INTEGER :: i
        REAL :: average

 

Same for find_sum being an internal subroutine of find_ave2. Hence stopping in find_sum should show the following locals:
! from find_ave2
    INTEGER :: nsize
    REAL :: array(nsize), sumval, average
! from find_sum
    INTEGER :: i

It looks like we miss some of the internal subroutine/function/subprogram handling in the debug information. I wonder whether those are limitations since we use the debug information format msdia which we cannot change. Nevertheless, as soon as I have a response from engineering I'll update the thread at hand.

Thank you for your explanations & best regards,

Georg Zitzlsberger

0 Kudos
Moonkyu_H_
Beginner
2,755 Views

Hi Georg,

Thank you for the update.   You probably may want to ask the following ticket, where non-host associated variables have been removed.  

Regards,

Moonkyu

 

find_ave1 is an internal subroutine to main and hence stopping in it should show the following locals:

! from main
    INTEGER :: nsize
    REAl, DIMENSION(5) :: area = (/1.0, 2.0, 3.0, 4.0, 5.0/)

! from find_ave1
        INTEGER :: i
        REAL :: average

 

Same for find_sum being an internal subroutine of find_ave2. Hence stopping in find_sum should show the following locals:
! from find_ave2
    INTEGER :: nsize
    REAL :: array(nsize), sumval 
! from find_sum
    INTEGER :: i

0 Kudos
andrew_4619
Honored Contributor III
2,755 Views

The normal debugger behaviour with module variables is to only be able to track variables that are actually referenced in the subroutine. This makes sense to me as there might be many thousands of variables in scope but you will normally only be interesting in variables you are actually working with at the time. You could be swamped with information.

For module variables you can access other vars that are in scope with modulename::varname . I expect there will be some similar syntax that will allow you to watch the non-referenced but host associated variables that are in scope.

 

0 Kudos
andrew_4619
Honored Contributor III
2,755 Views

The normal debugger behaviour with module variables is to only be able to track variables that are actually referenced in the subroutine. This makes sense to me as there might be many thousands of variables in scope but you will normally only be interesting in variables you are actually working with at the time. You could be swamped with information.

For module variables you can access other vars that are in scope with modulename::varname . I expect there will be some similar syntax that will allow you to watch the non-referenced but host associated variables that are in scope.

0 Kudos
Moonkyu_H_
Beginner
2,755 Views

My issue is just that.  When I am within an "internal subroutine", I am not able to view the values of the variables which are actually being used in that subroutine.  No, I am not interested in the all the variables defined in the calling or hosing program, but I want to know the values of the variables being used or modified in the current scope I am working on.  I've been having this issue both for module variables and regular variables.

0 Kudos
Georg_Z_Intel
Employee
2,755 Views

Hello,

I've had a talk with our debugger engineers who in turn checked with the compiler's debug information team. There's a problem:

I understand what you want but that would require major efforts. The current implementation only knows about the stack frames and interleaving (selected) variables between them is neither trivial nor straight forward. So, to implement bringing used variables from outer stack frames within an internal subprogram is a feature request with a low chance to be realized.

So, this is what I propose:

- There is a limited workaround: You can manually change the call stack (walk to the calling subroutine/function) and peek at the variables. Downside is that modifications done by the called internal subprogram on a temporary copy of such a variable might not yet have been stored back. In such a case you'll still see the old value in the upper stack frame.

- We'll fix the inconsistent locals entry (array "area" within "find_ave1") and only allow really local variables to be shown - no support for internal subprograms here but it'll be consistent. It'll also cover the case where variables up the stack frame were not evaluated correctly: in my case for a Win32 built, in subroutine "find_sum", walking up to "find_ave2" showed variables "average" and "nsize" as "undefined address".

- If you still want to have handling of internal subprograms I can file a feature request for this. However, odds are very low (almost zero) got get that implemented the next years.

Best regards,

Georg Zitzlsberger

0 Kudos
andrew_4619
Honored Contributor III
2,755 Views

IMO internal subprograms have quite limited uses, it is much better to make use of modules in which case you won't see this problem.

 

0 Kudos
Moonkyu_H_
Beginner
2,755 Views

Hi,

I am dealing with a commercial program package with more than half a million lines of Fortran 95, and it seems employing internal subprograms was a good decision.  It is already using module units extensively.  So, restructuring the program package is not an option here.

I've just tried and tested the test program under Cygwin, and found f95/gdb has passed the test without any issue.  The gdb was able to show all the variables used in the internal subroutines, and there was no need to take any extra steps at all.

Part of my job is to modify and upgrade the program package, and proper functioning of the debugger would be of great help.  

Regards,

Moonkyu

0 Kudos
Reply