[AP-UTILS] Bus Error on Linux/Sparc

Erik Rossen ap-utils@kiev.iorta.com
Sun, 4 Aug 2002 23:41:16 +0200


--liOOAslEiF7prFVr
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Sat, Aug 03, 2002 at 05:02:21PM +0300, Roman Festchook wrote:
> On ??? 31 ??? 2002 15:36, Erik Rossen wrote:
> > The problem seems to be coming from the fact that raw structs are being
> > used to unpack information coming from SNMP requests.  One of the hard
> > lessons to learn in C is *never* use structs to unpack a data stream -
> > always parse it piece-by-piece, even if it is painfully unelegant.  This
> > is also necessary for taking care of endianess conversion.
> I rewrote code to do not use structures for unpack data comming from AP. =
Hope=20
> this fix problems with nonintel architectures. Latest tarball accesible a=
t=20
> web site:  http://ap-utils.polesye.net/files/ap-utils-1.0.3-020802.tar.bz=
2.
> Please test and report about success or fail.

Are you sure that you are parsing the data from the AP field-by-field?

I quickly diffed the last two versions of ap-utils and all that I saw is
that you are using my hack to malloc() memory for data structures and
then copying them to the new buffers with memcpy().  You are still
relying on the fields in the data stream from the AP to have exactly the
same internal alignment and byte order as whatever gcc compiles.

Although this malloc()ing will get rid of some of the alignment
problems, it is not a guarentee of correctness.  All that someone has to
do is to change the gcc compilation options (to optimise for space, for
example) and there will potentially be new strange errors occuring, even
on i386.

> > This software will probably never reliably work on any architecture
> > except i386 until it is re-written to not use structs for unpacking.  I
> I think its done - wait for your test.

It is not done - you have just removed a few symptoms.

If the guy who posted the original ap-utils-on-Sparc question tries the
new version, he is going to be disappointed by the statistics that he=20
sees when he tries the Info->Ethernet option.  The problem is that the
data in the EthernetRxStatistics struct coming from directly from the AP
is in little-endian format.  This displays fine with no conversion on
little-endian architectures like i386, but it is completely wrong on a
big-endian machine like a Sparc.  If your program was carefully parsing
the data stream field-by-field into each structure, this sort of error
would not occur.

I wrote the following patch of atmel/stat.c to get a few of the fields
to display proper numbers for me by converting them to bigendian format,
but it is only meant to be a demonstration of the endianess problem.  It
does *not* fix the fundamental problem which is that the data stream
must be parsed piece-by-piece.  It is too bad that libc does not have an
"unpack" function like Perl - that would make the job a lot easier for
you...

Cheers,

--- ap-utils-1.0.3-020802/atmel/stat.c	Sat Aug  3 15:19:55 2002
+++ ap-utils-1.0.3-020802.ERIK/atmel/stat.c	Sun Aug  4 14:09:42 2002
@@ -34,6 +34,10 @@
=20
 extern WINDOW *main_sub;
=20
+/* a quick-and-dirty macro to unconditionally swap bytes in 4-byte integers
+ * between big-endian and little-endian ordering */
+#define swap4(n) (((n) >> 24) + (((n) & 0x00FF0000) >>  8) + (((n) & 0x000=
0FF00) <<  8) + ((n) << 24))
+
 void EthStat()
 {
     struct EthernetRxStatistics *EthRxStat=3DNULL;
@@ -113,10 +117,10 @@
 	mvwaddstr(main_sub, 1, 2, _("Received:"));
 	mvwaddstr(main_sub, 1, 30, _("Transmited:"));
 	sprintf(message, "TotalBytes       %10lu TotalBytes         %10lu",
-		EthRxStat->TotalBytesRx, EthTxStat->TotalBytesTx);
+		swap4(EthRxStat->TotalBytesRx), EthTxStat->TotalBytesTx);
 	mvwaddstr(main_sub, 3, 2, message);
 	sprintf(message, "TotalPackets     %10lu TotalPackets       %10lu",
-		EthRxStat->TotalPacketsRx, EthTxStat->TotalPacketsTx);
+		swap4(EthRxStat->TotalPacketsRx), EthTxStat->TotalPacketsTx);
 	mvwaddstr(main_sub, 4, 2, message);
 	sprintf(message, "PacketCRCError   %10lu PacketCRCError     %10lu",
 		EthRxStat->PacketCRCErrorRx, EthTxStat->PacketCRCErrorTx);


--=20
Erik Rossen                          ^    OpenPGP key: 2935D0B9
rossen@freesurf.ch                  /e\   "Use GnuPG, see the
http://people.linux-gull.ch/rossen  ---    black helicopters."

--liOOAslEiF7prFVr
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9TZ97Y88aPik10LkRAgpaAJwJudwYl9JeL2rV53Brx2v6cFlqGwCfVkUN
iGtUhnCNLC/tuVdkPznojXI=
=RPv9
-----END PGP SIGNATURE-----

--liOOAslEiF7prFVr--