[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>*** =3B =3B =3B Exception "IPE=
>rror.FatalError" not in RAISES list<BR>*** =3B =3B =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>
> =3B<BR>
>PROCEDURE GetHostAddr(): Address =3D<BR> =3B VAR hname: ARRAY [0..255] =
OF CHAR=3B<BR> =3B BEGIN<BR> =3B =3B =3B LOCK mu DO<BR>&nbs=
>p=3B =3B =3B =3B =3B IF Unix.gethostname(ADR(hname[0])=2C B=
>YTESIZE(hname)) # 0 THEN<BR> =3B =3B =3B =3B =3B =
>=3B =3B IPError.Die ()=3B<BR> =3B =3B =3B =3B =3B E=
>ND=3B<BR> =3B =3B =3B =3B =3B VAR h :=3D Unetdb.gethost=
>byname(ADR(hname[0]))=3B BEGIN<BR> =3B =3B =3B =3B =3B&=
>nbsp=3B =3B IF h =3D NIL THEN IPError.Die()=3B END=3B<BR> =3B =
>=3B =3B =3B =3B =3B =3B RETURN GetAddress(h)=3B<BR>&nbs=
>p=3B =3B =3B =3B =3B END=3B<BR> =3B =3B =3B END=
>=3B<BR> =3B END GetHostAddr=3B<BR>
><BR>PROCEDURE GetAddress (ent: Unetdb.struct_hostent_star): Address =3D<BR>=
> =3B VAR ua: Uin.struct_in_addr=3B<BR> =3B BEGIN<BR> =3B =
>=3B =3B <=3B* ASSERT ent.h_length <=3B=3D BYTESIZE(Address) *>=3B=
><BR> =3B =3B =3B ua :=3D LOOPHOLE(ent.h_addr_list=2C<BR> =
>=3B =3B =3B =3B =3B =3B =3B =3B =3B =3B=
> =3B =3B =3B =3B =3B =3B =3B =3B =3B UN=
>TRACED REF UNTRACED REF Uin.struct_in_addr)^^=3B<BR> =3B =3B =
>=3B RETURN LOOPHOLE(ua.s_addr=2C Address)=3B<BR> =3B END GetAddress=3B<=
>BR>
> =3B<BR>
>gethostbyname is failing.<BR>
><BR> =3B<BR>
>Analogous C code also fails:<BR>
> =3B<BR>
><BR>[jay at fbsdamd64a /cm3/bin]$ cat ~/5.c<BR>#include <=3Bassert.h>=3B<B=
>R>#include <=3Bnetdb.h>=3B<BR>#include <=3Bstdio.h>=3B<BR>#include =
><=3Berrno.h>=3B<BR>typedef struct hostent hostent_t=3B<BR>
> =3B<BR>
>int main()<BR>{<BR> =3Bchar hostname[200]=3B<BR> =3Bhostent_t* h=3B=
><BR> =3Bint i=3B<BR>
> =3Bi =3D gethostname(hostname=2C 200)=3B<BR> =3Bassert(i =3D=3D 0)=
>=3B<BR> =3Bprintf("hostname: %s\n"=2C hostname)=3B<BR> =3Bh =3D get=
>hostbyname(hostname)=3B<BR> =3Bherror("foo")=3B<BR> =3Bprintf("%p %=
>d %d\n"=2C h=2C errno=2C h_errno)=3B<BR> =3Bassert(h)=3B<BR> =3Bret=
>urn 0=3B<BR>}<BR>
> =3B<BR>
>herror says "unknown host".<BR>
><BR>Stack is:<BR>
> =3B =3B =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> =3B =3B =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> =3B =3B =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> =
>=3B =3B =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> =3B =3B =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> =3B =3B =3B at ../src/xvbt/XExtensions.m3=
>:14<BR>#19 0x00000008012467a4 in XClientF__Connect (M3_Bd56fi_inst=3D0x1879=
>b=2C<BR> =3B =3B =3B M3_AQuuui_trsl=3D0x6) at ../src/xvbt/XClie=
>ntF.m3:583<BR>---Type <=3Breturn>=3B to continue=2C or q <=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> =3B VAR<BR> =3B =3B&n=
>bsp=3B display =3B =3B =3B =3B =3B =3B =3B =
>=3B =3B =3B =3B =3B =3B =3B =3B =3B :=3D Di=
>splayHost(trsl)=3B<BR> =3B =3B =3B displayAddr: IP.Address=3B<B=
>R> =3B BEGIN<BR> =3B =3B =3B IF display =3D NIL THEN RETURN=
> TRUE=3B END=3B<BR>
> =3B =3B =3B TRY<BR> =3B =3B =3B =3B =3B IF=
> NOT IP.GetHostByName(display=2C displayAddr) THEN RETURN FALSE=3B END=3B<B=
>R> =3B =3B =3B =3B =3B RETURN displayAddr =3D IP.GetHos=
>tAddr()=3B<BR> =3B =3B =3B EXCEPT<BR> =3B =3B =3B |=
> IP.Error =3D>=3B RETURN FALSE=3B<BR> =3B =3B =3B END=3B<BR>&=
>nbsp=3B END SameHost=3B<BR>
> =3B<BR>
>Thoughts?<BR>
> =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> =3B<BR>
>Seems like SocketPosix has nearly the exact same code but appears<BR>more f=
>orgiving.. IOError instead of Fatal?<BR>
> =3B<BR>
><BR>SocketPosix.m3:<BR>
> =3B<BR>
><BR>PROCEDURE GetHostAddr (): Address<BR> =3B RAISES {OSError.E} =3D<BR=
>> =3B VAR<BR> =3B =3B =3B host : ARRAY [0..255] OF CHAR=3B<=
>BR> =3B =3B =3B info : Unetdb.struct_hostent_star=3B<BR> =
>=3B =3B =3B ua =3B =3B : Uin.struct_in_addr=3B<BR> =3B =
>BEGIN<BR> =3B =3B =3B IF Unix.gethostname (ADR (host[0])=2C BYT=
>ESIZE (host)) # 0 THEN<BR> =3B =3B =3B =3B =3B IOError =
>(Unexpected)=3B<BR> =3B =3B =3B END=3B<BR>
> =3B =3B =3B info :=3D Unetdb.gethostbyname (ADR (host[0]))=3B<=
>BR> =3B =3B =3B IF info =3D NIL THEN IOError (Unexpected)=3B EN=
>D=3B<BR> =3B =3B =3B <=3B* ASSERT info.h_length <=3B=3D BYT=
>ESIZE (Address) *>=3B<BR>
> =3B =3B =3B ua :=3D LOOPHOLE(info.h_addr_list=2C<BR> =3B&n=
>bsp=3B =3B =3B =3B =3B =3B =3B =3B =3B =
>=3B =3B =3B =3B =3B =3B =3B =3B UNTRACED REF UN=
>TRACED REF Uin.struct_in_addr)^^=3B<BR> =3B =3B =3B RETURN LOOP=
>HOLE (ua.s_addr=2C Address)=3B<BR> =3B END GetHostAddr=3B<BR>
> =3B<BR>
> =3B<BR>
>It is again disappointing to see such code duplication.<BR>
> =3B<BR>
> =3B<BR>
>I guess =3BSameHost can duplicate the logic to predict the error state =
>and return false =3Bupon error?<BR>
>Duplicating the logic for a third time. :(<BR>
> =3B<BR>
><BR> =3B- Jay<BR><BR></body>
></html>=
>
>--_9e67232c-a064-417d-879e-227a77e310f9_--
More information about the M3devel
mailing list