[M3devel] netobj bug report

mika at async.caltech.edu mika at async.caltech.edu
Fri Jun 28 01:00:39 CEST 2013


Hi m3devel,

I think I found a bug in the Network Objects code.

Here is what I was doing: I made an object that I wanted to export
using Network Objects, but I *also* wanted to Pickle the object locally
(for persistence).

I find that if I create the object and try to pickle it, I get a Pickle error
"Can't pickle a surrogate object".  

The source of the error is in StubLib.m3, the Pickle special that is recorded
for network objects:

PROCEDURE OutSpecial(self: Pickle.Special;
                 r: REFANY;
                 writer: Pickle.Writer)
  RAISES  {Pickle.Error, Wr.Failure, Thread.Alerted} =
  BEGIN
    TYPECASE writer OF
    | SpecWr(wtr) => OutRef(wtr.c, r);
    ELSE
      TYPECASE r OF
      | NetObj.T(x) =>
          IF NOT ISTYPE(x.r, Transport.Location) THEN
            (* This will gratuitously pickle the ExportInfo ref
               embedded in x.r.  It would be better to exclude this
               if and when possible, but it shouldn't hurt for now. *)
            Pickle.Special.write(self, r, writer);
          ELSE
            RAISE Pickle.Error("Can't pickle a surrogate object");
          END;
      ELSE RAISE Pickle.Error("Can't Pickle Rd.T or Wr.T");
      END;
    END;
  END OutSpecial;

(In CM3, OutSpecial2 has the same bug for Pickle2 pickles.  PM3 doesn't 
have Pickle2 nor OutSpecial2.)

The problem is the test

         IF NOT ISTYPE(x.r, Transport.Location) THEN
            (* This will gratuitously pickle the ExportInfo ref
               embedded in x.r.  It would be better to exclude this
               if and when possible, but it shouldn't hurt for now. *)
            Pickle.Special.write(self, r, writer);
          ELSE
            RAISE Pickle.Error("Can't pickle a surrogate object");
          END;

The intent, I think, is that an object that is remote (that is, has x.r
of type Transport.Location) should not be pickle-able.

The problem is that x.r is initially NIL, and NIL is a member of
Transport.Location.

My workaround is to FIRST export the object before attempting to Pickle
it.  This works fine but it shouldn't be necessary, should it?  What if
I don't want to export the object, but just pickle it?

I believe the test should be changed to be

IF x.r = NIL OR NOT ISTYPE(x.r, Transport.Location) THEN...

    Mika





More information about the M3devel mailing list