- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I am seeing the following error:
As I said I cannot figure out what the #@!% is causing this issue. I am tempted to revert two days of work and added features to get around this sticking point.
[plain]forrtl: severe (174): SIGSEGV, segmentation fault occurredWhen I open up the executable with idb everything seems fine, there is a reasonable unused file handle (unit number) and the file needing to be opened exists. I am using fancy 2003 OOP features which are "supported" under ifort 11.1. I have read the sticky thread/article about debugging segfaults and don't know where to go from here. Line 386 of modfileio.F90 and is the OPEN statement in the following snippet (line 11):
Image PC Routine Line Source
mk_test_data 00000000004105CE modfileio_mp_init 386 modfileio.F90
mk_test_data 000000000040528A modfileio_mp_dns_ 254 modfileio.F90
mk_test_data 0000000000403217 MAIN__ 9 mk_test_data.F90
mk_test_data 00000000004031AC Unknown Unknown Unknown
libc.so.6 0000003DDD01D994 Unknown Unknown Unknown
mk_test_data 00000000004030B9 Unknown Unknown Unknown
[/plain]
[fxfortran] CALL Free_grid_3d(grid,err) ! This will clobber previous contentsDoes anyone know why an OPEN statement would cause a segfault????
IF ( CATCH(err=err) ) RETURN
! Called from read routine
! Open file to extract grid + header info
! get file handle
CALL get_fl_handle(handle,err=err)
IF( CATCH(err=err) ) RETURN
OPEN(unit=handle, &
file=path//'REST/old_plane.101', &
form='unformatted', &
&action='read', &
position='rewind', &
status='old', &
iostat=err)
IF ( CATCH(err=err,set=file_open_err) ) RETURN
! Read first line of header. includes imax, jmax, kmax
READ(handle,iostat=err) tmp_r, tmp_i, &
grid%imax, grid%jmax, grid%kmax
IF ( CATCH(err=err,set=failed_read) ) RETURN[/fxfortran]
As I said I cannot figure out what the #@!% is causing this issue. I am tempted to revert two days of work and added features to get around this sticking point.
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, this is your bug. OPEN, WRITE, etc. are not intrinsic functions, they are statements. While it is true that in references to intrinsic functions with optional arguments that you may pass an omitted optional argument, this is not the case for specifiers in I/O statements.
What you'll have to do is specify a local variable for IOSTAT and then use PRESENT(err) to test whether or not you should asisgn the value back to "err".
What you'll have to do is specify a local variable for IOSTAT and then use PRESENT(err) to test whether or not you should asisgn the value back to "err".
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Seg Faults will occure on Linux/Mac when you dereference a NULL pointer/reference.
Check the arguments to OPEN to make sure none are NULL.
Add IMPLICIT NONE
Add Check for reference to un-initialized variables
If that doesn't show anything, add
write(*,*) LOC(HANDLE), LOC(PATH), LOC(IOSTAT)
Verifry none are < 4096
Jim Dempsey
Check the arguments to OPEN to make sure none are NULL.
Add IMPLICIT NONE
Add Check for reference to un-initialized variables
If that doesn't show anything, add
write(*,*) LOC(HANDLE), LOC(PATH), LOC(IOSTAT)
Verifry none are < 4096
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm pretty sure I've found a bug which has been haunting me in many forms for a long time now. I am on the brink of my sanity because of this. In the above code the err variable was INTENT(out) and OPTIONAL. This variable is also intent(out) and optional in the procedure which calls this procedure. From Metcalf Reid & Cohen fortran 95/2003 explained, pp. 85:
[plain]A slight complication occurs if an optional dummy argument is used within the subprogram as an actual argument iniostat is an optional argument for the intrinsic IO functions so this should apply to iostat as well. A simple test program illustrates that this will fail if we try to use this technique of optional dummy arguments and propagate through two subroutine calls to the IO intrinsic procedure, if we do not provide the optional actual argument to the first subroutine called by the parent program. Note also that module procedures *should* have explicit interfaces by default. Please see the simple reproducer code below. Compile with:
a procedure invocation. ... In such a case, an absent optional argument is also regarded as absent in the second-
level subprogram. ... Such absent arguments may be propagated through any number of calls, provided the dummy
argument is optional in each case.[/plain]
[bash]ifort -warn -check -g -traceback my_test.f90[/bash]Here is the reproducer/test program, my_test.f90 :
[fortran]MODULE talkI have also attached the file for your convenience. I am quite confident this is a compiler bug.
IMPLICIT NONE
CONTAINS
SUBROUTINE msgoutter(err)
INTEGER, OPTIONAL, INTENT(out) :: err
WRITE(*,*,iostat=err) 'This works, so ...'
CALL msginner(err=err)
END SUBROUTINE msgoutter
SUBROUTINE msginner(err)
INTEGER, OPTIONAL, INTENT(out) :: err
WRITE(*,*,iostat=err) 'This *Should* work.'
END SUBROUTINE msginner
END MODULE talk
PROGRAM my_test
USE talk
IMPLICIT NONE
INTEGER :: error
CALL msgoutter()
END PROGRAM my_test[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, this is your bug. OPEN, WRITE, etc. are not intrinsic functions, they are statements. While it is true that in references to intrinsic functions with optional arguments that you may pass an omitted optional argument, this is not the case for specifiers in I/O statements.
What you'll have to do is specify a local variable for IOSTAT and then use PRESENT(err) to test whether or not you should asisgn the value back to "err".
What you'll have to do is specify a local variable for IOSTAT and then use PRESENT(err) to test whether or not you should asisgn the value back to "err".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
EDITED: May 7, 2010, 12:30 P.M. EST
If this is true, then shouldn't the outer subroutine in the test code produce a segfault/error? Or at least a warning when compiled with warn all or check all? You can pretty much insert whatever fortran statement you like in the above code that takes and optional argument. (open, close, read, write, allocate, deallocate, etc.) It will always work without complaining if an optional argument is passed one level deep, but nested optional arguments cause the code to fail. I guess if this is true, consider this post a feature request for the -warn option.
I guess I'll need to rethink my error handling routines. It would be nice if the outer subroutine also failed to keep things consistent. If one works but the other doesn't this can lead to confusion.
If this is true, then shouldn't the outer subroutine in the test code produce a segfault/error? Or at least a warning when compiled with warn all or check all? You can pretty much insert whatever fortran statement you like in the above code that takes and optional argument. (open, close, read, write, allocate, deallocate, etc.) It will always work without complaining if an optional argument is passed one level deep, but nested optional arguments cause the code to fail. I guess if this is true, consider this post a feature request for the -warn option.
I guess I'll need to rethink my error handling routines. It would be nice if the outer subroutine also failed to keep things consistent. If one works but the other doesn't this can lead to confusion.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The actual WRITE occurs - the attempted store to "err" happens after the I/O is done. If you compile -O0 and with traceback, you'll see that the segfault happens in msgouter. With default optimizations, inlining occurs and this obscures the error location.
What would you like the compiler to warn you about? That you made a reference to an optional argument without protecting it with PRESENT? That's a level of analysis that would be rather difficult, and impossible in some cases.
What would you like the compiler to warn you about? That you made a reference to an optional argument without protecting it with PRESENT? That's a level of analysis that would be rather difficult, and impossible in some cases.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK fair enough. Sorry for crying wolf.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is one reason why it is probably not a good idea to give an early warning on using a missing OPTIONAL argument (from the Fortran rules):
"An optional dummy argument whose actual argument is not present may not be referenced or defined (or invoked if it is a dummy procedure), except that it may be passed to another procedure as an optional argument and will be considered not present."
In many applications, a missing OPTIONAL argument may be passed around many times before something is actually attempted on it. Similarly, an output ALLOCATABLE array may be passed around many times before something is written to it. It is at the point of writing to this array when it has not yet been allocated and, correspondingly, attempting to write to a missing OPTIONAL argument, where a run-time error occurs.
It is probably a good design decision that we are allowed to pass missing OPTIONAL arguments to other procedures. Had this been otherwise, we would find ourselves cluttering up our code with lots of ..IF(PRESENT())... statements.
I find it helpful to think of missing arguments as similar to a NULL in C. You can pass null-pointers freely, use them in comparisons, and so on, as long as you do not dereference the pointer.
Having said all this, allow me to state that there are compilers that can give a "user-friendly" error message for your error:
f95 -Haesux my_test.f90
s:\ttst>my_test
jwe1575i-s line 10 The optional dummy argument (err) is not associated with actual argument.
error occurs at _talk@_msgoutter_ line 10 loc 0040307f offset 00000075
_talk@_msgoutter_ at loc 0040300a called from loc 004031fb in _MAIN__ line 28
"An optional dummy argument whose actual argument is not present may not be referenced or defined (or invoked if it is a dummy procedure), except that it may be passed to another procedure as an optional argument and will be considered not present."
In many applications, a missing OPTIONAL argument may be passed around many times before something is actually attempted on it. Similarly, an output ALLOCATABLE array may be passed around many times before something is written to it. It is at the point of writing to this array when it has not yet been allocated and, correspondingly, attempting to write to a missing OPTIONAL argument, where a run-time error occurs.
It is probably a good design decision that we are allowed to pass missing OPTIONAL arguments to other procedures. Had this been otherwise, we would find ourselves cluttering up our code with lots of ..IF(PRESENT())... statements.
I find it helpful to think of missing arguments as similar to a NULL in C. You can pass null-pointers freely, use them in comparisons, and so on, as long as you do not dereference the pointer.
Having said all this, allow me to state that there are compilers that can give a "user-friendly" error message for your error:
f95 -Haesux my_test.f90
s:\ttst>my_test
jwe1575i-s line 10 The optional dummy argument (err) is not associated with actual argument.
error occurs at _talk@_msgoutter_ line 10 loc 0040307f offset 00000075
_talk@_msgoutter_ at loc 0040300a called from loc 004031fb in _MAIN__ line 28

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page