[Top][All Lists]
[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
gprolog-1.2.19_configure_and_make.gz
Description: Binary data
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- a couple of problems building gprolog on sparc/solaris,
dugald . foreman <=