Bug somewhere in the XML stuff

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug somewhere in the XML stuff

Chris Uppal-3
I'm hitting a problem trying to use the new(-ish) XML package.  It is
causing Dolphin to go into an infinite loop that cannot be broken.

Here's a way to reproduce it that works every time on three of the machines
I have access to.

This is taken straight from the package comment:
    doc := IXMLDOMDocument new.
    doc loadURL: 'http://develop.com/soap/soapfaq.xml'.
    root := doc documentElement.

Then do:
    root getProperty: 'attributes'.

Dolphin hangs somewhere in or just after:
    VARIANT>>value
    IXMLDOMElement(IDispatch)>>invokeId:flags:parms:
    IXMLDOMElement(IDispatch)>>getPropertyId:
    IXMLDOMElement(IDispatch)>>getProperty:

The VM is in an unbreakable infinite loop and slowly uses more and more
memory.  I'd not be surprised if this is actually a problem in the
underlying DLL, but the fact that the Dolphin memory is growing at about
1MB/sec suggests that there is at least some interaction between Dolphin and
the DLL.

I've tried this on W2K sp1 and sp2, and on NT sp5.  The XML component was at
version 2, version 3 was not installed on any of the machines.  I'm using
Dolphin 4.01.

(BTW, what are OA's plans for the XML package; will it be enhanced to track
changes/enhancements in the M$-supplied components ?).

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Bug somewhere in the XML stuff

Blair McGlashan
Chris

"Chris Uppal" <[hidden email]> wrote in message
news:[hidden email]...
> I'm hitting a problem trying to use the new(-ish) XML package.  It is
> causing Dolphin to go into an infinite loop that cannot be broken.
>
> Here's a way to reproduce it that works every time on three of the
machines
> I have access to.
>
> This is taken straight from the package comment:
>     doc := IXMLDOMDocument new.
>     doc loadURL: 'http://develop.com/soap/soapfaq.xml'.
>     root := doc documentElement.
>
> Then do:
>     root getProperty: 'attributes'.

I'm sure you've used that expression just to reproduce the problem, but for
the benefit of the uninitiated one should of course evaluate 'root
attributes' instead to stay within the comfortable confines of the XML
package.

The problem is due to the way Dolphin attempts to "print" a raw IDispatch
object; it tries to include the "value" of the object, and if that is not
available then it tries to print the "contents" on the assumption that it
might be a collection. In this case the object is a collection, but has a
faulty implementation of IEnumVARIANT::Next(). When Dolphin enumerates
through IEnumXXXX, it attempts to retrieve the elements in blocks of 32 -
see IEnumXXXX>>upToEndDo:, terminating when zero elements are returned. This
ought to work fine, but in this case the COM object keeps returning 1
object, and thus Dolphin keeps enumerating. The same bug is probably
responsible for:

e := (root getProperty: 'attributes') newEnum.    "Ctrl+E"
e next.     "Ctrl+S, should get an IDispatch"
e next.    "Ctrl+S, walkback due to reading off end"
e next.    "Ctrl+S, whoops, the enumerator appears to have reset to the
beginning again"

Basically the enumerator should not be resetting to the beginning after it
has read off the end.

Anyway we can easily make Dolphin's IEnumXXXX>>upToEndDo: implementation a
bit more robust so that it can cope with objects that don't implement the
Next() method correctly (see attached).

>
> Dolphin hangs somewhere in or just after:
>     VARIANT>>value
>     IXMLDOMElement(IDispatch)>>invokeId:flags:parms:
>     IXMLDOMElement(IDispatch)>>getPropertyId:
>     IXMLDOMElement(IDispatch)>>getProperty:
>
> The VM is in an unbreakable infinite loop and slowly uses more and more
> memory....

I was able to break into the loop just fine using Ctrl+Break, because it is
looping in the Smalltalk code. The Dolphin VM doesn't contain any code for
interfacing with COM, apart from the very barest essentials (the ability to
invoke and implement virtual functions, understanding of basic COM types
such as BSTR). Behaviour in the debugger might lead you to think it is
locking up in the VM because the Debugger attempts to use #printOn: itself
to print the objects. In circumstances where this causes a problem one can
redefine #debugPrintString to avoid going through #printOn:, which is how I
was able to debug this (by implementing it as #basicPrintString on both
IDispatch and VARIANT). Another strangeness is caused by the fact that
IDispatch>>printOn: suppresses errors attempting to access the value and the
contents of the object, and since Ctrl+Break actually raises an exception
that too is suppressed so the expression just terminates without a walkback.

> (BTW, what are OA's plans for the XML package; will it be enhanced to
track
> changes/enhancements in the M$-supplied components ?).

We're intending to do a refresh when the doppler shift around it is no
longer apparent.

Regards

Blair


------------------------------------
!IEnumXXXX methodsFor!

upToEndDo: operation
 "Private - Evaluate the <monadicValuable> argument, transformer, for
 each of the remaining elements of the receiver.
 Implementation Note: To reduce round trips to the server object, the
elements
 are fetched in blocks of <N> at a time, where N is configurable. Note that
we
 stop enumerating when the object returns fewer elements than we ask for,
since
 it seems that some objects have a bug whereby they will restart the
enumerator
 after having read off the end. See #batchSize for further information."

 | count |
 count := self batchSize.

 [| elems |
 elems := self nextAvailable: count.
 elems do: [:e | operation value: e].
 elems size < count]
   whileFalse! !
!IEnumXXXX categoriesFor: #upToEndDo:!helpers!private! !