Bug 42073 - Infinite loop when parsing a project file, alpha only
Summary: Infinite loop when parsing a project file, alpha only
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: ada (show other bugs)
Version: 4.4.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-11-16 23:08 UTC by Ludovic Brenta
Modified: 2012-03-13 13:16 UTC (History)
3 users (show)

See Also:
Host: alpha-linux-gnu
Target: alpha-linux-gnu
Build: alpha-linux-gnu
Known to work: 4.3.4
Known to fail: 4.4.2
Last reconfirmed:


Attachments
Disassembly of prj-part.adb, with sources (objdump -S) (76.73 KB, text/plain)
2009-11-19 18:50 UTC, Ludovic Brenta
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ludovic Brenta 2009-11-16 23:08:16 UTC
On alpha-linux-gnu, gnatmake enters an infinite loop consuming 100% CPU while parsing this project file:

project GNADE_Common_Build is

   Soversion := External ("soversion");

   type Lib_Type is ("static", "dynamic");

   Libtype : Lib_Type := external ("LIBTYPE");

   for Languages use ("Ada");

   --  At install time, Source_Dirs must reflect the build source
   --  directories
   for Source_Dirs use ("../support");

   --  Library_Dir must be a single directory containing all the
   --  library files (*.ali, *.a, *.so) for all of the gnade packages.
   for Library_Dir use "tmp";

   --  Object_Dir is only used at build time; it must be distinct from
   --  the other package object directories, and from the library
   --  directory.
   for Object_Dir use "tmp/common-" & Libtype;

   for Library_Name use "gnadecommon";
   for Library_Kind use Libtype;

   --  Library_Version is not used when Library_Kind is "static"
   for Library_Version use "libgnadecommon.so." & Soversion;

   package Compiler is
      for Default_Switches ("Ada") use
        ("-g",
         "-O2",
         "-gnat05",
         "-gnatfno",
         "-gnatwa",
         "-gnatVa",
         "-fstack-check");
   end Compiler;

end GNADE_Common_Build;

Steps to reproduce:
$ gnatmake -p -j1 -vP2 -Pdebian/gnade_common_build -XLIBTYPE=static  -Xsoversion=1 -v
GPR_PROJECT_PATH=".:/usr/share/ada/adainclude/"
Project_Path_Name_Of ("debian/gnade_common_build", "/home/lbrenta/gnade-1.6.2/");
   Trying /home/lbrenta/gnade-1.6.2//debian/gnade_common_build.gpr
Project_Name_From ("/home/lbrenta/gnade-1.6.2/debian/gnade_common_build.gpr")
(infinite loop)

gnatmake works with the same project file on all architectures I tried: {amd64,hppa,i386,ia64,mips,mipsel,powerpc,s390,sparc}-linux-gnu, so this looks like a code generation bug that affects gnatmake.

I have access to an alpha-linux-gnu machine, please tell me if I can help narrow this problem down.
Comment 1 Ludovic Brenta 2009-11-17 10:27:54 UTC
The following project file is known to work on alpha-gnu-linux with GCC 4.3.4:

project Build_XMLAda is
   for Source_Dirs use ("dom", "input_sources", "sax", "schema", "unicode");
   for Library_Name use "xmlada";
   for Library_Dir use ".";
   for Library_Kind use External ("kind");
   for Library_Version use External ("soname");
   for Object_Dir use External ("obj");
   for Library_ALI_Dir use "ali-" & External ("obj");
   package Compiler is
      for Default_Switches ("Ada") use ("-g", "-O2", "-gnatafno", "-gnatVa", "-gnatwa");
   end Compiler;
end Build_XMLAda;

Since this project file is not noticeably different from GNADE_Common_Build, I think the bug is actually a regression in 4.4.
Comment 2 Uroš Bizjak 2009-11-17 17:47:52 UTC
(In reply to comment #0)

> I have access to an alpha-linux-gnu machine, please tell me if I can help
> narrow this problem down.

A debug trace from gdb would be a nice starting point.

Comment 3 Ludovic Brenta 2009-11-17 19:56:12 UTC
Even an empty project file triggers the bug:

$ cat > p.gpr <<EOF
project p is
end p;
EOF
$ gdb gnatmake
(gdb) run -vP2 -Pp
Starting program: /usr/bin/gnatmake -vP2 -Pp
GPR_PROJECT_PATH=".:/usr/share/ada/adainclude/"
Project_Path_Name_Of ("p", "/home/lbrenta/");
   Trying /home/lbrenta//p.gpr
Project_Name_From ("/home/lbrenta/p.gpr")
^C
Program received signal SIGINT, Interrupt.
0x000002000086f344 in prj__tree__tree_private_part__projects_htable__get_next () from /usr/lib/libgnatprj.so.4.4
(gdb) bt
#0  0x000002000086f344 in prj__tree__tree_private_part__projects_htable__get_next () from /usr/lib/libgnatprj.so.4.4
#1  0x0000020000853dd8 in ?? () from /usr/lib/libgnatprj.so.4.4
#2  0x0000020000856abc in prj__part__parse () from /usr/lib/libgnatprj.so.4.4
#3  0x000002000084df7c in prj__pars__parse () from /usr/lib/libgnatprj.so.4.4
#4  0x00000001200635d4 in ?? ()
#5  0x00000001200450c4 in ?? ()
#6  0x000000012000cf60 in ?? ()
#7  0x00000001200ad114 in ?? ()
#8  0x0000020000bd650c in __libc_start_main (main=<value optimized out>, argc=<value optimized out>, ubp_av=<value optimized out>,
    init=0x1200ad190, fini=<value optimized out>, rtld_fini=<value optimized out>, stack_end=0x11fcbd730) at libc-start.c:222
#9  0x000000012000b958 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

Note: this gnatmake is built with -O2 and without -g.

(gdb) disassemble
Dump of assembler code for function prj__tree__tree_private_part__projects_htable__tab__get_next:
0x000002000086f290 <prj__tree__tree_private_part__projects_htable__tab__get_next+0>:    ldah    gp,6(t12)
0x000002000086f294 <prj__tree__tree_private_part__projects_htable__tab__get_next+4>:    lda     gp,-12016(gp)
0x000002000086f298 <prj__tree__tree_private_part__projects_htable__tab__get_next+8>:    lda     sp,-32(sp)
0x000002000086f29c <prj__tree__tree_private_part__projects_htable__tab__get_next+12>:   stq     s0,8(sp)
0x000002000086f2a0 <prj__tree__tree_private_part__projects_htable__tab__get_next+16>:   mov     a0,s0
0x000002000086f2a4 <prj__tree__tree_private_part__projects_htable__tab__get_next+20>:   stq     ra,0(sp)
0x000002000086f2a8 <prj__tree__tree_private_part__projects_htable__tab__get_next+24>:   stq     s1,16(sp)
0x000002000086f2ac <prj__tree__tree_private_part__projects_htable__tab__get_next+28>:   bne     a0,0x2000086f2d0 <prj__tree__tree_private_part__projects_htable__tab__get_next+64>
0x000002000086f2b0 <prj__tree__tree_private_part__projects_htable__tab__get_next+32>:   clr     v0
0x000002000086f2b4 <prj__tree__tree_private_part__projects_htable__tab__get_next+36>:   ldq     ra,0(sp)
0x000002000086f2b8 <prj__tree__tree_private_part__projects_htable__tab__get_next+40>:   ldq     s0,8(sp)
0x000002000086f2bc <prj__tree__tree_private_part__projects_htable__tab__get_next+44>:   ldq     s1,16(sp)
0x000002000086f2c0 <prj__tree__tree_private_part__projects_htable__tab__get_next+48>:   lda     sp,32(sp)
0x000002000086f2c4 <prj__tree__tree_private_part__projects_htable__tab__get_next+52>:   ret
0x000002000086f2c8 <prj__tree__tree_private_part__projects_htable__tab__get_next+56>:   nop
0x000002000086f2cc <prj__tree__tree_private_part__projects_htable__tab__get_next+60>:   unop
0x000002000086f2d0 <prj__tree__tree_private_part__projects_htable__tab__get_next+64>:   ldah    s1,1(a0)
0x000002000086f2d4 <prj__tree__tree_private_part__projects_htable__tab__get_next+68>:   ldl     t0,-16312(s1)
0x000002000086f2d8 <prj__tree__tree_private_part__projects_htable__tab__get_next+72>:   and     t0,0xff,t0
0x000002000086f2dc <prj__tree__tree_private_part__projects_htable__tab__get_next+76>:   beq     t0,0x2000086f2b0 <prj__tree__tree_private_part__projects_htable__tab__get_next+32>
0x000002000086f2e0 <prj__tree__tree_private_part__projects_htable__tab__get_next+80>:   ldq     a0,-16320(s1)
0x000002000086f2e4 <prj__tree__tree_private_part__projects_htable__tab__get_next+84>:   ldq     t12,-32248(gp)
0x000002000086f2e8 <prj__tree__tree_private_part__projects_htable__tab__get_next+88>:   jsr     ra,(t12),0x2000086f2ec <prj__tree__tree_private_part__projects_htable__tab__get_next+92>
0x000002000086f2ec <prj__tree__tree_private_part__projects_htable__tab__get_next+92>:   ldah    gp,6(ra)
0x000002000086f2f0 <prj__tree__tree_private_part__projects_htable__tab__get_next+96>:   mov     s0,a0
0x000002000086f2f4 <prj__tree__tree_private_part__projects_htable__tab__get_next+100>:  lda     gp,-12108(gp)
0x000002000086f2f8 <prj__tree__tree_private_part__projects_htable__tab__get_next+104>:  stq     v0,-16320(s1)
0x000002000086f2fc <prj__tree__tree_private_part__projects_htable__tab__get_next+108>:  ldq     t12,-28536(gp)
0x000002000086f300 <prj__tree__tree_private_part__projects_htable__tab__get_next+112>:  jsr     ra,(t12),0x2000086f304 <prj__tree__tree_private_part__projects_htable__tab__get_next+116>
0x000002000086f304 <prj__tree__tree_private_part__projects_htable__tab__get_next+116>:  ldah    gp,6(ra)
0x000002000086f308 <prj__tree__tree_private_part__projects_htable__tab__get_next+120>:  lda     gp,-12132(gp)
0x000002000086f30c <prj__tree__tree_private_part__projects_htable__tab__get_next+124>:  ldq     ra,0(sp)
0x000002000086f310 <prj__tree__tree_private_part__projects_htable__tab__get_next+128>:  ldq     s0,8(sp)
0x000002000086f314 <prj__tree__tree_private_part__projects_htable__tab__get_next+132>:  ldq     s1,16(sp)
0x000002000086f318 <prj__tree__tree_private_part__projects_htable__tab__get_next+136>:  lda     sp,32(sp)
0x000002000086f31c <prj__tree__tree_private_part__projects_htable__tab__get_next+140>:  ret
End of assembler dump.

The sources corresponding to this procedure is:

      function Get_Next (T : Instance) return Element is
         Tmp : constant Elmt_Ptr := Tab.Get_Next (Tab.Instance (T));
      begin
         if Tmp = null then
            return No_Element;
         else
            return Tmp.E;
         end if;
      end Get_Next;

Is this sufficient for debugging?
Comment 4 Ludovic Brenta 2009-11-17 19:59:44 UTC
Actually the disassembly above was that of Tab.Get_Next. The source for Tab.Get_Next is:

      function Get_Next (T : Instance) return Elmt_Ptr is
      begin
         if T = null or else not T.Iterator_Started then
            return Null_Ptr;
         end if;

         T.Iterator_Ptr := Next (T.Iterator_Ptr);
         return Get_Non_Null (T);
      end Get_Next;


The disassembly of Simple_HTable.Get_Next is:

(gdb) up
#1  0x000002000086f344 in prj__tree__tree_private_part__projects_htable__get_next () from /usr/lib/libgnatprj.so.4.4
(gdb) disassemble
Dump of assembler code for function prj__tree__tree_private_part__projects_htable__get_next:
0x000002000086f320 <prj__tree__tree_private_part__projects_htable__get_next+0>: ldah    gp,6(t12)
0x000002000086f324 <prj__tree__tree_private_part__projects_htable__get_next+4>: lda     gp,-12160(gp)
0x000002000086f328 <prj__tree__tree_private_part__projects_htable__get_next+8>: lda     sp,-16(sp)
0x000002000086f32c <prj__tree__tree_private_part__projects_htable__get_next+12>:        ldq     t12,-27200(gp)
0x000002000086f330 <prj__tree__tree_private_part__projects_htable__get_next+16>:        stq     s0,8(sp)
0x000002000086f334 <prj__tree__tree_private_part__projects_htable__get_next+20>:        mov     a0,s0
0x000002000086f338 <prj__tree__tree_private_part__projects_htable__get_next+24>:        stq     ra,0(sp)
0x000002000086f33c <prj__tree__tree_private_part__projects_htable__get_next+28>:        mov     a1,a0
0x000002000086f340 <prj__tree__tree_private_part__projects_htable__get_next+32>:        jsr     ra,(t12),0x2000086f344 <prj__tree__tree_private_part__projects_htable__get_next+36>
0x000002000086f344 <prj__tree__tree_private_part__projects_htable__get_next+36>:        ldah    gp,6(ra)
0x000002000086f348 <prj__tree__tree_private_part__projects_htable__get_next+40>:        lda     gp,-12196(gp)
0x000002000086f34c <prj__tree__tree_private_part__projects_htable__get_next+44>:        beq     v0,0x2000086f390 <prj__tree__tree_private_part__projects_htable__get_next+112>
0x000002000086f350 <prj__tree__tree_private_part__projects_htable__get_next+48>:        ldl     t0,16(v0)
0x000002000086f354 <prj__tree__tree_private_part__projects_htable__get_next+52>:        ldl     t3,4(v0)
0x000002000086f358 <prj__tree__tree_private_part__projects_htable__get_next+56>:        ldl     t2,8(v0)
0x000002000086f35c <prj__tree__tree_private_part__projects_htable__get_next+60>:        ldl     t1,12(v0)
0x000002000086f360 <prj__tree__tree_private_part__projects_htable__get_next+64>:        stl     t3,0(s0)
0x000002000086f364 <prj__tree__tree_private_part__projects_htable__get_next+68>:        stl     t2,4(s0)
0x000002000086f368 <prj__tree__tree_private_part__projects_htable__get_next+72>:        stl     t1,8(s0)
0x000002000086f36c <prj__tree__tree_private_part__projects_htable__get_next+76>:        stl     t0,12(s0)
0x000002000086f370 <prj__tree__tree_private_part__projects_htable__get_next+80>:        mov     s0,v0
0x000002000086f374 <prj__tree__tree_private_part__projects_htable__get_next+84>:        ldq     ra,0(sp)
0x000002000086f378 <prj__tree__tree_private_part__projects_htable__get_next+88>:        ldq     s0,8(sp)
0x000002000086f37c <prj__tree__tree_private_part__projects_htable__get_next+92>:        lda     sp,16(sp)
0x000002000086f380 <prj__tree__tree_private_part__projects_htable__get_next+96>:        ret
0x000002000086f384 <prj__tree__tree_private_part__projects_htable__get_next+100>:       unop
0x000002000086f388 <prj__tree__tree_private_part__projects_htable__get_next+104>:       nop
0x000002000086f38c <prj__tree__tree_private_part__projects_htable__get_next+108>:       unop
0x000002000086f390 <prj__tree__tree_private_part__projects_htable__get_next+112>:       ldah    t1,-4(gp)
0x000002000086f394 <prj__tree__tree_private_part__projects_htable__get_next+116>:       lda     t0,20296(t1)
0x000002000086f398 <prj__tree__tree_private_part__projects_htable__get_next+120>:       ldl     t3,20296(t1)
0x000002000086f39c <prj__tree__tree_private_part__projects_htable__get_next+124>:       ldl     t2,4(t0)
0x000002000086f3a0 <prj__tree__tree_private_part__projects_htable__get_next+128>:       ldl     t1,12(t0)
0x000002000086f3a4 <prj__tree__tree_private_part__projects_htable__get_next+132>:       ldl     t0,8(t0)
0x000002000086f3a8 <prj__tree__tree_private_part__projects_htable__get_next+136>:       stl     t3,0(s0)
0x000002000086f3ac <prj__tree__tree_private_part__projects_htable__get_next+140>:       stl     t2,4(s0)
0x000002000086f3b0 <prj__tree__tree_private_part__projects_htable__get_next+144>:       stl     t0,8(s0)
0x000002000086f3b4 <prj__tree__tree_private_part__projects_htable__get_next+148>:       stl     t1,12(s0)
0x000002000086f3b8 <prj__tree__tree_private_part__projects_htable__get_next+152>:       mov     s0,v0
0x000002000086f3bc <prj__tree__tree_private_part__projects_htable__get_next+156>:       ldq     ra,0(sp)
0x000002000086f3c0 <prj__tree__tree_private_part__projects_htable__get_next+160>:       ldq     s0,8(sp)
0x000002000086f3c4 <prj__tree__tree_private_part__projects_htable__get_next+164>:       lda     sp,16(sp)
0x000002000086f3c8 <prj__tree__tree_private_part__projects_htable__get_next+168>:       ret
End of assembler dump.
Comment 5 charlet@adacore.com 2009-11-17 21:45:57 UTC
Subject: Re:  [4.4 regression] Infinite loop when parsing a
	project file, alpha only

> #1  0x0000020000853dd8 in ?? () from /usr/lib/libgnatprj.so.4.4
> #2  0x0000020000856abc in prj__part__parse () from /usr/lib/libgnatprj.so.4.4
> #3  0x000002000084df7c in prj__pars__parse () from /usr/lib/libgnatprj.so.4.4

Well, there's no such thing as libgnatprj.so in GCC sources/Makefiles.

Can you please retry with a stock GCC and build with -O0 -g to get a more
complete info/debug session? TIA.

Arno
Comment 6 Ludovic Brenta 2009-11-18 22:09:47 UTC
With a stock GCC 4.4.2 bootstrapped with the default options (-g -O2, I think) on alpha the symptoms are the same.  Here is a backtrace:

(gdb) run -vP2 -Pp
Starting program: /home/lbrenta/gcc-obj/gcc/gnatmake -vP2 -Pp
GPR_PROJECT_PATH=".:/home/lbrenta/gcc/lib/gcc/alphaev68-unknown-linux-gnu/4.4.2/../../../gnat"
Project_Path_Name_Of ("p", "/home/lbrenta/");
   Trying /home/lbrenta//p.gpr
Project_Name_From ("/home/lbrenta/p.gpr")
^C
Program received signal SIGINT, Interrupt.
0x00000001200f8ed8 in prj.part.parse_single_project (in_tree=0x1205fc3e0, path_name=<value optimized out>, extended=<value optimized out>,
    from_extended=<value optimized out>, in_limited=false, packages_to_check=..., depth=0, current_dir=...)
    at /home/lbrenta/gcc-4.4.2/gcc/ada/prj-part.adb:1104
1104               Tree_Private_Part.Projects_Htable.Get_Next (In_Tree.Projects_HT);
(gdb) bt
#0  0x00000001200f8ed8 in prj.part.parse_single_project (in_tree=0x1205fc3e0, path_name=<value optimized out>, extended=<value optimized out>,
    from_extended=<value optimized out>, in_limited=false, packages_to_check=..., depth=0, current_dir=...)
    at /home/lbrenta/gcc-4.4.2/gcc/ada/prj-part.adb:1104
#1  0x00000001200fb020 in prj.part.parse (in_tree=0x1205fc3e0, project_file_name=<value optimized out>,
    always_errout_finalize=<value optimized out>, packages_to_check=<value optimized out>, store_comments=false, current_directory=...)
    at /home/lbrenta/gcc-4.4.2/gcc/ada/prj-part.adb:525
#2  0x00000001200f4878 in prj.pars.parse (in_tree=<value optimized out>, project_file_name=..., packages_to_check=...,
    when_no_sources=<value optimized out>, reset_tree=true) at /home/lbrenta/gcc-4.4.2/gcc/ada/prj-pars.adb:63
#3  0x00000001200858f8 in make.initialize () at /home/lbrenta/gcc-4.4.2/gcc/ada/make.adb:6993
#4  0x00000001200866cc in make.gnatmake () at /home/lbrenta/gcc-4.4.2/gcc/ada/make.adb:4708
#5  0x0000000120067708 in gnatmake () at /home/lbrenta/gcc-4.4.2/gcc/ada/gnatmake.adb:38
(gdb) p In_Tree.Projects_HT
$4 = (access prj.tree.tree_private_part.projects_htable.tab.instance_data) 0x0

The infinite loop appears to be the loop starting at prj-pars.adb:1048 (frame #0 in the above backtrace).  I'll attach a disassembly.
Comment 7 Ludovic Brenta 2009-11-19 18:50:25 UTC
Created attachment 19060 [details]
Disassembly of prj-part.adb, with sources (objdump -S)
Comment 8 Jakub Jelinek 2012-03-13 13:16:26 UTC
Can you reproduce this with 4.5+?  4.4 is no longer supported.