In next_char() of libgfortran/io/list_read.c, dtp->u.p.line_buffer_enabled is not initialized properly and this may cause segfault while accessing dtp->u.p.line_buffer[dtp->u.p.item_count] even dtp->u.p.linebuffer is NULL. I think it can be solved with initializing in namelist_read() as follows. Tested with gcc version 4.3.0 20071129 (experimental) (GCC) on Mac OS X 10.4.11 intel. Index: libgfortran/io/list_read.c =================================================================== --- libgfortran/io/list_read.c (revision 130508) +++ libgfortran/io/list_read.c (working copy) @@ -2646,6 +2646,7 @@ dtp->u.p.namelist_mode = 1; dtp->u.p.input_complete = 0; dtp->u.p.expanded_read = 0; + dtp->u.p.line_buffer_enabled = 0; dtp->u.p.eof_jump = &eof_jump; if (setjmp (eof_jump))
It turns out that my explanation and assumption about uninitialization was wrong, but the real cause of the segmentation fault is that some functions call free_line(dtp) without resetting line_buffer_enabled. Here is the revised patch to avoid crash. Index: list_read.c =================================================================== --- list_read.c (revision 130508) +++ list_read.c (working copy) @@ -125,6 +125,7 @@ free_mem (dtp->u.p.line_buffer); dtp->u.p.line_buffer = NULL; + dtp->u.p.line_buffer_enabled = 0; }
Can you please provide a testcase for the testsuite?
Jerry, libgfortran IO is your domain...
I can't provide a simple test case sorry, but I now realized that it seems to be related that READ() for a namelist file ended with "&END" instead of "/" causes the problem. I use a library which creates namelist file by itself, and it puts "&END". If I replace the "&END" with "/", libgfortran doesn't seem to crash.
Maybe I could find a reliable testcase for the problem. Following program will crash while accessing dtp->u.p.line_buffer[dtp->u.p.item_count]. IMPLICIT NONE CHARACTER(len=10), DIMENSION(2) :: var NAMELIST /inx/ var OPEN(unit=11, status='scratch') write (11, *) "&INX" write (11, *) "var(1)='hello'" write (11, *) "&END" rewind (11) READ(11,NML=inx) CLOSE(11) END Here is the backtrace. (gdb) run Starting program: /Users/kato/src/gcc-4.2.999-071129/gcc/testsuite/gfortran.dg/a.out Reading symbols for shared libraries .++ done Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000005 0x0026f1d5 in next_char (dtp=0xbfffe6ac) at ../../../gcc-4.2.999-071129/libgfortran/io/list_read.c:152 152 c = dtp->u.p.line_buffer[dtp->u.p.item_count]; (gdb) where #0 0x0026f1d5 in next_char (dtp=0xbfffe6ac) at ../../../gcc-4.2.999-071129/libgfortran/io/list_read.c:152 #1 0x0026f4e0 in eat_spaces (dtp=0xbfffe6ac) at ../../../gcc-4.2.999-071129/libgfortran/io/list_read.c:269 #2 0x0026f519 in eat_separator (dtp=0xbfffe6ac) at ../../../gcc-4.2.999-071129/libgfortran/io/list_read.c:294 #3 0x00272e48 in nml_get_obj_data (dtp=0xbfffe6ac, pprev_nl=0xbfffe5bc, nml_err_msg=0xbfffe510 "\002\020") at ../../../gcc-4.2.999-071129/libgfortran/io/list_read.c:2388 #4 0x002739b3 in *__gfortrani_namelist_read (dtp=0xbfffe6ac) at ../../../gcc-4.2.999-071129/libgfortran/io/list_read.c:2716 #5 0x00279321 in finalize_transfer (dtp=0xbfffe6ac) at ../../../gcc-4.2.999-071129/libgfortran/io/transfer.c:2616 #6 0x00279511 in *__gfortran_st_read_done (dtp=0xbfffe6ac) at ../../../gcc-4.2.999-071129/libgfortran/io/transfer.c:2777 #7 0x00002c76 in MAIN__ () #8 0x00002ce8 in main (argc=1, argv=0xbfffe87c) at ../../../gcc-4.2.999-071129/libgfortran/fmain.c:21 Here is a workaround. Index: list_read.c =================================================================== --- list_read.c (revision 130508) +++ list_read.c (working copy) @@ -365,6 +365,9 @@ break; case '/': + /* should check 'end' after the character? */ + case '$': + case '&': dtp->u.p.input_complete = 1; if (!dtp->u.p.namelist_mode) return;
I will get on this soon.
I have retitled this to reflect a bit more correctly. The workaround in Comment #6 almost works, but it masks another problem. The patch that caused the regression is r129016. The test case works fine on r129015 of list_read.c
Subject: Bug 34291 Author: jvdelisle Date: Fri Nov 30 23:19:34 2007 New Revision: 130548 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130548 Log: 2007-11-30 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/34291 * io/list_read.c (read_character): When reading an unquoted string, return if special characters that could signify the end of the namelist read are encountered. Modified: trunk/libgfortran/ChangeLog trunk/libgfortran/io/list_read.c
Subject: Bug 34291 Author: jvdelisle Date: Fri Nov 30 23:21:48 2007 New Revision: 130549 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130549 Log: 2007-11-30 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/34291 * gfortran.dg/namelist_41.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/namelist_41.f90 Modified: trunk/gcc/testsuite/ChangeLog
Fixed on trunk.