- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Hi All,
I have an application that throws an access violation when it hits a DEALLOCATE statement. The code below illustrates what I believe to be a boiled down version of what my code does, without all complexity:
MODULE one
TYPE test
INTEGER, POINTER, DIMENSION(:) :: subArray,
END TYPE test
TYPE(test) :: var
END MODULE one
MODULE two
USE one
CONTAINS
SUBROUTINE DoSomething
TYPE(test) :: opt
! Allocate the memory
CALL AllocMem(opt)
! Code that uses the subArray substructure
opt%subArray = 1
someVal = opt%subArray(3)
! Free the allocated memory
CALL FreeMem(opt)
END SUBROUTINE DoSomething
SUBROUTINE AllocMem(block)
TYPE(test) :: block
ALLOCATE(block(50))
END SUBROUTINE AllocMem
SUBROUTINE FreeMem(block)
TYPE(test) :: block
DEALLOCATE(block%subArray) ! Code dies here
END SUBROUTINE FreeMem
END MODULE two
Essentially, I call one routine to allocate a pointer array in a derived type, use that array, then call another routine to deallocate the memory. There is lots of other code and and operations on other data mixed in, and the derived type has more than just 1 substructure, but you get the idea.
If I run my code in the debugger, it dies right at the DEALLOCATE statement with the following stack trace:
V31113_R5TRIPMAP! __sbh_free_block + 371 bytes
V31113_R5TRIPMAP! free + 40 bytes
V31113_R5TRIPMAP! for_deallocate + 101 bytes
V31113_R5TRIPMAP! for_dealloc_allocatable + 85 bytes
CVTR5GLOBALDATA::CONVERTR5OPTIONS() line 186 + 67 bytes
Looking in the debugger, right before the DEALLOCATE is called, the array is properly allocated in that all array elements are there, and no data appears corrupted.
If I move the DEALLOCATE statement up out of FreeMem and right after the call to AllocMem, ala
CALL AllocMem(opt)
DEALLOCATE(opt%subArray)
the code still dies.
If I put the DEALLOCATE statement in AllocMem, then it deallocates the memory as expected.
I figure that somewhere else in the code, the code is clobbering memory that is adjacent to the array that I am attempting to deallocate, but before I spend a buttload of time tracking this down, my question is this:
Is it conceivable that this is instead a compiler bug?
Chris
I have an application that throws an access violation when it hits a DEALLOCATE statement. The code below illustrates what I believe to be a boiled down version of what my code does, without all complexity:
MODULE one
TYPE test
INTEGER, POINTER, DIMENSION(:) :: subArray,
END TYPE test
TYPE(test) :: var
END MODULE one
MODULE two
USE one
CONTAINS
SUBROUTINE DoSomething
TYPE(test) :: opt
! Allocate the memory
CALL AllocMem(opt)
! Code that uses the subArray substructure
opt%subArray = 1
someVal = opt%subArray(3)
! Free the allocated memory
CALL FreeMem(opt)
END SUBROUTINE DoSomething
SUBROUTINE AllocMem(block)
TYPE(test) :: block
ALLOCATE(block(50))
END SUBROUTINE AllocMem
SUBROUTINE FreeMem(block)
TYPE(test) :: block
DEALLOCATE(block%subArray) ! Code dies here
END SUBROUTINE FreeMem
END MODULE two
Essentially, I call one routine to allocate a pointer array in a derived type, use that array, then call another routine to deallocate the memory. There is lots of other code and and operations on other data mixed in, and the derived type has more than just 1 substructure, but you get the idea.
If I run my code in the debugger, it dies right at the DEALLOCATE statement with the following stack trace:
V31113_R5TRIPMAP! __sbh_free_block + 371 bytes
V31113_R5TRIPMAP! free + 40 bytes
V31113_R5TRIPMAP! for_deallocate + 101 bytes
V31113_R5TRIPMAP! for_dealloc_allocatable + 85 bytes
CVTR5GLOBALDATA::CONVERTR5OPTIONS() line 186 + 67 bytes
Looking in the debugger, right before the DEALLOCATE is called, the array is properly allocated in that all array elements are there, and no data appears corrupted.
If I move the DEALLOCATE statement up out of FreeMem and right after the call to AllocMem, ala
CALL AllocMem(opt)
DEALLOCATE(opt%subArray)
the code still dies.
If I put the DEALLOCATE statement in AllocMem, then it deallocates the memory as expected.
I figure that somewhere else in the code, the code is clobbering memory that is adjacent to the array that I am attempting to deallocate, but before I spend a buttload of time tracking this down, my question is this:
Is it conceivable that this is instead a compiler bug?
Chris
링크가 복사됨
8 응답
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Well, it is conceivable but very unlikely. What you observe look like typical symptoms of array bounds violations (expecially referring to subArray(0)); switch on "Array bounds checking" in Project/Settings/Fortran/Run time and fix the code when you find out where it occurs.
Jugoslav
Jugoslav
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Though the presented code does not compile at all in CVF6.6B, I think it shows a big mistake.
The subroutine AllocMem tries to allocate 50 elements of the derived type test, thus 50 elements containing a pointer to subarray; subarray itself is never allocated (at least in the presented code). But in the subroutine FreeMem you deallocate subarray, which is never allocated.
Guus
The subroutine AllocMem tries to allocate 50 elements of the derived type test, thus 50 elements containing a pointer to subarray; subarray itself is never allocated (at least in the presented code). But in the subroutine FreeMem you deallocate subarray, which is never allocated.
Guus
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Yeah, array bounds checking (and every other run-time check for that matter) is already turned on. What I get is specifically an access violation. The array is dimensioned from 1 to 90 (in my actual code; the example shows 50).
What I figured MIGHT be happening is that some sloppy coding on our part (leading to clobbered memory somewhere) is uncovering a flaw in the DEALLOCATE logic internal to the compiler. But I have been coding long enough to know that the mistakes are almost always my fault, so that is my first assumption. My only reason for asking the question is that this is going to be an incredibly difficult bug to track down and I wanted to make sure I wasn't chasing a ghost. Nobody else on my development team can reproduce this problem, so the weight is solely on my shoulders.
Thanks,
Chris
What I figured MIGHT be happening is that some sloppy coding on our part (leading to clobbered memory somewhere) is uncovering a flaw in the DEALLOCATE logic internal to the compiler. But I have been coding long enough to know that the mistakes are almost always my fault, so that is my first assumption. My only reason for asking the question is that this is going to be an incredibly difficult bug to track down and I wanted to make sure I wasn't chasing a ghost. Nobody else on my development team can reproduce this problem, so the weight is solely on my shoulders.
Thanks,
Chris
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
Before you continue, and since it's reproducible only in one machine, I'd first ask the classic sanity check:
Are you sure you're debugging the same code you see on the screen? Screwed date/time on your machine or source files or .obj files can cause havoc.
Ok, if you have passed the first test, I'd try to tackle it in the following manner:
- Immediately after allocate, open "Memory" debugger window and type the name of your derived-type variable. It should contain only the array descriptor, i.e. its contents shouldn't be changed during its lifetime.
- Step through the code in large steps and see whether the contents change; if they do, repeat it in smaller steps until you find the offending line. If they don't, um, I'm running out of ideas.
- If you put an stat= into deallocate, what does it return?
Jugoslav
Are you sure you're debugging the same code you see on the screen? Screwed date/time on your machine or source files or .obj files can cause havoc.
Ok, if you have passed the first test, I'd try to tackle it in the following manner:
- Immediately after allocate, open "Memory" debugger window and type the name of your derived-type variable. It should contain only the array descriptor, i.e. its contents shouldn't be changed during its lifetime.
- Step through the code in large steps and see whether the contents change; if they do, repeat it in smaller steps until you find the offending line. If they don't, um, I'm running out of ideas.
- If you put an stat= into deallocate, what does it return?
Jugoslav
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
I am not really sure what you mean by open the Memory window and type in the name of the derived type variable. Perhaps you meant the Watch window???
If I click on View, Debug Window, Memory, it opens up a dialog box whose top entry box indicates it is expecting a memory address, not variable name. The lower part of the box is filled with question marks for each memory address.
This brings up a question. Is it possible to watch locations in memory adjacent to a variable of interest? Is there some way to use the memory formatting symbols (i.e. ma, m, mb, etc) to print out the memory location of a variable, then use that info to track it in the Memory window?
Thanks for your time and patience on this, Jugoslav. I lurk on this site every so often. If it weren't for guys like you donating your time for the greater good, the FORTRAN community would be much worse off.
Chris
If I click on View, Debug Window, Memory, it opens up a dialog box whose top entry box indicates it is expecting a memory address, not variable name. The lower part of the box is filled with question marks for each memory address.
This brings up a question. Is it possible to watch locations in memory adjacent to a variable of interest? Is there some way to use the memory formatting symbols (i.e. ma, m, mb, etc) to print out the memory location of a variable, then use that info to track it in the Memory window?
Thanks for your time and patience on this, Jugoslav. I lurk on this site every so often. If it weren't for guys like you donating your time for the greater good, the FORTRAN community would be much worse off.
Chris
- 신규로 표시
- 북마크
- 구독
- 소거
- RSS 피드 구독
- 강조
- 인쇄
- 부적절한 컨텐트 신고
If I recall correctly, typing variable name in the Memory window is sufficient. In any case, typing LOC(Variable) in either the memory window or watch window surely works. Further, "LOC(Variable),x" in the watch window gives the address in hexadecimal. Each structure member which is a POINTER occupies 4 bytes + 24 bytes per each array dimension; note that this is only a descriptor -- it contains no data. Real data are located at the address pointed to by the first 4 bytes. It's too bad that it isn't possible to open multiple Memory windows simultaneously.
Thanks for your compliments.
Jugoslav
Thanks for your compliments.
Jugoslav
