bug-prolog
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

a couple of problems building gprolog on sparc/solaris


From: dugald . foreman
Subject: a couple of problems building gprolog on sparc/solaris
Date: Mon, 27 Feb 2006 21:39:53 +0000 (GMT)

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

Attachment: gprolog-1.2.19_configure_and_make.gz
Description: Binary data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]