[M3devel] Juno (X) networking problem on AMD64_FREEBSD

Mika Nystrom mika at async.caltech.edu
Sun Jan 11 17:02:18 CET 2009


This is a screwy thing in Modula-3.  A bug I would call it.

I've noticed a lot of networking M3 programs don't work right unless
the return value of Unix's "hostname" maps to a real IP address via
gethostbyname.  I accomplish it in practice by adding my hostname
to /etc/hosts.

This is obviously not the right way to fix it...  

     Mika

Jay writes:
>--_9e67232c-a064-417d-879e-227a77e310f9_
>Content-Type: text/plain; charset="iso-8859-1"
>Content-Transfer-Encoding: quoted-printable
>
>
>Hi. Unix network programming question..
>AMD64_FREEBSD:
>$DISPLAY is set to point back to Cygwin host.It works for PPC_LINUX.
>[jay at fbsdamd64a /cm3/bin]$ ./Juno
>****** runtime error:***    Exception "IPError.FatalError" not in RAISES li=
>st***    file "../src/common/IPError.m3"=2C line 27***
>Abort trap: 6 (core dumped)[jay at fbsdamd64a /cm3/bin]$
>IP.m3:
>=20
>PROCEDURE GetHostAddr(): Address =3D  VAR hname: ARRAY [0..255] OF CHAR=3B =
> BEGIN    LOCK mu DO      IF Unix.gethostname(ADR(hname[0])=2C BYTESIZE(hna=
>me)) # 0 THEN        IPError.Die ()=3B      END=3B      VAR h :=3D Unetdb.g=
>ethostbyname(ADR(hname[0]))=3B BEGIN        IF h =3D NIL THEN IPError.Die()=
>=3B END=3B        RETURN GetAddress(h)=3B      END=3B    END=3B  END GetHos=
>tAddr=3B
>PROCEDURE GetAddress (ent: Unetdb.struct_hostent_star): Address =3D  VAR ua=
>: Uin.struct_in_addr=3B  BEGIN    <* ASSERT ent.h_length <=3D BYTESIZE(Addr=
>ess) *>    ua :=3D LOOPHOLE(ent.h_addr_list=2C                    UNTRACED =
>REF UNTRACED REF Uin.struct_in_addr)^^=3B    RETURN LOOPHOLE(ua.s_addr=2C A=
>ddress)=3B  END GetAddress=3B
>=20
>gethostbyname is failing.
>=20
>Analogous C code also fails:
>=20
>[jay at fbsdamd64a /cm3/bin]$ cat ~/5.c#include <assert.h>#include <netdb.h>#i=
>nclude <stdio.h>#include <errno.h>typedef struct hostent hostent_t=3B
>=20
>int main(){ char hostname[200]=3B hostent_t* h=3B int i=3B
> i =3D gethostname(hostname=2C 200)=3B assert(i =3D=3D 0)=3B printf("hostna=
>me: %s\n"=2C hostname)=3B h =3D gethostbyname(hostname)=3B herror("foo")=3B=
> printf("%p %d %d\n"=2C h=2C errno=2C h_errno)=3B assert(h)=3B return 0=3B}
>=20
>herror says "unknown host".
>Stack is:
>    at ../src/runtime/ex_frame/RTExFrame.m3:58#13 0x0000000801a7f2b3 in RTH=
>ooks__Raise (M3_AJWxb1_ex=3DError accessing memory address 0x8000ffffd278: =
>Bad address.)    at ../src/runtime/common/RTHooks.m3:79#14 0x000000080169c8=
>d3 in IPError__Die () at ../src/common/IPError.m3:27#15 0x0000000801698a3e =
>in IP__GetHostAddr (M3_BCxjPn__result=3DError accessing memory address 0x80=
>00ffffd338: Bad address.)    at ../src/POSIX/IP.m3:82#16 0x00000008012133d0=
> in XSharedMem__SameHost (M3_AQuuui_trsl=3DError accessing memory address 0=
>x8000ffffd4d8: Bad address.)    at ../src/xvbt/XSharedMem.m3:96#17 0x000000=
>0801212ab7 in XSharedMem__InitXClient (M3_AQuuui_v=3DError accessing memory=
> address 0x8000ffffd648: Bad address.)    at ../src/xvbt/XSharedMem.m3:29#1=
>8 0x0000000801211819 in XExtensions__InitXClient (M3_AQuuui_xclient=3DError=
> accessing memory address 0x8000ffffd7f8: Bad address.)    at ../src/xvbt/X=
>Extensions.m3:14#19 0x00000008012467a4 in XClientF__Connect (M3_Bd56fi_inst=
>=3D0x1879b=2C    M3_AQuuui_trsl=3D0x6) at ../src/xvbt/XClientF.m3:583---Typ=
>e <return> to continue=2C or q <return> to quit---(More stack frames follow=
>...)(gdb)
>(* return TRUE if server and client are on same host *)PROCEDURE SameHost (=
>trsl: XClient.T): BOOLEAN =3D  VAR    display                 :=3D DisplayH=
>ost(trsl)=3B    displayAddr: IP.Address=3B  BEGIN    IF display =3D NIL THE=
>N RETURN TRUE=3B END=3B
>    TRY      IF NOT IP.GetHostByName(display=2C displayAddr) THEN RETURN FA=
>LSE=3B END=3B      RETURN displayAddr =3D IP.GetHostAddr()=3B    EXCEPT    =
>| IP.Error =3D> RETURN FALSE=3B    END=3B  END SameHost=3B
>=20
>Thoughts?
>=20
>Perhaps my network isn't setup well=2C like I should add the local machine =
>to /etc/hosts.I think this can be made to fail gracefully though.It seems l=
>ike it has nothing to do with AMD64_FREEBSD=2C but could have to do with Fr=
>eeBSD.
>=20
>Seems like SocketPosix has nearly the exact same code but appearsmore forgi=
>ving.. IOError instead of Fatal?
>=20
>SocketPosix.m3:
>=20
>PROCEDURE GetHostAddr (): Address  RAISES {OSError.E} =3D  VAR    host : AR=
>RAY [0..255] OF CHAR=3B    info : Unetdb.struct_hostent_star=3B    ua   : U=
>in.struct_in_addr=3B  BEGIN    IF Unix.gethostname (ADR (host[0])=2C BYTESI=
>ZE (host)) # 0 THEN      IOError (Unexpected)=3B    END=3B
>    info :=3D Unetdb.gethostbyname (ADR (host[0]))=3B    IF info =3D NIL TH=
>EN IOError (Unexpected)=3B END=3B    <* ASSERT info.h_length <=3D BYTESIZE =
>(Address) *>
>    ua :=3D LOOPHOLE(info.h_addr_list=2C                   UNTRACED REF UNT=
>RACED REF Uin.struct_in_addr)^^=3B    RETURN LOOPHOLE (ua.s_addr=2C Address=
>)=3B  END GetHostAddr=3B
>=20
>=20
>It is again disappointing to see such code duplication.
>=20
>=20
>I guess SameHost can duplicate the logic to predict the error state and ret=
>urn false upon error?
>Duplicating the logic for a third time. :(
>=20
> - Jay=
>
>--_9e67232c-a064-417d-879e-227a77e310f9_
>Content-Type: text/html; charset="iso-8859-1"
>Content-Transfer-Encoding: quoted-printable
>
><html>
><head>
><style>
>.hmmessage P
>{
>margin:0px=3B
>padding:0px
>}
>body.hmmessage
>{
>font-size: 10pt=3B
>font-family:Verdana
>}
></style>
></head>
><body class=3D'hmmessage'>
>Hi. Unix network programming question..<BR>
><BR>AMD64_FREEBSD:<BR>
><BR>$DISPLAY is set to point back to Cygwin host.<BR>It works for PPC_LINUX=
>.<BR>
><BR>[jay at fbsdamd64a /cm3/bin]$ ./Juno<BR>
><BR>***<BR>*** runtime error:<BR>***&nbsp=3B&nbsp=3B&nbsp=3B Exception "IPE=
>rror.FatalError" not in RAISES list<BR>***&nbsp=3B&nbsp=3B&nbsp=3B file "..=
>/src/common/IPError.m3"=2C line 27<BR>***<BR>
><BR>Abort trap: 6 (core dumped)<BR>[jay at fbsdamd64a /cm3/bin]$<BR>
><BR>IP.m3:<BR>
>&nbsp=3B<BR>
>PROCEDURE GetHostAddr(): Address =3D<BR>&nbsp=3B VAR hname: ARRAY [0..255] =
OF CHAR=3B<BR>&nbsp=3B BEGIN<BR>&nbsp=3B&nbsp=3B&nbsp=3B LOCK mu DO<BR>&nbs=
>p=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B IF Unix.gethostname(ADR(hname[0])=2C B=
>YTESIZE(hname)) # 0 THEN<BR>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=
>=3B&nbsp=3B IPError.Die ()=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B E=
>ND=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B VAR h :=3D Unetdb.gethost=
>byname(ADR(hname[0]))=3B BEGIN<BR>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&=
>nbsp=3B&nbsp=3B IF h =3D NIL THEN IPError.Die()=3B END=3B<BR>&nbsp=3B&nbsp=
>=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B RETURN GetAddress(h)=3B<BR>&nbs=
>p=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B END=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B END=
>=3B<BR>&nbsp=3B END GetHostAddr=3B<BR>
><BR>PROCEDURE GetAddress (ent: Unetdb.struct_hostent_star): Address =3D<BR>=
>&nbsp=3B VAR ua: Uin.struct_in_addr=3B<BR>&nbsp=3B BEGIN<BR>&nbsp=3B&nbsp=
>=3B&nbsp=3B &lt=3B* ASSERT ent.h_length &lt=3B=3D BYTESIZE(Address) *&gt=3B=
><BR>&nbsp=3B&nbsp=3B&nbsp=3B ua :=3D LOOPHOLE(ent.h_addr_list=2C<BR>&nbsp=
>=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B=
>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B UN=
>TRACED REF UNTRACED REF Uin.struct_in_addr)^^=3B<BR>&nbsp=3B&nbsp=3B&nbsp=
>=3B RETURN LOOPHOLE(ua.s_addr=2C Address)=3B<BR>&nbsp=3B END GetAddress=3B<=
>BR>
>&nbsp=3B<BR>
>gethostbyname is failing.<BR>
><BR>&nbsp=3B<BR>
>Analogous C code also fails:<BR>
>&nbsp=3B<BR>
><BR>[jay at fbsdamd64a /cm3/bin]$ cat ~/5.c<BR>#include &lt=3Bassert.h&gt=3B<B=
>R>#include &lt=3Bnetdb.h&gt=3B<BR>#include &lt=3Bstdio.h&gt=3B<BR>#include =
>&lt=3Berrno.h&gt=3B<BR>typedef struct hostent hostent_t=3B<BR>
>&nbsp=3B<BR>
>int main()<BR>{<BR>&nbsp=3Bchar hostname[200]=3B<BR>&nbsp=3Bhostent_t* h=3B=
><BR>&nbsp=3Bint i=3B<BR>
>&nbsp=3Bi =3D gethostname(hostname=2C 200)=3B<BR>&nbsp=3Bassert(i =3D=3D 0)=
>=3B<BR>&nbsp=3Bprintf("hostname: %s\n"=2C hostname)=3B<BR>&nbsp=3Bh =3D get=
>hostbyname(hostname)=3B<BR>&nbsp=3Bherror("foo")=3B<BR>&nbsp=3Bprintf("%p %=
>d %d\n"=2C h=2C errno=2C h_errno)=3B<BR>&nbsp=3Bassert(h)=3B<BR>&nbsp=3Bret=
>urn 0=3B<BR>}<BR>
>&nbsp=3B<BR>
>herror says "unknown host".<BR>
><BR>Stack is:<BR>
>&nbsp=3B&nbsp=3B&nbsp=3B at ../src/runtime/ex_frame/RTExFrame.m3:58<BR>#13 =
>0x0000000801a7f2b3 in RTHooks__Raise (M3_AJWxb1_ex=3DError accessing memory=
> ad<BR>dress 0x8000ffffd278: Bad address.<BR>)<BR>&nbsp=3B&nbsp=3B&nbsp=3B =
>at ../src/runtime/common/RTHooks.m3:79<BR>#14 0x000000080169c8d3 in IPError=
>__Die () at ../src/common/IPError.m3:27<BR>#15 0x0000000801698a3e in IP__Ge=
>tHostAddr (M3_BCxjPn__result=3DError accessing mem<BR>ory address 0x8000fff=
>fd338: Bad address.<BR>)<BR>&nbsp=3B&nbsp=3B&nbsp=3B at ../src/POSIX/IP.m3:=
>82<BR>#16 0x00000008012133d0 in XSharedMem__SameHost (M3_AQuuui_trsl=3DErro=
>r accessing m<BR>emory address 0x8000ffffd4d8: Bad address.<BR>)<BR>&nbsp=
>=3B&nbsp=3B&nbsp=3B at ../src/xvbt/XSharedMem.m3:96<BR>#17 0x0000000801212a=
>b7 in XSharedMem__InitXClient (M3_AQuuui_v=3DError accessing m<BR>emory add=
>ress 0x8000ffffd648: Bad address.<BR>)<BR>&nbsp=3B&nbsp=3B&nbsp=3B at ../sr=
>c/xvbt/XSharedMem.m3:29<BR>#18 0x0000000801211819 in XExtensions__InitXClie=
>nt (M3_AQuuui_xclient=3DError acce<BR>ssing memory address 0x8000ffffd7f8: =
>Bad address.<BR>)<BR>&nbsp=3B&nbsp=3B&nbsp=3B at ../src/xvbt/XExtensions.m3=
>:14<BR>#19 0x00000008012467a4 in XClientF__Connect (M3_Bd56fi_inst=3D0x1879=
>b=2C<BR>&nbsp=3B&nbsp=3B&nbsp=3B M3_AQuuui_trsl=3D0x6) at ../src/xvbt/XClie=
>ntF.m3:583<BR>---Type &lt=3Breturn&gt=3B to continue=2C or q &lt=3Breturn&g=
>t=3B to quit---<BR>(More stack frames follow...)<BR>(gdb)<BR>
><BR>(* return TRUE if server and client are on same host *)<BR>PROCEDURE Sa=
>meHost (trsl: XClient.T): BOOLEAN =3D<BR>&nbsp=3B VAR<BR>&nbsp=3B&nbsp=3B&n=
>bsp=3B display&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=
>=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B :=3D Di=
>splayHost(trsl)=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B displayAddr: IP.Address=3B<B=
>R>&nbsp=3B BEGIN<BR>&nbsp=3B&nbsp=3B&nbsp=3B IF display =3D NIL THEN RETURN=
> TRUE=3B END=3B<BR>
>&nbsp=3B&nbsp=3B&nbsp=3B TRY<BR>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B IF=
> NOT IP.GetHostByName(display=2C displayAddr) THEN RETURN FALSE=3B END=3B<B=
>R>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B RETURN displayAddr =3D IP.GetHos=
>tAddr()=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B EXCEPT<BR>&nbsp=3B&nbsp=3B&nbsp=3B |=
> IP.Error =3D&gt=3B RETURN FALSE=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B END=3B<BR>&=
>nbsp=3B END SameHost=3B<BR>
>&nbsp=3B<BR>
>Thoughts?<BR>
>&nbsp=3B<BR>
><BR>Perhaps my network isn't setup well=2C like I should add the local mach=
>ine to /etc/hosts.<BR>I think this can be made to fail gracefully though.<B=
>R>It seems like it has nothing to do with AMD64_FREEBSD=2C but could have t=
>o do with FreeBSD.<BR>
><BR>&nbsp=3B<BR>
>Seems like SocketPosix has nearly the exact same code but appears<BR>more f=
>orgiving.. IOError instead of Fatal?<BR>
>&nbsp=3B<BR>
><BR>SocketPosix.m3:<BR>
>&nbsp=3B<BR>
><BR>PROCEDURE GetHostAddr (): Address<BR>&nbsp=3B RAISES {OSError.E} =3D<BR=
>>&nbsp=3B VAR<BR>&nbsp=3B&nbsp=3B&nbsp=3B host : ARRAY [0..255] OF CHAR=3B<=
>BR>&nbsp=3B&nbsp=3B&nbsp=3B info : Unetdb.struct_hostent_star=3B<BR>&nbsp=
>=3B&nbsp=3B&nbsp=3B ua&nbsp=3B&nbsp=3B : Uin.struct_in_addr=3B<BR>&nbsp=3B =
>BEGIN<BR>&nbsp=3B&nbsp=3B&nbsp=3B IF Unix.gethostname (ADR (host[0])=2C BYT=
>ESIZE (host)) # 0 THEN<BR>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B IOError =
>(Unexpected)=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B END=3B<BR>
>&nbsp=3B&nbsp=3B&nbsp=3B info :=3D Unetdb.gethostbyname (ADR (host[0]))=3B<=
>BR>&nbsp=3B&nbsp=3B&nbsp=3B IF info =3D NIL THEN IOError (Unexpected)=3B EN=
>D=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B &lt=3B* ASSERT info.h_length &lt=3B=3D BYT=
>ESIZE (Address) *&gt=3B<BR>
>&nbsp=3B&nbsp=3B&nbsp=3B ua :=3D LOOPHOLE(info.h_addr_list=2C<BR>&nbsp=3B&n=
>bsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=
>=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B UNTRACED REF UN=
>TRACED REF Uin.struct_in_addr)^^=3B<BR>&nbsp=3B&nbsp=3B&nbsp=3B RETURN LOOP=
>HOLE (ua.s_addr=2C Address)=3B<BR>&nbsp=3B END GetHostAddr=3B<BR>
>&nbsp=3B<BR>
>&nbsp=3B<BR>
>It is again disappointing to see such code duplication.<BR>
>&nbsp=3B<BR>
>&nbsp=3B<BR>
>I guess&nbsp=3BSameHost can duplicate the logic to predict the error state =
>and return false&nbsp=3Bupon error?<BR>
>Duplicating the logic for a third time. :(<BR>
>&nbsp=3B<BR>
><BR>&nbsp=3B- Jay<BR><BR></body>
></html>=
>
>--_9e67232c-a064-417d-879e-227a77e310f9_--



More information about the M3devel mailing list