Bug 34858 - [4.3 Regression] ICE on invalid depending of the length of the source name
Summary: [4.3 Regression] ICE on invalid depending of the length of the source name
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P4 minor
Target Milestone: 4.3.0
Assignee: Daniel Franke
URL:
Keywords: error-recovery, ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2008-01-18 20:39 UTC by Dominique d'Humieres
Modified: 2008-01-24 21:38 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-01-19 20:49:48


Attachments
Proposed patch. (1.11 KB, patch)
2008-01-24 15:47 UTC, Daniel Franke
Details | Diff
Proposed patch v2 (other patch contains unrelated differences) (881 bytes, patch)
2008-01-24 15:53 UTC, Daniel Franke
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dominique d'Humieres 2008-01-18 20:39:06 UTC
At revision 131629 (trunk), the following code

type a_t
  sequence
  integer i
end type a_t

block data bd
  common c
end block data bd

common /a_t/ c
end

gives

1234567.f90:6.13:

block data bd
            1
Error: Unexpected BLOCK DATA statement at (1)
1234567.f90:7.10:

  common c
         1
Error: Unexpected COMMON statement at (1)
1234567.f90:8.3:

end block data bd
  1
Error: Expecting END PROGRAM statement at (1)
1234567.f90:10.14:

common /a_t/ c
             1
Error: Unexpected COMMON statement at (1)
f951: internal compiler error: Segmentation fault

If I have identical copies named 1234567890a.f90 and 1234567890ab.f90, I have the following behavior:

"gfc 1234567890a.f90" gives only the errors, but
"gfc -m64 gfc 1234567890a.f90" gives the errors + the ICE,
as well as "gfc 1234567890a.f90 -o tmp.o" , and
"gfc 1234567890ab.f90" with or without "-o tmp.o".

I have a similar behavior on powerpc-apple-darwin9.

The problem appeared between 'GNU Fortran (GCC) 4.3.0 20080115' (rev. 131542) and '4.3.0 20080116' (rev. 131572). I don't see the problem on x86_64-unknown-linux-gnu rev. 131592 (Tobias Burnus' binaries).
Comment 1 Dominique d'Humieres 2008-01-19 17:21:18 UTC
Some debuging (this as fas as I can go on my own):

note the line

5: csym->value = (struct gfc_expr *) warning: Got an error handling event: "Cannot access memory at 
for the case that does not crash.

(gdb) run 1234567.f90 
Starting program: /opt/gcc/gcc4.3w/libexec/gcc/i686-apple-darwin9/4.3.0/f951 1234567.f90
Reading symbols for shared libraries +++++. done
1234567.f90:6.13:

block data bd
            1
Error: Unexpected BLOCK DATA statement at (1)
1234567.f90:7.10:

  common c
         1
Error: Unexpected COMMON statement at (1)
1234567.f90:8.3:

end block data bd
  1
Error: Expecting END PROGRAM statement at (1)
1234567.f90:10.14:

common /a_t/ c
             1
Error: Unexpected COMMON statement at (1)

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xc000004f
resolve_common_vars (sym=<value temporarily unavailable, due to optimizations>, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:657
657           if (csym->value || csym->attr.data)
(gdb) b 655
Breakpoint 1 at 0x62f0e: file ../../gcc-4.3-work/gcc/fortran/resolve.c, line 655.
(gdb) b 657
Breakpoint 2 at 0x62f47: file ../../gcc-4.3-work/gcc/fortran/resolve.c, line 657.
(gdb) display csym->value
Disabling display 1 to avoid infinite recursion.
1: csym->value = (struct gfc_expr *) Cannot access memory at address 0xc000004f
(gdb) run 1234567.f90 
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /opt/gcc/gcc4.3w/libexec/gcc/i686-apple-darwin9/4.3.0/f951 1234567.f90
1234567.f90:6.13:

block data bd
            1
Error: Unexpected BLOCK DATA statement at (1)
1234567.f90:7.10:

  common c
         1
Error: Unexpected COMMON statement at (1)
1234567.f90:8.3:

end block data bd
  1
Error: Expecting END PROGRAM statement at (1)
1234567.f90:10.14:

common /a_t/ c
             1
Error: Unexpected COMMON statement at (1)

Breakpoint 1, resolve_common_vars (sym=0x40d06d80, named_common=0 '\0') at ../../gcc-4.3-work/gcc/fortran/resolve.c:655
655       for (; csym; csym = csym->common_next)
(gdb) display csym->value
Disabling display 2 to avoid infinite recursion.
2: csym->value = (struct gfc_expr *) Cannot access memory at address 0x4c
(gdb) c
Continuing.

Breakpoint 2, resolve_common_vars (sym=<value temporarily unavailable, due to optimizations>, named_common=0 '\0') at ../../gcc-4.3-work/gcc/fortran/resolve.c:657
657           if (csym->value || csym->attr.data)
(gdb) display csym->value
3: csym->value = (struct gfc_expr *) 0x0
(gdb) c
Continuing.

Breakpoint 1, resolve_common_vars (sym=0x40d06f50, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:655
655       for (; csym; csym = csym->common_next)
Disabling display 3 to avoid infinite recursion.
3: csym->value = (struct gfc_expr *) warning: Got an error handling event: "Cannot access memory at address 0x4c".
(gdb) c
Continuing.

Breakpoint 2, resolve_common_vars (sym=<value temporarily unavailable, due to optimizations>, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:657
657           if (csym->value || csym->attr.data)
(gdb) c
Continuing.

Breakpoint 2, resolve_common_vars (sym=<value temporarily unavailable, due to optimizations>, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:657
657           if (csym->value || csym->attr.data)
(gdb) display csym->value
Disabling display 4 to avoid infinite recursion.
4: csym->value = (struct gfc_expr *) Cannot access memory at address 0xc000004f
(gdb) c
Continuing.

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xc000004f
resolve_common_vars (sym=<value temporarily unavailable, due to optimizations>, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:657
657           if (csym->value || csym->attr.data)
(gdb) run 1234567890a.f90 
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /opt/gcc/gcc4.3w/libexec/gcc/i686-apple-darwin9/4.3.0/f951 1234567890a.f90
1234567890a.f90:6.13:

block data bd
            1
Error: Unexpected BLOCK DATA statement at (1)
1234567890a.f90:7.10:

  common c
         1
Error: Unexpected COMMON statement at (1)
1234567890a.f90:8.3:

end block data bd
  1
Error: Expecting END PROGRAM statement at (1)
1234567890a.f90:10.14:

common /a_t/ c
             1
Error: Unexpected COMMON statement at (1)

Breakpoint 1, resolve_common_vars (sym=0x40d06d90, named_common=0 '\0') at ../../gcc-4.3-work/gcc/fortran/resolve.c:655
655       for (; csym; csym = csym->common_next)
(gdb) c
Continuing.

Breakpoint 2, resolve_common_vars (sym=<value temporarily unavailable, due to optimizations>, named_common=0 '\0') at ../../gcc-4.3-work/gcc/fortran/resolve.c:657
657           if (csym->value || csym->attr.data)
(gdb) display csym->value
5: csym->value = (struct gfc_expr *) 0x0
(gdb) c
Continuing.

Breakpoint 1, resolve_common_vars (sym=0x40d06f20, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:655
655       for (; csym; csym = csym->common_next)
Disabling display 5 to avoid infinite recursion.
5: csym->value = (struct gfc_expr *) warning: Got an error handling event: "Cannot access memory at address 0x4c".
(gdb) c
Continuing.

Breakpoint 2, resolve_common_vars (sym=<value temporarily unavailable, due to optimizations>, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:657
657           if (csym->value || csym->attr.data)
(gdb) c
Continuing.

Execution times (seconds)
 parser                :   0.00 ( 0%) usr   0.01 (100%) sys  32.42 (100%) wall     248 kB (70%) ggc
 TOTAL                 :   0.01             0.01            32.42                354 kB
Extra diagnostic checks enabled; compiler may run slowly.
Configure with --enable-checking=release to disable checks.

Comment 2 Jerry DeLisle 2008-01-19 17:47:14 UTC
On x86-64 linux using valgrind:

==2713== Invalid read of size 8
==2713==    at 0x45C16C: resolve_common_vars (resolve.c:657)

and 

==2713== Invalid read of size 1
==2713==    at 0x45C230: resolve_common_vars (resolve.c:657)

No segfault but doing something wrong.
Comment 3 Dominique d'Humieres 2008-01-19 19:47:41 UTC
Further debug:

Breakpoint 2, resolve_common_blocks (common_root=0x40d02c50) at ../../gcc-4.3-work/gcc/fortran/resolve.c:692
692     {
(gdb) c
Continuing.

Breakpoint 3, resolve_common_vars (sym=0x40d06f50, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:652
652     {
(gdb) c
Continuing.

Breakpoint 4, resolve_common_vars (sym=0x40d06f50, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:655
655       for (; csym; csym = csym->common_next)
(gdb) print csym
$11 = <value temporarily unavailable, due to optimizations>
(gdb) print csym->common_next
Cannot access memory at address 0x64

and

Breakpoint 3, resolve_common_vars (sym=0x40d06f50, named_common=1 '\001') at ../../gcc-4.3-work/gcc/fortran/resolve.c:652
652     {
(gdb) print csym
$15 = <value temporarily unavailable, due to optimizations>
(gdb) print csym->common_next
Cannot access memory at address 0x64
(gdb) print sym->common_next
$16 = (struct gfc_symbol *) 0xc0000003
(gdb) print sym->common_next->common_next
Cannot access memory at address 0xc0000067

So it seems that the list in "common_root->n.common->head" is not properly terminated.

Comment 4 Tobias Burnus 2008-01-19 20:49:48 UTC
I can reproduce it on x86-64-linux. The first error valgrind shows is

==25404== Invalid read of size 8
==25404==    at 0x44361B: gfc_match_common (match.c:2756)
==25404==    by 0x4522B9: match_word (parse.c:64)

That line is:
      while (old_blank_common->common_next)

The problem is essentially the same as for PR 33375: We have a half-deleted symbol somewhere. I believe the right spot is gfc_match_common; somewhere the error recovery does not properly delete a symbol or forgets a pointer = NULL.

When trying to debug PR 33375 I never quite understood why it was failing. I had also the feeling that the patch in PR 33375 might not be fully right. My starting point would be gfc_match_common either with the current tree or with the patch of PR 33375 reverted.
Comment 5 Dominique d'Humieres 2008-01-20 14:56:03 UTC
I am trying to proceed backward.  I have reached the following point:

Breakpoint 8, gfc_parse_file () at ../../gcc-4.3-work/gcc/fortran/parse.c:3460
3460    {
(gdb) s
gfc_parse_file () at ../../gcc-4.3-work/gcc/fortran/parse.c:3466
3466      gfc_start_source_files ();
(gdb) print gfc_current_ns->common_root->n.common->head->common_next
Cannot access memory at address 0x8
(gdb) print gfc_current_ns->common_root                             
Cannot access memory at address 0x8
(gdb) print gfc_current_ns             
$13 = (gfc_namespace *) 0x0
(gdb) s
gfc_start_source_files () at ../../gcc-4.3-work/gcc/fortran/scanner.c:348
348     {
(gdb) s
warning: Got an error handling event: "Cannot access memory at address 0x7".
(gdb) s
warning: Got an error handling event: "Cannot access memory at address 0x7".
(gdb) s
warning: Got an error handling event: "Cannot access memory at address 0x7".
(gdb) s
gfc_start_source_files () at ../../gcc-4.3-work/gcc/fortran/scanner.c:355
355       report_file_change (gfc_current_locus.lb);
(gdb) print gfc_current_locus.lb
$14 = (gfc_linebuf *) 0x40d06700
(gdb) print debug_hooks->start_end_main_source_file
$15 = 0
(gdb) print gfc_source_file
$16 = 0xbfffeec7 "1234567.f90"
(gdb) print file_changes_cur
$17 = 0
(gdb) print *debug_hooks->start_source_file
$18 = {void (unsigned int, const char *)} 0x339b70 <debug_nothing_int_charstar>

The "warning: Got an error handling event: "Cannot access memory at address 0x7" look bad, but I do not see where they come from.

Comment 6 Daniel Franke 2008-01-23 23:43:48 UTC
integer :: c        ! anything, makes block data invalid
block data bd
  common d          ! 'd' undefined, new symbol generated that needs to be undone
end block data bd
end

In the code above, the newly generated symbol for 'd' is plugged into the namespace hooks for commons (here, gfc_current_ns->blank_common). In gfc_undo_symbols(), the symbol itself is removed, but the namespace hooks are left untouched. Hence, while traversing the namespace, gfortran tries to resolve a dead symbol resulting in valgrind errors as

==23032== Invalid read of size 4
==23032==    at 0x80A171F: resolve_common_vars (resolve.c:658)
==23032==    by 0x4600BC7: ???
==23032==  Address 0x42320d4 is 76 bytes inside a block of size 288 free'd
==23032==    at 0x402248F: free (vg_replace_malloc.c:323)
==23032==    by 0x80B9C1C: gfc_undo_symbols (symbol.c:2591)

I think we need to check if the symbol was added to the COMMON-structures (sym->attr.in_common == 1) and, if yes, remove it as well.

If no one beats me to it, I will try to see if I'm right within the next days :)
Comment 7 Daniel Franke 2008-01-24 15:47:46 UTC
Created attachment 15017 [details]
Proposed patch.

This fixes the testcase from comment #6 as well as the original report in terms of invalid reads. On i686-pc-linux-gnu, I can not observe any more ICEs.

This patch also reverts the fix for PR33375 as this seems to be the more correct approach (no segfaults or invalid reads while compiling common_6.f90).

Not fully regression tested yet, but gfortran.dg/common_* does not show any problems.

Dominique, could you give it a try on your machines?
Comment 8 Daniel Franke 2008-01-24 15:53:03 UTC
Created attachment 15018 [details]
Proposed patch v2 (other patch contains unrelated differences)
Comment 9 Dominique d'Humieres 2008-01-24 16:46:24 UTC
Subject: Re:  [4.3 Regression] ICE on invalid depending of
 the length of the source name

Preliminary tests show that my test cases are fixed by the
patch. I'll launch regtesting.

Thanks for the patch.
Comment 10 Dominique d'Humieres 2008-01-24 19:57:19 UTC
The patch regtested fine on intel darwin9. I'll port it ot ppc, but I'll got the results only tomorrow morning.

Comment 11 Daniel Franke 2008-01-24 21:37:03 UTC
Subject: Bug 34858

Author: dfranke
Date: Thu Jan 24 21:36:14 2008
New Revision: 131811

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131811
Log:
2008-01-24  Daniel Franke  <franke.daniel@gmail.com>

        PR fortran/33375
        PR fortran/34858
        * gfortran.h: Revert changes from 2008-01-17.
        * match.c: Likewise.
        * symbol.c: Likewise.
        (gfc_undo_symbols): Undo namespace changes related to common blocks.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/match.c
    trunk/gcc/fortran/symbol.c

Comment 12 Daniel Franke 2008-01-24 21:38:18 UTC
Fixed in trunk. Closing.