Hi,
We have a GemStone database (3.1.0.5) that apparently misbehaves in seaside callback processing. Has anyone encountered something like this? We'll appreciate the help we can get. We are processing callbacks as the following method is on the stack: WACallbackRegistry >> handle: aRequestContext The method calls evaluateWithFieldValues: on each callback: ... set sorted do: [ :callback | callback evaluateWithFieldValues: (fields allAt: callback key) ] ... In a database that behaves, the previous stack frame (n - 1) is WACallback >> evaluateWithFieldValues: and the one prior to that is: GSNMethod class >> _noopReturnTos The subequent stack list appears fine, evaluating the callback block, etc. In another database that breaks, WACallback >> evaluateWithFieldValues: is not on the stack. WACallbackRegistry >> handle: is directly preceded by GSNMethod class >> _noopReturnTos. This causes the method GRGemStonePlatform >> callbackMarker which searches for the WACallback frame on the stack to return nil, which means that call: or answer: breaks with 'You can only #call: and #answer: from within a callback or a Task.'. We are in a callback phase and we know that WACallback >> evaluateWithFieldValues: is called, but somehow it is not on the stack. It may be a compiler optimisation or something like that. In that case, the algorithm in #callbackMarker cannot reliably work, unless there's a way to force a class or method to be on the stack if it is called. Thanks Otto & Iwan _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Otto, While I refresh my continuation skilz:), could you send me some stacks (don't need args)? Dale On Mon, May 19, 2014 at 7:02 AM, Otto Behrens <[hidden email]> wrote: Hi, _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Hi,
Thanks for the response. I'll send you some stacks shortly. Pieter just reminded me that he encountered the same thing. An unrelated code change made the problem not reproducable. The subject of the message that he posted to this list was: "Spurious 'You can only #call: and #answer: from within a callback or a Task.'?". I tried various things now and got some strange behaviour. I modified GRGemStonePlatform >> callbackMarker to search for WACallbackRegistry >> handle: then found that this disappears off the stack! So no matter what I search for in the method, the stack seem to "hide" it. Does not make sense at all, right? Here's my change: callbackMarker ... whileTrue: [ (((aFrame at: 10) isKindOf: WACallbackRegistry and: [ (aFrame at: 1) selector == #handle: ]) or: [ (aFrame at: 1) == visitTaskMethod ]) ifTrue: [ ^aFrame at: 1 ]. ... This does not work as WACallbackRegistry >> handle: is replaced with a _noopReturnTos. Anyhow, I'm going to produce some stacks and send them. Thanks for the help On Mon, May 19, 2014 at 4:31 PM, Dale Henrichs <[hidden email]> wrote: > Otto, > > While I refresh my continuation skilz:), could you send me some stacks > (don't need args)? > > I'd like to see the full stack for the good callback and the full stack for > the bad callback ... I'm also interested in the seaside methods where the > callbacks are being created ... method source and an example call stack for > the method would help ... > > We're creating partial continuations, so it's probable that the bug is > introduced a callback creation time, so a picture of the stack at that time > will be useful .. at the end of the day, I will probably need to be able to > reproduce the problem so that I can get my hands on it in a c debugger... > > Dale > > > On Mon, May 19, 2014 at 7:02 AM, Otto Behrens <[hidden email]> wrote: >> >> Hi, >> >> We have a GemStone database (3.1.0.5) that apparently misbehaves in >> seaside callback processing. Has anyone encountered something like >> this? We'll appreciate the help we can get. >> >> We are processing callbacks as the following method is on the stack: >> >> WACallbackRegistry >> handle: aRequestContext >> >> The method calls evaluateWithFieldValues: on each callback: >> ... >> set sorted do: [ :callback | callback evaluateWithFieldValues: (fields >> allAt: callback key) ] >> ... >> >> In a database that behaves, the previous stack frame (n - 1) is >> >> WACallback >> evaluateWithFieldValues: >> >> and the one prior to that is: >> >> GSNMethod class >> _noopReturnTos >> >> The subequent stack list appears fine, evaluating the callback block, etc. >> >> In another database that breaks, >> >> WACallback >> evaluateWithFieldValues: >> >> is not on the stack. WACallbackRegistry >> handle: is directly >> preceded by GSNMethod class >> _noopReturnTos. This causes the method >> >> GRGemStonePlatform >> callbackMarker >> >> which searches for the WACallback frame on the stack to return nil, >> which means that call: or answer: breaks with 'You can only #call: and >> #answer: from within a callback or a Task.'. We are in a callback >> phase and we know that WACallback >> evaluateWithFieldValues: is >> called, but somehow it is not on the stack. >> >> It may be a compiler optimisation or something like that. In that >> case, the algorithm in #callbackMarker cannot reliably work, unless >> there's a way to force a class or method to be on the stack if it is >> called. >> >> Thanks >> Otto & Iwan >> _______________________________________________ >> Glass mailing list >> [hidden email] >> http://lists.gemtalksystems.com/mailman/listinfo/glass > > Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by Dale Henrichs-3
Otto, Could you run the WACallbackTest tests in both data bases? There are test cases that involve WACallback >> evaluateWithFieldValues in a couple of different scenarios, so it would be good to know that the tests are passing ...On Mon, May 19, 2014 at 7:31 AM, Dale Henrichs <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by Dale Henrichs-3
I attach the full working and broken stacks.
I also cut some stuff out and commented in both (the _snipped_ versions). On Mon, May 19, 2014 at 4:31 PM, Dale Henrichs <[hidden email]> wrote: > Otto, > > While I refresh my continuation skilz:), could you send me some stacks > (don't need args)? > > I'd like to see the full stack for the good callback and the full stack for > the bad callback ... I'm also interested in the seaside methods where the > callbacks are being created ... method source and an example call stack for > the method would help ... > > We're creating partial continuations, so it's probable that the bug is > introduced a callback creation time, so a picture of the stack at that time > will be useful .. at the end of the day, I will probably need to be able to > reproduce the problem so that I can get my hands on it in a c debugger... > > Dale > > > On Mon, May 19, 2014 at 7:02 AM, Otto Behrens <[hidden email]> wrote: >> >> Hi, >> >> We have a GemStone database (3.1.0.5) that apparently misbehaves in >> seaside callback processing. Has anyone encountered something like >> this? We'll appreciate the help we can get. >> >> We are processing callbacks as the following method is on the stack: >> >> WACallbackRegistry >> handle: aRequestContext >> >> The method calls evaluateWithFieldValues: on each callback: >> ... >> set sorted do: [ :callback | callback evaluateWithFieldValues: (fields >> allAt: callback key) ] >> ... >> >> In a database that behaves, the previous stack frame (n - 1) is >> >> WACallback >> evaluateWithFieldValues: >> >> and the one prior to that is: >> >> GSNMethod class >> _noopReturnTos >> >> The subequent stack list appears fine, evaluating the callback block, etc. >> >> In another database that breaks, >> >> WACallback >> evaluateWithFieldValues: >> >> is not on the stack. WACallbackRegistry >> handle: is directly >> preceded by GSNMethod class >> _noopReturnTos. This causes the method >> >> GRGemStonePlatform >> callbackMarker >> >> which searches for the WACallback frame on the stack to return nil, >> which means that call: or answer: breaks with 'You can only #call: and >> #answer: from within a callback or a Task.'. We are in a callback >> phase and we know that WACallback >> evaluateWithFieldValues: is >> called, but somehow it is not on the stack. >> >> It may be a compiler optimisation or something like that. In that >> case, the algorithm in #callbackMarker cannot reliably work, unless >> there's a way to force a class or method to be on the stack if it is >> called. >> >> Thanks >> Otto & Iwan >> _______________________________________________ >> Glass mailing list >> [hidden email] >> http://lists.gemtalksystems.com/mailman/listinfo/glass > > _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass working_stack.txt (44K) Download Attachment broken_stack.txt (43K) Download Attachment working_snipped_stack.txt (3K) Download Attachment broken_snipped_stack.txt (2K) Download Attachment |
In reply to this post by Dale Henrichs-3
both runs fine it seems:
run WACallbackTest suite run printString % 12 run, 12 passes, 0 expected defects, 0 failures, 0 errors, 0 unexpected passes On Mon, May 19, 2014 at 4:56 PM, Dale Henrichs <[hidden email]> wrote: > Otto, > > Could you run the WACallbackTest tests in both data bases? There are test > cases that involve WACallback >> evaluateWithFieldValues in a couple of > different scenarios, so it would be good to know that the tests are passing > ... > > Dale > > > On Mon, May 19, 2014 at 7:31 AM, Dale Henrichs > <[hidden email]> wrote: >> >> Otto, >> >> While I refresh my continuation skilz:), could you send me some stacks >> (don't need args)? >> >> I'd like to see the full stack for the good callback and the full stack >> for the bad callback ... I'm also interested in the seaside methods where >> the callbacks are being created ... method source and an example call stack >> for the method would help ... >> >> We're creating partial continuations, so it's probable that the bug is >> introduced a callback creation time, so a picture of the stack at that time >> will be useful .. at the end of the day, I will probably need to be able to >> reproduce the problem so that I can get my hands on it in a c debugger... >> >> Dale >> >> >> On Mon, May 19, 2014 at 7:02 AM, Otto Behrens <[hidden email]> wrote: >>> >>> Hi, >>> >>> We have a GemStone database (3.1.0.5) that apparently misbehaves in >>> seaside callback processing. Has anyone encountered something like >>> this? We'll appreciate the help we can get. >>> >>> We are processing callbacks as the following method is on the stack: >>> >>> WACallbackRegistry >> handle: aRequestContext >>> >>> The method calls evaluateWithFieldValues: on each callback: >>> ... >>> set sorted do: [ :callback | callback evaluateWithFieldValues: (fields >>> allAt: callback key) ] >>> ... >>> >>> In a database that behaves, the previous stack frame (n - 1) is >>> >>> WACallback >> evaluateWithFieldValues: >>> >>> and the one prior to that is: >>> >>> GSNMethod class >> _noopReturnTos >>> >>> The subequent stack list appears fine, evaluating the callback block, >>> etc. >>> >>> In another database that breaks, >>> >>> WACallback >> evaluateWithFieldValues: >>> >>> is not on the stack. WACallbackRegistry >> handle: is directly >>> preceded by GSNMethod class >> _noopReturnTos. This causes the method >>> >>> GRGemStonePlatform >> callbackMarker >>> >>> which searches for the WACallback frame on the stack to return nil, >>> which means that call: or answer: breaks with 'You can only #call: and >>> #answer: from within a callback or a Task.'. We are in a callback >>> phase and we know that WACallback >> evaluateWithFieldValues: is >>> called, but somehow it is not on the stack. >>> >>> It may be a compiler optimisation or something like that. In that >>> case, the algorithm in #callbackMarker cannot reliably work, unless >>> there's a way to force a class or method to be on the stack if it is >>> called. >>> >>> Thanks >>> Otto & Iwan >>> _______________________________________________ >>> Glass mailing list >>> [hidden email] >>> http://lists.gemtalksystems.com/mailman/listinfo/glass >> >> > Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by Dale Henrichs-3
Otto, In Pieter's example, I would be interested to see the source code to the addFrom: messages .. presumably there is a difference between the two methods ... and at this point in time the differences are interesting ... Dale On Mon, May 19, 2014 at 7:56 AM, Dale Henrichs <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by otto
Otto, In the broken case, it appears that you _are_ in the do loop that calls evaluateWithFieldValues: (frame 66). The corresponding frame in the working case is frame 54 ... On Mon, May 19, 2014 at 8:19 AM, Otto Behrens <[hidden email]> wrote: I attach the full working and broken stacks. _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by Dale Henrichs-3
I know the stack I'm working on better, so easier for me to give you bits on this one. Here's what you may be interested in: Investment >> matchComponent: aComponent [
self isMatched ifFalse: [ aComponent call:
(MatchInvestmentPage new instruction: self; yourself).
self addBuysForEditing. aComponent reset ] ] on: ValidateError
do: [ :err | aComponent inform: err messageText. aComponent answer ]
This is where the callback block is. FinePrintFormDecoration >> printButton: each on: html | label |
label := self labelForSelector: each key. ^ html submitButton accessKey: label first;
style: self buttonStyle; value: (self component labelForSelector: each key); callback: [ self performAction: each key selector: each value asSymbol ];
text: label; yourself and this horrible method is performed in the callback block:
matchBankEntryCallbackForComponent: aComponent | selectedPaymentMethod | selectedPaymentMethod := (aComponent childAt: aComponent memento model descriptionPaymentMethod) component memento
cache at: self bankTransfer descriptionPaymentMethod. (self isNew and: [ self bankTransfer isDebitOrderAccountVisibleForType: selectedPaymentMethod ])
ifTrue: [ aComponent showMessage: 'Cannot match an investment with this method of payment' ] ifFalse: [ self saveComponent: aComponent ifValidDo: [ self matchComponent: aComponent ] ]
On Mon, May 19, 2014 at 5:24 PM, Dale Henrichs <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Which code is for the working case and which code si for the broken case ... do they differ greatly? Dale On Mon, May 19, 2014 at 8:45 AM, Otto Behrens <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by Dale Henrichs-3
> In the broken case, it appears that you _are_ in the do loop that calls
> evaluateWithFieldValues: (frame 66). The corresponding frame in the working > case is frame 54 ... Ok, can see that > It looks like the index of do loop is 2, so that implies that the either a) > the first callback was "corrupt" or b) the second callback was created > incorrectly ... I can't tell, will have to dig more > I would like to be able to see what the stack looked like when the second > callback was created ... Looking at the method source for the methods > involved in rendering the component would be a good place to start, since > there is likely something funky there... Ok, but that is not simple. There's some ajax involved and yes, funkiness there. It would be nice if I can show you... _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by Dale Henrichs-3
Hmmm, Is the input data identical as well?On Mon, May 19, 2014 at 8:49 AM, Otto Behrens <[hidden email]> wrote: There is no difference in the code, same version was loaded _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
> Is the input data identical as well?
No, they are different databases. One is a test environment that the client worked on, backed up and restored (broken one). The other is a test db built locally from scratch, one (passing) test run that simulates the scenario. _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
In reply to this post by otto
... I'll have to read the c code that creates the partial continuations, but IIRC we have to account for all of the frames on the stack that need to be copied for the partial continuation and it seems that in this case we have an off-by-one-error ... so nested blocks and temp arg references could lead to different stack configurations ... perhaps capturing the stack at the point the continue is created will give us clues ...On Mon, May 19, 2014 at 8:52 AM, Otto Behrens <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
> perhaps capturing the stack at the point the continue is created will give
> us clues ... Attached are some stacks that I hacked in by calling the following method where we create them: WAPartialContinuation >> printStack | stream | stream := GsFile openWriteOnServer: '/tmp/stack_', self asOop printString. [ stream nextPutAll: partial printString ] ensure: [ stream close ] It does not tell me much at the moment. But perhaps you can see something. Or perhaps you have a better printing method that I can call? Thanks Otto _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass stack_188947713 (952 bytes) Download Attachment stack_191521537 (590 bytes) Download Attachment stack_193135105 (516 bytes) Download Attachment |
Otto, Thanks! I'm finally in the office ) and will spend some time today getting myself grounded in continuations again ... then I should have a better idea how to proceed ...On Mon, May 19, 2014 at 9:47 AM, Otto Behrens <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Thank you, Dale. I'm finally at home :)
On Monday, May 19, 2014, Dale Henrichs <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Otto, send @34379893 sourceStringGiven an instance of WACallback, you can determine the source code of the method where the callback is defined by looking at the `block` instance variable og a WACallBack instance ... then in 3.1: block _method sourceString. "source" block _method inClass "class" block _method _lineDeltaForBlock "line number in source (ignoring selector)" This can be done from a debugger (topaz) when error occurs ... navigate up the stack to the WACallback>>evaluateWithFieldValues: frame... get the oop of the _method (use `display oops`) and then sued the `send` command to send the three different messages: Dale On Mon, May 19, 2014 at 10:55 AM, Otto Behrens <[hidden email]> wrote: Thank you, Dale. I'm finally at home :) _______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Otto, I haven't been able to reproduce the bad error yet and I think that the corruption is being caused by the previous callback in the set ... the stack is corrupt at the point you try to create the continuation for the inform: in the validation block ... On Mon, May 19, 2014 at 2:48 PM, Dale Henrichs <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Otto, Another possibility ... although I don't know if this kind of thing would be possible but here goes nothing ...Dale On Mon, May 19, 2014 at 5:41 PM, Dale Henrichs <[hidden email]> wrote:
_______________________________________________ Glass mailing list [hidden email] http://lists.gemtalksystems.com/mailman/listinfo/glass |
Free forum by Nabble | Edit this page |