[M3devel] cm3cg failing on linuxlibc6

Rodney M. Bates rodney_bates at lcwb.coop
Thu May 26 05:58:11 CEST 2016


Just an FYI on the And bug.

I think I have diagnosed this for this particular case.  TInt.ToBytes is following
the invariants of a TInt.T, which always uses twos-complement notation, but, with
a 9th byte, is big enough to hold the entire overlap of the 64-bit signed and unsigned
ranges.  OTOH, M3CG_BinWr.AddBigX is converting to signed-magnitude, with a separate
sign.  It passes an absolute value to ToBytes.  For only this single value
16_8000000000000000, this is representable as a positive absolute value in 8 bytes,
but ToBytes correctly considers this too few bytes for twos-complement and returns
zero.

It will take more work to look at all the calls on ToBytes and ascertain which
cases suffer this mismatch.  Also, I am currently unable to build a working
compiler for LINUXLIBC6, something to do with jumbufs.  So I will have to get around
that before testing a fix and for regressions.

It looks like it doesn't happen when compiling on a 64-bit machine because that
takes a different path, using native INTEGER rather than TInt for the constant
value.

On 05/24/2016 02:24 AM, Peter McKinna wrote:
> I may have been a tad hasty in blaming the back end for the crashes, the front end has some explaining to do as well.
>
> I was getting an infinite loop in a program which I have cut down here to demonstrate. The original cm3 5.2  I think it
> was from elegosoft worked fine. The latest produces different intermediate code.
>
> First the source, (excuse the size, its extracted from my implementation of grisu which I was on the point of pushing to github)
>
> MODULE Main;
>
> IMPORT Long,IO,Fmt;
>
> CONST
>    kUint64MSB = 16_8000000000000000L;
>
> TYPE
>    Uint64 = Long.T;
> PROCEDURE Normalize(sig : Long.T; exp : INTEGER) =
>    CONST
>      k10MSBits = 16_FFC0000000000000L;
>    VAR
>      significand : Uint64;
>      exponent : INTEGER;
>
>    BEGIN
>      <*ASSERT sig # 0L *>
>      significand := sig;
>      exponent := exp;
> (*IO.Put("sig init " & Fmt.LongInt(significand) & "\n");*)
>
>      (* This method is mainly called for normalizing boundaries. In general
>         boundaries need to be shifted by 10 bits. We thus optimize for this case. *)
>      WHILE Long.And(significand, k10MSBits) = 0L DO
>        significand := Long.LeftShift(significand, 10);
> (*IO.Put("sig loop 1 " & Fmt.LongInt(significand) & "\n");*)
>        DEC(exponent, 10);
>      END;
> (*IO.Put("sig after loop 1 " & Fmt.LongInt(significand) & "\n");*)
> (*
> IO.PutLongInt(Long.And(significand, kUint64MSB));
> IO.Put("\n");
> *)
>      WHILE Long.And(significand, kUint64MSB) = 0L DO
> (*IO.Put("sig loop2 1 " & Fmt.LongInt(significand) & "\n");*)
>        significand := Long.LeftShift(significand, 1);
> (*IO.Put("sig loop2 2 " & Fmt.LongInt(significand) & "\n");*)
>        DEC(exponent);
>      END;
>    END Normalize;
> BEGIN
>
>    Normalize(3L,2);
> END Main.
>
> Now the correct intermediate from the original cm3
> Its a shame we cant embed the cm3 version into the intermediate. But theres no mention of widechar so you can tell its an old
> version.
>
> begin_unit0
> -----FILE ../src/Main.m3  -----
> -----LINE 1  -----
> # module global constants
> declare_segment* -1 T v.1
> # module global data
> declare_segmentM_Main -1 F v.2
> -----LINE 45  -----
> declare_procedureMain_M3 1 Addr 0 0 T * p.1
> declare_parammode 4 4 Int.32 425470580 F F 100 v.3
> declare_proctype1318003907 2 0 0 0
> declare_formalsig 89530742
> declare_formalexp 425470580
> import_procedureMain_I3 0 Addr 0 p.2
> export_unitMain
> import_procedureFmt_I3 0 Addr 0 p.3
> import_unitFmt
> import_procedureIO_I3 0 Addr 0 p.4
> import_unitIO
> import_procedureLong_I3 0 Addr 0 p.5
> import_unitLong
> import_procedureRTHooks_I3 0 Addr 0 p.6
> import_unitRTHooks
> declare_typename89530742 Uint64
> declare_procedureMain__Normalize 2 Void 0 0 F * p.7
> declare_localsignificand 8 4 Int.64 89530742 F F 50 v.4
> declare_localexponent 4 4 Int.32 425470580 F F 50 v.5
> declare_paramsig 8 4 Int.64 89530742 F F 50 v.6
> declare_paramexp 4 4 Int.32 425470580 F F 50 v.7
> # Normalize
> -----LINE 11  -----
> begin_procedurep.7
> -----LINE 12  -----
> -----LINE 19  -----
> loadv.6 0 Int.64 Int.64
> load_integerInt.64 0
> if_neInt.64 L.1 100
> import_procedureRTHooks__ReportFault 2 Void 0 p.8
> declare_parammodule 4 4 Addr 138420323 F F 50 v.8
> declare_paraminfo 4 4 Int.32 425470580 F F 50 v.9
> set_runtime_procReportFault p.8
> abort0
> . L.1 F
> -----LINE 20  -----
> loadv.6 0 Int.64 Int.64
> storev.4 0 Int.64 Int.64
> -----LINE 21  -----
> loadv.7 0 Int.32 Int.32
> storev.5 0 Int.32 Int.32
> -----LINE 26  -----
> jumpL.2
> . L.3 F
> -----LINE 27  -----
> loadv.4 0 Int.64 Int.64
> load_integerInt.32 10
> shift_leftInt.64
> storev.4 0 Int.64 Int.64
> -----LINE 29  -----
> loadv.5 0 Int.32 Int.32
> load_integerInt.32 10
> subtractInt.32
> storev.5 0 Int.32 Int.32
> -----LINE 26  -----
> . L.2 F
> loadv.4 0 Int.64 Int.64
> load_integerInt.64 -18014398509481984
> andInt.64
> load_integerInt.64 0
> if_eqInt.64 L.3 80
> . L.4 F
> -----LINE 36  -----
> jumpL.5
> . L.6 F
> -----LINE 38  -----
> loadv.4 0 Int.64 Int.64
> load_integerInt.32 1
> shift_leftInt.64
> storev.4 0 Int.64 Int.64
> -----LINE 40  -----
> loadv.5 0 Int.32 Int.32
> load_integerInt.32 1
> subtractInt.32
> storev.5 0 Int.32 Int.32
> -----LINE 36  -----
> . L.5 F
> loadv.4 0 Int.64 Int.64
> load_integerInt.64 -9223372036854775808
> andInt.64
> load_integerInt.64 0
> if_eqInt.64 L.6 80
> . L.7 F
> -----LINE 43  -----
> exit_procVoid
> end_procedurep.7
> # Main_M3
> # module main body Main_M3
> -----LINE 45  -----
> begin_procedurep.1
> loadv.3 0 Int.32 Int.32
> if_falseInt.32 L.8 0
> -----LINE 47  -----
> start_call_directp.7 0 Void
> load_integerInt.64 3
> pop_paramInt.64
> load_integerInt.32 2
> pop_paramInt.32
> call_directp.7 Void
> . L.8 F
> load_addressv.2 0
> exit_procAddr
> end_procedurep.1
> # global constant type descriptor
> declare_record-1 448 0
> # global data type descriptor
> declare_record-1 896 0
> # module global constants
> bind_segmentv.1 56 4 Struct F T
> begin_initv.1
> # procedure names
> init_chars0 "Main_M3"
> init_chars8 "Normalize"
> # procedure table
> init_proc20 p.1
> init_var24 v.1 0
> init_proc28 p.7
> init_var32 v.1 8
> # file name
> init_chars40 "../src/Main.m3"
> end_initv.1
> # module global data
> bind_segmentv.2 112 4 Struct F T
> begin_initv.2
> init_var0 v.1 40
> init_var20 v.1 20
> init_var36 v.2 52
> init_proc44 p.1
> init_int48 3 Int.32
> init_proc56 p.2
> init_var60 v.2 64
> init_proc68 p.3
> init_var72 v.2 76
> init_proc80 p.4
> init_var84 v.2 88
> init_proc92 p.5
> init_var96 v.2 100
> init_proc104 p.6
> end_initv.2
> # load map
> #
> #
> #  global data allocation for M_Main
> #      0    52  4  *module info*
> #     52    12  4  import Main
> #     64    12  4  import Fmt
> #     76    12  4  import IO
> #     88    12  4  import Long
> #    100    12  4  import RTHooks
> #    112     0  4  *TOTAL*
> #
> #
> #  global constants for M_Main
> #      0    18  4  *proc names*
> #     20    20  4  *proc info*
> #     40    15  1  *string*
> #     56     0  4  *TOTAL*
> #
> end_unit
>
>
> Now the intermediate from the latest compiler
>
> begin_unit0
> widechar_size16
> -----FILE ../src/Main.m3  -----
> -----LINE 1  -----
> # module global constants
> declare_segment* -1 T v.1
> # module global data
> declare_segmentM_Main -1 F v.2
> -----LINE 45  -----
> declare_procedureMain_M3 1 Addr 0 0 T * p.1
> declare_parammode 4 4 Int.32 425470580 F F 100 v.3
> declare_proctype1318003907 2 0 0 0
> declare_formalsig 89530742
> declare_formalexp 425470580
> import_procedureMain_I3 0 Addr 0 p.2
> export_unitMain
> import_procedureFmt_I3 0 Addr 0 p.3
> import_unitFmt
> import_procedureIO_I3 0 Addr 0 p.4
> import_unitIO
> import_procedureLong_I3 0 Addr 0 p.5
> import_unitLong
> import_procedureRTHooks_I3 0 Addr 0 p.6
> import_unitRTHooks
> declare_typename89530742 Uint64
> declare_procedureMain__Normalize 2 Void 0 0 F * p.7
> declare_localsignificand 8 8 Int.64 89530742 F F 50 v.4
> declare_localexponent 4 4 Int.32 425470580 F F 50 v.5
> declare_paramsig 8 8 Int.64 89530742 F F 50 v.6
> declare_paramexp 4 4 Int.32 425470580 F F 50 v.7
> # Normalize
> -----LINE 11  -----
> begin_procedurep.7
> -----LINE 12  -----
> -----LINE 19  -----
> load_integerInt.64 0
> loadv.6 0 Int.64 Int.64
> if_neInt.64 L.1 100
> declare_proctype-1531209598 2 0 -1 0
> declare_formalmodule 138420323
> declare_formalinfo 425470580
> import_procedureRTHooks__ReportFault 2 Void 0 p.8
> declare_parammodule 4 4 Addr 138420323 F F 50 v.8
> declare_paraminfo 4 4 Int.32 425470580 F F 50 v.9
> set_runtime_procReportFault p.8
> abort0
> . L.1 F
> -----LINE 20  -----
> loadv.6 0 Int.64 Int.64
> storev.4 0 Int.64 Int.64
> -----LINE 21  -----
> loadv.7 0 Int.32 Int.32
> storev.5 0 Int.32 Int.32
> -----LINE 26  -----
> jumpL.2
> . L.3 F
> -----LINE 27  -----
> loadv.4 0 Int.64 Int.64
> load_integerInt.32 10
> shift_leftWord.64
> storev.4 0 Int.64 Int.64
> -----LINE 29  -----
> loadv.5 0 Int.32 Int.32
> load_integerInt.32 10
> subtractInt.32
> storev.5 0 Int.32 Int.32
> -----LINE 26  -----
> . L.2 F
> load_integerInt.64 -18014398509481984
> loadv.4 0 Int.64 Int.64
> andWord.64
> load_integerInt.64 0
> if_eqInt.64 L.3 80
> . L.4 F
> -----LINE 36  -----
> jumpL.5
> . L.6 F
> -----LINE 38  -----
> loadv.4 0 Int.64 Int.64
> load_integerInt.32 1
> shift_leftWord.64
> storev.4 0 Int.64 Int.64
> -----LINE 40  -----
> loadv.5 0 Int.32 Int.32
> load_integerInt.32 1
> subtractInt.32
> storev.5 0 Int.32 Int.32
> -----LINE 36  -----
> . L.5 F
> load_integerInt.64 0
> loadv.4 0 Int.64 Int.64
> andWord.64
> load_integerInt.64 0
> if_eqInt.64 L.6 80
> . L.7 F
> -----LINE 43  -----
> exit_procVoid
> end_procedurep.7
> # Main_M3
> # module main body Main_M3
> -----LINE 45  -----
> begin_procedurep.1
> loadv.3 0 Int.32 Int.32
> if_falseInt.32 L.8 0
> -----LINE 47  -----
> start_call_directp.7 0 Void
> load_integerInt.64 3
> pop_paramInt.64
> load_integerInt.32 2
> pop_paramInt.32
> call_directp.7 Void
> . L.8 F
> load_addressv.2 0
> exit_procAddr
> end_procedurep.1
> # global constant type descriptor
> declare_record-1 448 0
> # global data type descriptor
> declare_record-1 896 0
> # module global constants
> bind_segmentv.1 56 8 Struct F T
> begin_initv.1
> # procedure names
> init_chars0 "Main_M3"
> init_chars8 "Normalize"
> # procedure table
> init_proc20 p.1
> init_var24 v.1 0
> init_proc28 p.7
> init_var32 v.1 8
> # file name
> init_chars40 "../src/Main.m3"
> end_initv.1
> # module global data
> bind_segmentv.2 112 8 Struct F T
> begin_initv.2
> init_var0 v.1 40
> init_var20 v.1 20
> init_var36 v.2 52
> init_proc44 p.1
> init_int48 3 Int.32
> init_proc56 p.2
> init_var60 v.2 64
> init_proc68 p.3
> init_var72 v.2 76
> init_proc80 p.4
> init_var84 v.2 88
> init_proc92 p.5
> init_var96 v.2 100
> init_proc104 p.6
> end_initv.2
> # load map
> #
> #
> #  global data allocation for M_Main
> #      0    52  4  *module info*
> #     52    12  4  import Main
> #     64    12  4  import Fmt
> #     76    12  4  import IO
> #     88    12  4  import Long
> #    100    12  4  import RTHooks
> #    112     0  4  *TOTAL*
> #
> #
> #  global constants for M_Main
> #      0    18  4  *proc names*
> #     20    20  4  *proc info*
> #     40    15  1  *string*
> #     56     0  4  *TOTAL*
> #
> end_unit
>
>
> Its very similar except for using Word.64 instead of Int.64 and a couple of other cosmetic issues.
> The trouble is near label L5 where it does a load_integer of 0 instead of the big constant.
> The result of anding the zero and testing for zero is causing the loop.
> Compiling this with -O also causes the backend to crash.
> Both of these are on LINUXLIBC6. The AMD64 intermediate is correct. Seems like its not parsing the
> big long for some reason or else its wrapping around.
>
> Any ideas?
>
> Regards Peter
>
>
>
> On Tue, May 24, 2016 at 4:40 AM, Rodney M. Bates <rodney_bates at lcwb.coop <mailto:rodney_bates at lcwb.coop>> wrote:
>
>
>
>
>     I did git pull and rebuilt on LINUXLIBC6.  The built cm3 executable crashes compiling
>     a very small experiment program:
>
>        rodney at yellowstone:~/proj/m3/exp/FmtBug/src$ cm3-
>        Segmentation fault (core dumped)
>
>     m3gdb (after I built it) gives this:
>
>        rodney at yellowstone:~/proj/m3/exp/FmtBug/src$ m3gdb cm3-
>        GNU gdb plus Modula-3 6.4
>        Copyright 2005 Free Software Foundation, Inc.
>        GDB is free software, covered by the GNU General Public License, and you are
>        welcome to change it and/or distribute copies of it under certain conditions.
>        Type "show copying" to see the conditions.
>        There is absolutely no warranty for GDB.  Type "show warranty" for details.
>        This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
>
>        (m3gdb) run
>        Starting program: /usr/local/cm3-githead/bin/cm3-
>        [Thread debugging using libthread_db enabled]
>        [New LWP 23615]
>        [New Thread -1216829744 (LWP 23615)]
>
>        Program received signal SIGSEGV, Segmentation fault.
>        [Switching to Thread -1216829744 (LWP 23615)]
>        0x0037c26f in siglongjmp () from /lib/tls/i686/cmov/libc.so.6
>        (m3gdb) bt
>        #0  0x0037c26f in siglongjmp () from /lib/tls/i686/cmov/libc.so.6
>        #1  0x577b2a84 in ?? ()
>        Cannot access memory at address 0xd7a0906f
>        (m3gdb) quit
>
>
>     stock gdb gives even less information:
>
>        rodney at yellowstone:~/proj/m3/exp/FmtBug/src$ gdb cm3-
>        GNU gdb (GDB) 7.1-ubuntu
>        Copyright (C) 2010 Free Software Foundation, Inc.
>        License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
>        This is free software: you are free to change and redistribute it.
>        There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
>        and "show warranty" for details.
>        This GDB was configured as "i486-linux-gnu".
>        For bug reporting instructions, please see:
>        <http://www.gnu.org/software/gdb/bugs/>...
>        Reading symbols from /usr/local/cm3-githead/bin/cm3-...done.
>        (gdb) run
>        Starting program: /usr/local/cm3-githead/bin/cm3-
>        [Thread debugging using libthread_db enabled]
>
>        Program received signal SIGSEGV, Segmentation fault.
>        0x0032e26f in ?? () from /lib/tls/i686/cmov/libc.so.6
>        (gdb) bt
>        #0  0x0032e26f in ?? () from /lib/tls/i686/cmov/libc.so.6
>        #1  0xfb35d04b in ?? ()
>        Cannot access memory at address 0x7bee2da0
>        (gdb)
>
>     Note that gdb gives a different address in the same library for the point of fault.
>
>     m3gdb claims it's in siglongjmp.  I recall there were some recent changes involving
>     longjump.
>
>
>
>
>
>
>     On 05/22/2016 09:28 PM, Peter McKinna wrote:
>      > I dont know what changed but the backend is crashing on linuxlibc6 when compiled with -O Try compiling m3core.
>      >
>      > Also some of my low level tests with Long.And and Long.Shift are not working with
>      > normal compile without the optimisations on that platform. Bit suspicious. I'm still investigating.
>      >
>      > Anyone got any clues or can replicate?
>      >
>      > Thanks Peter
>      >
>      >
>      >
>      >
>      > _______________________________________________
>      > M3devel mailing list
>      > M3devel at elegosoft.com <mailto:M3devel at elegosoft.com>
>      > https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>      >
>
>
>     --
>     Rodney Bates
>     rodney.m.bates at acm.org <mailto:rodney.m.bates at acm.org>
>     _______________________________________________
>     M3devel mailing list
>     M3devel at elegosoft.com <mailto:M3devel at elegosoft.com>
>     https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>
>

-- 
Rodney Bates
rodney.m.bates at acm.org



More information about the M3devel mailing list