Unfortunately, this is an issue which I cant easily reproduce, at least not without a third party tool (1525). Now I would like the general opinion/experience of debugging Morphic code especially in threads. Usually an exception raised from within Morphic code pops up a debugger as usual. However, from time to time, or for more complicated stuff, the situation runs out of hand and tons of debugger pop up everywhere because the same faulty gets obviously executed again and again. Now can somebody with some Morphic knowledge explain how this is supposed to work and how to deal with such issues? -- Simon _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Simon,
I can't speak to the specifics of your problem, but recursive errors
from a GUI thread can indeed happen. Imagine if the debugger itself had
trouble opening. Note that problem does not necessarily have to be "in the
debugger;" it is enough to have the attempt to open it invalidate something else
and trigger another debugger which invalidates something and so on until you run
out of memory or patience.
Some general comments:
(1) this type of thing is why I kick up dust any time somebody wants
to take away the notifier (aka pre-debugger, aka walkback window). The
full debugger takes time to open, and that extra time can make it that much
harder to interrupt something that is going nuts.
(2) Debugging drawing code is probably best done using a single-shot
breakpoint. I _think_ I have seen something about halt once in
Pharo. FWIW, somebody posted a class called Once that creates such a
feature that looks like
Once do:[
"do anything here, but
this is common:"
self
halt.
].
Somewhere you need to do Once reset or something (it's obvious from
the code) to enable the breakpoint. Once evaluates the block one time, and
then won't evaluate the block again until told to do so. If there is a
need for this in Pharo, I should be able to "port" it - IIRC, it was licensed
for public consumption.
(3) I
have yet identify this in Morphic (haven't had time to look for it), but a
LOT of community-created Dolphin code for views is completely
needless. Yup, I said that :) It's true too. Many times I have
seen people create a view when they could just as easily create a bitmap and
display it in an image presenter. The latter can be done efficiently by
redrawing pieces of the bitmap and updating only the corresponding portion of
the image presenter - no custom view required. The savings in
programming overhead is larger than it might seem due to Dolphin's handling of
views as serialized objects.
Avoiding the custom view also simplifies
debugging. One can write code to draw to an in-memory bitmap and debug
essentially free of concern. Once it stops raising errors and runs, then
display the result in an image presenter and fix the visual problems. At
the same time, add some resolution-based drawing, and you have something that
can print in addition to drawing on the display. You might think about
adopting analogous practices.
(4) I
partition things into "just Smalltalk" and dangerous external interfacing.
By "just Smalltalk" I mean things that might go into an infinite loop, but
should never do anything horrible in terms of memory access. On the
dangerous side, I consider anything newly changed in the way of FFI and
changes to GUI elements; the latter goes on the list because it can meltdown as
you are seeing. For such situations, I get the image ready do the work,
including a do-it in plain view, save the image, and then do the thing that
might blow up. If it gets ugly, I use the debugger to learn what I can,
quit w/o saving, and start the next iteration. That way, I (hopefully)
never save an unstable image.
Bill
From: [hidden email] [mailto:[hidden email]] On Behalf Of Simon Denier Sent: Monday, November 30, 2009 2:18 PM To: Pharo Development Cc: Simon Denier Subject: [Pharo-project] Is there something wrong in debugging in the Morphic thread? Unfortunately, this is an issue which I cant easily reproduce, at least not
without a third party tool (1525). Now I
would like the general opinion/experience of debugging Morphic code especially
in threads.
Usually an exception raised from within Morphic code pops up a debugger as
usual. However, from time to time, or for more complicated stuff, the situation
runs out of hand and tons of debugger pop up everywhere because the same faulty
gets obviously executed again and again.
Now can somebody with some Morphic knowledge explain how this is supposed
to work and how to deal with such issues? --
Simon
_______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
The problem we're encountering is really vicious. It is hard to
identify a situation when it happens. I tried to define a simple subclass of morph with an erroneous drawOn: method, but it behaved as one would expect: the morph is colored in red. In mondrian, if a zero- arg block is provided when a one-arg block is expected, boom... Hard to reproduce... Cheers, Alexandre On 30 Nov 2009, at 18:06, Schwab,Wilhelm K wrote: > Simon, > > I can't speak to the specifics of your problem, but recursive errors > from a GUI thread can indeed happen. Imagine if the debugger itself > had trouble opening. Note that problem does not necessarily have to > be "in the debugger;" it is enough to have the attempt to open it > invalidate something else and trigger another debugger which > invalidates something and so on until you run out of memory or > patience. > > Some general comments: > > (1) this type of thing is why I kick up dust any time somebody wants > to take away the notifier (aka pre-debugger, aka walkback window). > The full debugger takes time to open, and that extra time can make > it that much harder to interrupt something that is going nuts. > > (2) Debugging drawing code is probably best done using a single-shot > breakpoint. I _think_ I have seen something about halt once in > Pharo. FWIW, somebody posted a class called Once that creates such > a feature that looks like > > Once do:[ > "do anything here, but this is common:" > self halt. > ]. > > Somewhere you need to do Once reset or something (it's obvious from > the code) to enable the breakpoint. Once evaluates the block one > time, and then won't evaluate the block again until told to do so. > If there is a need for this in Pharo, I should be able to "port" it > - IIRC, it was licensed for public consumption. > > (3) I have yet identify this in Morphic (haven't had time to look > for it), but a LOT of community-created Dolphin code for views is > completely needless. Yup, I said that :) It's true too. Many > times I have seen people create a view when they could just as > easily create a bitmap and display it in an image presenter. The > latter can be done efficiently by redrawing pieces of the bitmap and > updating only the corresponding portion of the image presenter - no > custom view required. The savings in programming overhead is > larger than it might seem due to Dolphin's handling of views as > serialized objects. > > Avoiding the custom view also simplifies debugging. One can write > code to draw to an in-memory bitmap and debug essentially free of > concern. Once it stops raising errors and runs, then display the > result in an image presenter and fix the visual problems. At the > same time, add some resolution-based drawing, and you have something > that can print in addition to drawing on the display. You might > think about adopting analogous practices. > > (4) I partition things into "just Smalltalk" and dangerous external > interfacing. By "just Smalltalk" I mean things that might go into > an infinite loop, but should never do anything horrible in terms of > memory access. On the dangerous side, I consider anything newly > changed in the way of FFI and changes to GUI elements; the latter > goes on the list because it can meltdown as you are seeing. For > such situations, I get the image ready do the work, including a do- > it in plain view, save the image, and then do the thing that might > blow up. If it gets ugly, I use the debugger to learn what I can, > quit w/o saving, and start the next iteration. That way, I > (hopefully) never save an unstable image. > > Bill > > > > From: [hidden email] [mailto:[hidden email] > ] On Behalf Of Simon Denier > Sent: Monday, November 30, 2009 2:18 PM > To: Pharo Development > Cc: Simon Denier > Subject: [Pharo-project] Is there something wrong in debugging in > the Morphic thread? > > > Unfortunately, this is an issue which I cant easily reproduce, at > least not without a third party tool (1525). Now I would like the > general opinion/experience of debugging Morphic code especially in > threads. > > Usually an exception raised from within Morphic code pops up a > debugger as usual. However, from time to time, or for more > complicated stuff, the situation runs out of hand and tons of > debugger pop up everywhere because the same faulty gets obviously > executed again and again. > > Now can somebody with some Morphic knowledge explain how this is > supposed to work and how to deal with such issues? > > -- > Simon > > > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Schwab,Wilhelm K
On 30.11.2009 22:06, Schwab,Wilhelm K wrote:
It exists already, is called haltOnce, and is used in the same manner as halt. To arm it, evaluate Object setHaltOnce. Make sure to remove them when you finish debugging though, since the overhead is non-negligible. This is rather primitive approach, but here's one way I've handled it in the past: 1. Read the debug.log 2.Handle the error by returning false (in that they may not be correct for the state), but valid values. 3.Insert a haltOnce which fires if the error condition arrises. 4.Trigger the error condition. 5. optional: Copy all instvars used in the method into temps if you're able to proceed with no error, then redo 3 and 4. (when the debugger opens, the object may no longer be in a state trigger the error condition). You should now have a responsibe debugger (due to step 2&3), and access to the parameter values that make it fail (step4). It's not much, and there are probably much better ways to go about it, but at least it's a start for debugging the problem. Good luck, Henry _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Nov 30, 2009, at 10:51 PM, Henrik Sperre Johansen wrote: > On 30.11.2009 22:06, Schwab,Wilhelm K wrote: >> >> >> (2) Debugging drawing code is probably best done using a single-shot breakpoint. I _think_ I have seen something about halt once in Pharo. FWIW, somebody posted a class called Once that creates such a feature that looks like >> >> Once do:[ >> "do anything here, but this is common:" >> self halt. >> ]. >> >> Somewhere you need to do Once reset or something (it's obvious from the code) to enable the breakpoint. Once evaluates the block one time, and then won't evaluate the block again until told to do so. If there is a need for this in Pharo, I should be able to "port" it - IIRC, it was licensed for public consumption. > It exists already, is called haltOnce, and is used in the same manner as halt. To arm it, evaluate Object setHaltOnce. Make sure to remove them when you finish debugging though, since the overhead is non-negligible. In addition, I added a trivial version of "contextual" or "subjective" halt feature to #haltIf:. It looks up the stack and only halts if there is a method with the name if the parameter is a symbol. Thus you can do: self haltIf: #testThatIWrote Of course, at some point (years, not days, I fear) we will make the deep principle that is hidden in this idea a core feature of the reflective model... Marcus _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Simon Denier-3
Hi Simon,
Have you tried http://www.squeaksource.com/LightweightClasses.html ? It's in an experimental stage, but I've used it succesfully for the recursive debugger problem. You may load it in Pharo-Core this way : Gofer new squeaksource: 'LightweightClasses'; addPackage: 'ParametrizedCompiler'; addPackage: 'LightweightClasses'; addPackage: 'OBLightweightClass'; load; recompile. Cordialement, Hernán 2009/11/30 Simon Denier <[hidden email]>: > > Unfortunately, this is an issue which I cant easily reproduce, at least not > without a third party tool (1525). Now I would like the general > opinion/experience of debugging Morphic code especially in threads. > Usually an exception raised from within Morphic code pops up a debugger as > usual. However, from time to time, or for more complicated stuff, the > situation runs out of hand and tons of debugger pop up everywhere because > the same faulty gets obviously executed again and again. > Now can somebody with some Morphic knowledge explain how this is supposed to > work and how to deal with such issues? > -- > Simon > > > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
OK folks, thanks for your suggestions, I will see how to be more
careful with such threads. The instance browser seems a very interesting idea and I will try to use it (although not necessarily for such problems, but for bugs popping up during very long computations, it can be great). As well is the idea of drawing in a bitmap canvas before displaying: I would like to see some kind of better sandboxing for such problems... Another cup of big bad error this morning. After seeing the image freezes once again on a long process, out of frustration I tried to interrupt it multiple times. I didn't get any debugger and the VM just quit after a while, but at least it seems like the stack dump still works in this case. So the last stack dump looks like this: Bitmap class(Behavior)>>basicNew: Receiver: Bitmap Arguments and temporary variables: sizeRequested: 206074 Receiver's instance variables: superclass: ArrayedCollection methodDict: a MethodDictionary(#asByteArray->a CompiledMethod(4056: Bitmap>>asB...etc... format: 33538 instanceVariables: nil organization: ('accessing' atAllPut: bitPatternForDepth: byteAt: byteAt:put: by...etc... subclasses: nil name: #Bitmap classPool: a Dictionary() sharedPools: nil environment: nil category: #'Graphics-Primitives' traitComposition: nil localSelectors: nil Bitmap class(Behavior)>>basicNew: Bitmap class(Behavior)>>basicNew: Bitmap class(Behavior)>>basicNew: Bitmap class(Behavior)>>basicNew: etc. while it's trying to open the debugger. Now I would like to get a better understanding. Why does this primitive keep failing and retry? My best guess is that the VM runs out of ressources (memory) but can not report it. On 1 déc. 2009, at 03:01, Hernán Morales Durand wrote: > Hi Simon, > Have you tried http://www.squeaksource.com/LightweightClasses.html ? > It's in an experimental stage, but I've used it succesfully for the > recursive debugger problem. You may load it in Pharo-Core this way : > > Gofer new > squeaksource: 'LightweightClasses'; > addPackage: 'ParametrizedCompiler'; > addPackage: 'LightweightClasses'; > addPackage: 'OBLightweightClass'; > load; > recompile. > > Cordialement, > > Hernán > > 2009/11/30 Simon Denier <[hidden email]>: >> >> Unfortunately, this is an issue which I cant easily reproduce, at >> least not >> without a third party tool (1525). Now I would like the general >> opinion/experience of debugging Morphic code especially in threads. >> Usually an exception raised from within Morphic code pops up a >> debugger as >> usual. However, from time to time, or for more complicated stuff, the >> situation runs out of hand and tons of debugger pop up everywhere >> because >> the same faulty gets obviously executed again and again. >> Now can somebody with some Morphic knowledge explain how this is >> supposed to >> work and how to deal with such issues? >> -- >> Simon >> >> >> >> _______________________________________________ >> Pharo-project mailing list >> [hidden email] >> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project >> > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project -- Simon _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
I guess this has to do with the cache I introduced a while ago. We
will discuss about this at lunch. Cheers, Alexandre On 1 Dec 2009, at 11:40, Simon Denier wrote: > OK folks, thanks for your suggestions, I will see how to be more > careful with such threads. The instance browser seems a very > interesting idea and I will try to use it (although not necessarily > for such problems, but for bugs popping up during very long > computations, it can be great). As well is the idea of drawing in a > bitmap canvas before displaying: I would like to see some kind of > better sandboxing for such problems... > > > Another cup of big bad error this morning. After seeing the image > freezes once again on a long process, out of frustration I tried to > interrupt it multiple times. I didn't get any debugger and the VM just > quit after a while, but at least it seems like the stack dump still > works in this case. So the last stack dump looks like this: > > Bitmap class(Behavior)>>basicNew: > Receiver: Bitmap > Arguments and temporary variables: > sizeRequested: 206074 > Receiver's instance variables: > superclass: ArrayedCollection > methodDict: a MethodDictionary(#asByteArray->a CompiledMethod(4056: > Bitmap>>asB...etc... > format: 33538 > instanceVariables: nil > organization: ('accessing' atAllPut: bitPatternForDepth: byteAt: > byteAt:put: by...etc... > subclasses: nil > name: #Bitmap > classPool: a Dictionary() > sharedPools: nil > environment: nil > category: #'Graphics-Primitives' > traitComposition: nil > localSelectors: nil > > Bitmap class(Behavior)>>basicNew: > Bitmap class(Behavior)>>basicNew: > Bitmap class(Behavior)>>basicNew: > Bitmap class(Behavior)>>basicNew: > etc. > > while it's trying to open the debugger. > > Now I would like to get a better understanding. Why does this > primitive keep failing and retry? My best guess is that the VM runs > out of ressources (memory) but can not report it. > > > > > On 1 déc. 2009, at 03:01, Hernán Morales Durand wrote: > >> Hi Simon, >> Have you tried http://www.squeaksource.com/LightweightClasses.html ? >> It's in an experimental stage, but I've used it succesfully for the >> recursive debugger problem. You may load it in Pharo-Core this way : >> >> Gofer new >> squeaksource: 'LightweightClasses'; >> addPackage: 'ParametrizedCompiler'; >> addPackage: 'LightweightClasses'; >> addPackage: 'OBLightweightClass'; >> load; >> recompile. >> >> Cordialement, >> >> Hernán >> >> 2009/11/30 Simon Denier <[hidden email]>: >>> >>> Unfortunately, this is an issue which I cant easily reproduce, at >>> least not >>> without a third party tool (1525). Now I would like the general >>> opinion/experience of debugging Morphic code especially in threads. >>> Usually an exception raised from within Morphic code pops up a >>> debugger as >>> usual. However, from time to time, or for more complicated stuff, >>> the >>> situation runs out of hand and tons of debugger pop up everywhere >>> because >>> the same faulty gets obviously executed again and again. >>> Now can somebody with some Morphic knowledge explain how this is >>> supposed to >>> work and how to deal with such issues? >>> -- >>> Simon >>> >>> >>> >>> _______________________________________________ >>> Pharo-project mailing list >>> [hidden email] >>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project >>> >> >> _______________________________________________ >> Pharo-project mailing list >> [hidden email] >> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > > -- > Simon > > > > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Free forum by Nabble | Edit this page |