a couple of problems building gprolog on sparc/solaris

[email protected]
Newsgroups gmane.comp.gnu.prolog.bugs
Message-ID <Pine.GSO.4.58.0602272132350.4944@ebusy>
Hello,

I hit a couple of problems trying to build gprolog on solaris/sparc.
I saw problem 1 with 1.2.16 and 1.2.19. Problem 2 only occurred on 1.2.19.

I was building on solaris 10 but these problems would probably be hit
earlier releases (pre-solaris 8 releases may avoid problem 1 due to having
simpler library code).

$ uname -a
SunOS host 5.10 Generic sun4u sparc SUNW,Sun-Fire

I have attached make && configure output for the 1.2.19 build (the 1.2.16
output was similiar). Both problems have the same output due being initial
failures when first running pl2wam.

problem 1: 1.2.16 build

$   ./configure && make
...
./pl_config

        -------------------------------
        --- GNU PROLOG INSTALLATION ---
        -------------------------------


GNU Prolog version: 1.2.16 (Sep 19 2002)
Operating system  : solaris2.10
Processor         : sparc
Size of a word    : 32 bits
C compiler        : gcc
C flags           : -O3 -fomit-frame-pointer
C flags machine   :
Loader flags      :
Loader libraries  : -lm -lsocket -lnsl
Use line editor   : Yes
Use piped consult : Yes
Use sockets       : Yes
Use FD solver     : Yes
Use machine regs. : Yes
Used register(s)  : g6 g7 			<- note this
...
gplc -c --fast-math fd2c.pl
compilation failed
*** Error code 1
make: Fatal error: Command failed for target `fd2c.o'
Current working directory /home/df125853/prolog/gprolog-1.2.16/src/Fd2C
*** Error code 1
make: Fatal error: Command failed for target `all'

gplc runs a copy of pl2wam which is dumping core into Fd2C.

$  dbx $(which pl2wam) core
Reading pl2wam
core file header read successfully
Reading ld.so.1
Reading libm.so.2
Reading libsocket.so.1
Reading libnsl.so.1
Reading libc.so.1
Reading libc_psr.so.1
program terminated by signal SEGV (no mapping at the fault address)
0xff115e14: lmutex_lock+0x001c: ld      [%i2 + %l6], %l5
>where
=>[1] lmutex_lock(0xff1694a0, 0x1, 0x0, 0xfc00, 0xbc47838, 0x0), at 0xff115e14
  [2] malloc(0xc, 0x1, 0x93ac4, 0x61707065, 0xff166258, 0xff16e49c), at
 0xff0d27cc
  [3] LE_Compl_Add_Word(0xc5138, 0xb, 0xffff, 0x1, 0x0, 0x1), at 0xb0a7c
  [4] Create_Atom(0xc5138, 0xcf400, 0x0, 0x0, 0x0, 0x11a098), at 0xadcc0
  [5] Object_Initializer(0xdeadbeef, 0x12345678, 0xc45c8, 0xc4400, 0xc45c8,
 0x2ae0c), at 0x2b2b0
  [6] Find_Linked_Objects(0x1, 0x1, 0x4, 0x22a800, 0x1aaa78, 0xc6e2000),
 at 0xaaff4
  [7] Start_Prolog(0xcd400, 0x11c000, 0x0, 0x0, 0x0, 0x0), at 0xab23c
  [8] main(0x5, 0xffbff4b4, 0xffbff4cc, 0x22aba0, 0xff3a0100, 0xff3a0140), at 0xaeb90
>dis lmutex_lock
0xff115df8: lmutex_lock       : save    %sp, -0x60, %sp
0xff115dfc: lmutex_lock+0x0004: ld      [%g7 + 0xc8], %i5
0xff115e00: lmutex_lock+0x0008: sethi   %hi(0x1000), %l7
0xff115e04: lmutex_lock+0x000c: ld      [%g7 + 0x54], %i2
0xff115e08: lmutex_lock+0x0010: add     %l7, 0x84, %l6
0xff115e0c: lmutex_lock+0x0014: add     %i5, 0x1, %i1
0xff115e10: lmutex_lock+0x0018: st      %i1, [%g7 + 0xc8]
0xff115e14: lmutex_lock+0x001c: ld      [%i2 + %l6], %l5   <- segfault here
>print $i
>print $i2
$i2 = 0
>print $l6
$l6 = 4228

%i2 (pulled from %g7+54) is empty.

solaris source for lmutex_lock() is:

(see
http://cvs.opensolaris.org/source/xref/on/usr/src/lib/libc/port/threads/synch.c)

void
lmutex_lock(mutex_t *mp)
{
   ulwp_t *self = curthread;
   uberdata_t *udp = self->ul_uberdata;
...
   if (udp->uberflags.uf_all == 0) { <- segfault here

%i2 is %g7+54 (self->ul_uberdata) where self is obtained from
curthread (i.e %g7).

There is a convention on sparc that %g7 will hold a pointer to a structure
describing the current thread (and libc etc. expect this convention to be
honoured).

Looking through source for gprolog, it makes use of %g7 as well
(Save_Machine_Regs()/Restore_Machine_Regs()).

I was able to get a successful build of gprolog by doing configure
--with-c-flags="-DNO_USE_REGS" after a make distclean. A suggested fix
might be to change Engine/machine.h to only use %g6 i.e change:

>#elif defined(M_sparc_solaris)
>
>#    define M_USED_REGS            {"g6", "g7", 0}

to:

>#elif defined(M_sparc_solaris)
>
>#    define M_USED_REGS            {"g6", 0}

problem 2.

When building gprolog 1.2.19 pl2wam also dumps core with another failure
mode.

$ truss -tmmap pl2wam
...
mmap(0x00000000, 15761408, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) = 0x00000000
    Incurred fault #6, FLTBOUNDS  %pc = 0x000A88D0
      siginfo: SIGSEGV SEGV_ACCERR addr=0x000A88D0
    Received signal #11, SIGSEGV [default]
      siginfo: SIGSEGV SEGV_ACCERR addr=0x000A88D0

Running pl2wam we now see:
mdb $(which pl2wam) core
Loading modules: [ libc.so.1 ld.so.1 ]
> <pc/ai						// read from corefile
M_Allocate_Stacks+0x114:
M_Allocate_Stacks+0x114:        unimp     0
> <pc?ai						// read from object
M_Allocate_Stacks+0x114:
M_Allocate_Stacks+0x114:        cmp       %o0, -1

pl2wam is unable to read the text for its own instructions.

I rebuilt with configure --with-c-flags=DDEBUG for clarity here.

$ pl2wam
trying at high addr: 0 --> base: 0 length: 15761408
Segmentation Fault(coredump)

This message comes from M_Allocate_Stacks() which will passes this base,len
to Virtual_Mem_Alloc().

M_Allocate_Stacks() obtains a base address of zero through the following
code which iterates through an array of base addresses addr_to_try[]
until it allocates memory near one of them.

...
  WamWord *addr_to_try[] = { NULL,
...
  for(i = 0; addr == NULL && addr_to_try[i] != (WamWord *) -1; i++)
    {
       addr = addr_to_try[i];
...
       addr = Virtual_Mem_Alloc(addr, length);

Within Virtual_Mem_Alloc(), since per the platform definitions for solaris
we HAVE_MMAP, we call mmap():

  addr = (WamWord *) mmap((void *) addr, length, PROT_READ | PROT_WRITE,
                          MAP_PRIVATE
#ifdef MMAP_NEEDS_FIXED
                          | MAP_FIXED
#endif
#ifdef MAP_ANON
                          | MAP_ANON, -1,
#else
                          , fd,
#endif /* !MAP_ANON */
                          0);

So we are calling mmap over a range that includes our process text. Since
we are using MAP_FIXED we are forcing the system to return a mapping to
an exact address.

The use of MAP_FIXED is peculiar to solaris per EnginePl/machine.h:
#if defined(M_sunos) || defined(M_solaris)
#   define MMAP_NEEDS_FIXED
#endif

This code seems to be required to avoid tripping the debug printf which
looks like a previous solaris bug fix.

DBGPRINTF("  -> invalid high bits addr\n");

I was able to work around this issue by changing the definition of the
addr_to_try_array from:

>  WamWord *addr_to_try[] = { NULL,
>#ifdef M_MMAP_HIGH_ADR1
>                             (WamWord *) M_MMAP_HIGH_ADR1,

to:

>  WamWord *addr_to_try[] = {
>#ifndef MMAP_NEEDS_FIXED
>                             NULL,
>#endif
>#ifdef M_MMAP_HIGH_ADR1
>                             (WamWord *) M_MMAP_HIGH_ADR1,

With this change and the suggested change to stop using %g7 shown above
my build completed successfully.

Hopefully this report is useful to you and I've managed to explain
what I am seeing clearly: if you have any questions do feel free to contact
me. I look forward to using gprolog: thanks for developing and
maintaining this code.

Regards,

Dug

_______________________________________________
Bug-prolog mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-prolog
gprolog-1.2.19_configure_and_make.gz (application/octet-stream, 2.6 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.