How to debug code using DynamicVariable?
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process? thanks, Norbert
Your analysis is correct: DynamicVariables are hard to impossible to debug, the debugger always runs in another process. I don't think there is a solution here (maybe let the debugger process copy/share the binding ?) apart from what you suggest: make sure you enter the debugger after the lookup and assignment of the value to a local variable. server := ZnCurrentServer value. Still, I find DynamicVariables very useful, especially architecture/design-wise. On 23 Jun 2014, at 13:50, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
Am 23.06.2014 um 14:03 schrieb Sven Van Caekenberghe <sven@stfx.eu>:
Your analysis is correct: DynamicVariables are hard to impossible to debug, the debugger always runs in another process. I don't think there is a solution here (maybe let the debugger process copy/share the binding ?) apart from what you suggest: make sure you enter the debugger after the lookup and assignment of the value to a local variable.
server := ZnCurrentServer value.
Still, I find DynamicVariables very useful, especially architecture/design-wise.
Agreed, I find context sensitive programming important because I don't like global state and you can solve this particular problem very easy. But I like the exception based dynamic variable much more. There the dynamic value is stored in a MethodContext which is a proper place for it. A process being only a runtime decorator for a stack is asking for trouble. Everything that copies/references the stack is suspect to produce errors. Of course the process variables are a lot faster. Don't know if a hybrid solution could work here. Norbert
On 23 Jun 2014, at 13:50, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
Norbert, I share the same feelings you have. And couldn't find any other way of dealing with them, other than doing the same thing Sven suggests. Regards! Esteban A. Maringolo 2014-06-23 9:03 GMT-03:00 Sven Van Caekenberghe <sven@stfx.eu>:
Your analysis is correct: DynamicVariables are hard to impossible to debug, the debugger always runs in another process. I don't think there is a solution here (maybe let the debugger process copy/share the binding ?) apart from what you suggest: make sure you enter the debugger after the lookup and assignment of the value to a local variable.
server := ZnCurrentServer value.
Still, I find DynamicVariables very useful, especially architecture/design-wise.
On 23 Jun 2014, at 13:50, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
Hi Norbert, it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap. The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged: *Process methods for accessing* *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self] then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g. *ProcessorScheduler methods for process state change* *terminateActive* "Terminate the process that is currently running." activeProcess effectiveProcess terminate and the debugging methods use evaluate:onBehalfOf: to install the process being debugged: *Process methods for private* *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess] *Process methods for changing suspended state* *step* ^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self *stepToCallee* "Step until top context changes" Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext etc. Changes from a Qwaq image attached. HTH On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
oops. I guess I hsould add those changes ;-) On Mon, Jun 23, 2014 at 9:58 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Hi Norbert,
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
*Process methods for accessing* *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
*ProcessorScheduler methods for process state change* *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
*Process methods for private* *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
*Process methods for changing suspended state* *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
Hi Norbert, [ let me try again. never try and get code out too early in the morning ;-) ] it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap. The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged: *Process methods for accessing* *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self] then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g. *ProcessorScheduler methods for process state change* *terminateActive* "Terminate the process that is currently running." activeProcess effectiveProcess terminate and the debugging methods use evaluate:onBehalfOf: to install the process being debugged: *Process methods for private* *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess] *Process methods for changing suspended state* *step* ^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self *stepToCallee* "Step until top context changes" Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext etc. Changes from a Qwaq image attached. HTH On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
and here are the changes I've just committed to Squeak trunk. On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
*Process methods for accessing* *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
*ProcessorScheduler methods for process state change* *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
*Process methods for private* *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
*Process methods for changing suspended state* *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
Thanks Eliot. Sven, Norbert if you package that nicely (BTW having some tests would be great) we can include that in 4.0 Stef On 23/6/14 19:29, Eliot Miranda wrote:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com <mailto:eliot.miranda@gmail.com>> wrote:
Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
/Process methods for accessing/ *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
/ProcessorScheduler methods for process state change/ *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
/Process methods for private/ *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
/Process methods for changing suspended state/ *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name <mailto:norbert@hartl.name>> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
https://pharo.fogbugz.com/default.asp?13378 Btw. I tested this as well in 3.0 and a backport would be highly appreciated. Norbert Am 23.06.2014 um 20:08 schrieb stepharo <stepharo@free.fr>:
Thanks Eliot. Sven, Norbert if you package that nicely (BTW having some tests would be great) we can include that in 4.0
Stef On 23/6/14 19:29, Eliot Miranda wrote:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote: Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
Process methods for accessing effectiveProcess "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
ProcessorScheduler methods for process state change terminateActive "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
Process methods for private evaluate: aBlock onBehalfOf: aProcess "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
Process methods for changing suspended state step
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
stepToCallee "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote: In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
The slice cannot be integrated automatically because there is a modal popping up Warning: Process should not be redefined. Proceed to store over it. Not sure what to do. Manual integration? Norbert Am 23.06.2014 um 23:55 schrieb Norbert Hartl <norbert@hartl.name>:
https://pharo.fogbugz.com/default.asp?13378
Btw. I tested this as well in 3.0 and a backport would be highly appreciated.
Norbert
Am 23.06.2014 um 20:08 schrieb stepharo <stepharo@free.fr>:
Thanks Eliot. Sven, Norbert if you package that nicely (BTW having some tests would be great) we can include that in 4.0
Stef On 23/6/14 19:29, Eliot Miranda wrote:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote: Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
Process methods for accessing effectiveProcess "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
ProcessorScheduler methods for process state change terminateActive "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
Process methods for private evaluate: aBlock onBehalfOf: aProcess "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
Process methods for changing suspended state step
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
stepToCallee "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote: In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
On Mon, Jun 23, 2014 at 3:04 PM, Norbert Hartl <norbert@hartl.name> wrote:
The slice cannot be integrated automatically because there is a modal popping up
Warning: Process should not be redefined. Proceed to store over it.
Not sure what to do. Manual integration?
Can you not wrap that in "[] valueSupplyingAnswer: true" ?
Norbert
Am 23.06.2014 um 23:55 schrieb Norbert Hartl <norbert@hartl.name>:
https://pharo.fogbugz.com/default.asp?13378
Btw. I tested this as well in 3.0 and a backport would be highly appreciated.
Norbert
Am 23.06.2014 um 20:08 schrieb stepharo <stepharo@free.fr>:
Thanks Eliot. Sven, Norbert if you package that nicely (BTW having some tests would be great) we can include that in 4.0
Stef On 23/6/14 19:29, Eliot Miranda wrote:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
*Process methods for accessing* *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
*ProcessorScheduler methods for process state change* *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
*Process methods for private* *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
*Process methods for changing suspended state* *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
-- best, Eliot
Am 24.06.2014 um 00:27 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
On Mon, Jun 23, 2014 at 3:04 PM, Norbert Hartl <norbert@hartl.name> wrote: The slice cannot be integrated automatically because there is a modal popping up
Warning: Process should not be redefined. Proceed to store over it.
Not sure what to do. Manual integration?
Can you not wrap that in "[] valueSupplyingAnswer: true" ?
Sure. But I can only provide the monticello package and this code needs to go into the build process. Right? I just wanted to say it early. I think the guys know how to treat it. If there is anything I can do....
Norbert
Norbert
Am 23.06.2014 um 23:55 schrieb Norbert Hartl <norbert@hartl.name>:
https://pharo.fogbugz.com/default.asp?13378
Btw. I tested this as well in 3.0 and a backport would be highly appreciated.
Norbert
Am 23.06.2014 um 20:08 schrieb stepharo <stepharo@free.fr>:
Thanks Eliot. Sven, Norbert if you package that nicely (BTW having some tests would be great) we can include that in 4.0
Stef
On 23/6/14 19:29, Eliot Miranda wrote: and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote: Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
Process methods for accessing effectiveProcess "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
ProcessorScheduler methods for process state change terminateActive "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
Process methods for private evaluate: aBlock onBehalfOf: aProcess "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
Process methods for changing suspended state step
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
stepToCallee "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
-- best, Eliot
The slice cannot be integrated automatically because there is a modal popping up
Warning: Process should not be redefined. Proceed to store over it.
Not sure what to do. Manual integration?
We will check that :)
Norbert
Am 23.06.2014 um 23:55 schrieb Norbert Hartl <norbert@hartl.name <mailto:norbert@hartl.name>>:
https://pharo.fogbugz.com/default.asp?13378
Btw. I tested this as well in 3.0 and a backport would be highly appreciated.
Norbert
Am 23.06.2014 um 20:08 schrieb stepharo <stepharo@free.fr <mailto:stepharo@free.fr>>:
Thanks Eliot. Sven, Norbert if you package that nicely (BTW having some tests would be great) we can include that in 4.0
Stef On 23/6/14 19:29, Eliot Miranda wrote:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com <mailto:eliot.miranda@gmail.com>> wrote:
Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
/Process methods for accessing/ *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
/ProcessorScheduler methods for process state change/ *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
/Process methods for private/ *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
/Process methods for changing suspended state/ *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name <mailto:norbert@hartl.name>> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
On 24/6/14 08:19, stepharo wrote:
The slice cannot be integrated automatically because there is a modal popping up
Warning: Process should not be redefined. Proceed to store over it.
Not sure what to do. Manual integration?
We will check that :)
Norbert
Am 23.06.2014 um 23:55 schrieb Norbert Hartl <norbert@hartl.name <mailto:norbert@hartl.name>>:
https://pharo.fogbugz.com/default.asp?13378
Btw. I tested this as well in 3.0 and a backport would be highly appreciated.
Norbert
Am 23.06.2014 um 20:08 schrieb stepharo <stepharo@free.fr <mailto:stepharo@free.fr>>:
Thanks Eliot. Sven, Norbert if you package that nicely (BTW having some tests would be great) we can include that in 4.0
Stef On 23/6/14 19:29, Eliot Miranda wrote:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com <mailto:eliot.miranda@gmail.com>> wrote:
Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
/Process methods for accessing/ *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
/ProcessorScheduler methods for process state change/ *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
/Process methods for private/ *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
/Process methods for changing suspended state/ *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name <mailto:norbert@hartl.name>> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
Am 24.06.2014 um 08:19 schrieb stepharo <stepharo@free.fr>:
The slice cannot be integrated automatically because there is a modal popping up
Warning: Process should not be redefined. Proceed to store over it.
Not sure what to do. Manual integration?
We will check that :)
Marcus already integrated it. Thanks! norbert
Norbert
Am 23.06.2014 um 23:55 schrieb Norbert Hartl <norbert@hartl.name>:
https://pharo.fogbugz.com/default.asp?13378
Btw. I tested this as well in 3.0 and a backport would be highly appreciated.
Norbert
Am 23.06.2014 um 20:08 schrieb stepharo <stepharo@free.fr>:
Thanks Eliot. Sven, Norbert if you package that nicely (BTW having some tests would be great) we can include that in 4.0
Stef On 23/6/14 19:29, Eliot Miranda wrote:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote: Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
Process methods for accessing effectiveProcess
"effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code
on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not
correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the
debugged process as the effectiveProcess of the process executing the code, preserving process
identity."
^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
ProcessorScheduler methods for process state change terminateActive
"Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
Process methods for private evaluate: aBlock onBehalfOf: aProcess
"Evaluate aBlock setting effectiveProcess to aProcess. Used
in the execution simulation machinery to ensure that
Processor activeProcess evaluates correctly when debugging."
| oldEffectiveProcess |
oldEffectiveProcess := effectiveProcess.
effectiveProcess := aProcess.
^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
Process methods for changing suspended state step
^Processor activeProcess
evaluate: [suspendedContext := suspendedContext step]
onBehalfOf: self
stepToCallee
"Step until top context changes"
Processor activeProcess
evaluate:
[| ctxt |
ctxt := suspendedContext.
[ctxt == suspendedContext] whileTrue: [
suspendedContext := suspendedContext step]]
onBehalfOf: self.
^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote: In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot
Hi Eliot, thank you very much. I imported your changes in a pharo 3 image and it works awesome. So I'm preparing a slice for pharo. Thanks again, a very annoying problem seems to be solved, Norbert Am 23.06.2014 um 19:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote: Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
Process methods for accessing effectiveProcess "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
ProcessorScheduler methods for process state change terminateActive "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
Process methods for private evaluate: aBlock onBehalfOf: aProcess "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
Process methods for changing suspended state step
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
stepToCallee "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote: In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot <trunk4.6EffectiveProcessMethods.st>
On Mon, Jun 23, 2014 at 12:05 PM, Norbert Hartl <norbert@hartl.name> wrote:
Hi Eliot,
thank you very much. I imported your changes in a pharo 3 image and it works awesome. So I'm preparing a slice for pharo.
Thanks again, a very annoying problem seems to be solved,
glad to hear it, and thanks for your prompting me as it's now in Squeak trunk too.
Norbert
Am 23.06.2014 um 19:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
*Process methods for accessing* *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
*ProcessorScheduler methods for process state change* *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
*Process methods for private* *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
*Process methods for changing suspended state* *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot <trunk4.6EffectiveProcessMethods.st>
-- best, Eliot
Hmmm, I'm trying to write a test for it and I wonder why testDynamicVariableAccessFromDifferentProcess | process sem1 result | sem1 := Semaphore new. process := [ TestDynamicVariable value: 123 during: [ sem1 wait ] ] fork. Processor activeProcess evaluate: [ result := TestDynamicVariable value ] onBehalfOf: process. sem1 signal. self assert: result = 123 does not work. The variable accessing is in DynamicVariable>>#value: anObject during: aBlock | p oldValue | p := Processor activeProcess. oldValue := (p psValueAt: index) ifNil: [ self default ]. ^ [ p psValueAt: index put: anObject. aBlock value ] ensure: [ p psValueAt: index put: oldValue ] Any ideas? Norbert Am 23.06.2014 um 21:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
On Mon, Jun 23, 2014 at 12:05 PM, Norbert Hartl <norbert@hartl.name> wrote: Hi Eliot,
thank you very much. I imported your changes in a pharo 3 image and it works awesome. So I'm preparing a slice for pharo.
Thanks again, a very annoying problem seems to be solved,
glad to hear it, and thanks for your prompting me as it's now in Squeak trunk too.
Norbert
Am 23.06.2014 um 19:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda<eliot.miranda@gmail.com> wrote: Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
Process methods for accessing effectiveProcess "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
ProcessorScheduler methods for process state change terminateActive "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
Process methods for private evaluate: aBlock onBehalfOf: aProcess "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
Process methods for changing suspended state step
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
stepToCallee "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name>wrote: In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot <trunk4.6EffectiveProcessMethods.st>
-- best, Eliot
2014-06-23 22:38 GMT+02:00 Norbert Hartl <norbert@hartl.name>:
Hmmm,
I'm trying to write a test for it and I wonder why
testDynamicVariableAccessFromDifferentProcess | process sem1 result | sem1 := Semaphore new. process := [ TestDynamicVariable value: 123 during: [ sem1 wait ] ] fork. Processor activeProcess evaluate: [ result := TestDynamicVariable value ] onBehalfOf: process. sem1 signal. self assert: result = 123
does not work. The variable accessing is in
DynamicVariable>>#value: anObject during: aBlock | p oldValue | p := Processor activeProcess. oldValue := (p psValueAt: index) ifNil: [ self default ]. ^ [ p psValueAt: index put: anObject. aBlock value ] ensure: [ p psValueAt: index put: oldValue ]
Any ideas?
But what happens when you immediately fork, are you sure the forked process immediately pre-empts the activeProcess? What if you introduce Processor activeProcess yield after the fork?
Norbert
Am 23.06.2014 um 21:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
On Mon, Jun 23, 2014 at 12:05 PM, Norbert Hartl <norbert@hartl.name> wrote:
Hi Eliot,
thank you very much. I imported your changes in a pharo 3 image and it works awesome. So I'm preparing a slice for pharo.
Thanks again, a very annoying problem seems to be solved,
glad to hear it, and thanks for your prompting me as it's now in Squeak trunk too.
Norbert
Am 23.06.2014 um 19:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda<eliot.miranda@gmail.com> wrote:
Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
*Process methods for accessing* *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
*ProcessorScheduler methods for process state change* *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
*Process methods for private* *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
*Process methods for changing suspended state* *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot <trunk4.6EffectiveProcessMethods.st <http://trunk4.6effectiveprocessmethods.st/>>
-- best, Eliot
2014-06-23 22:50 GMT+02:00 Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com>:
2014-06-23 22:38 GMT+02:00 Norbert Hartl <norbert@hartl.name>:
Hmmm,
I'm trying to write a test for it and I wonder why
testDynamicVariableAccessFromDifferentProcess | process sem1 result | sem1 := Semaphore new. process := [ TestDynamicVariable value: 123 during: [ sem1 wait ] ] fork. Processor activeProcess evaluate: [ result := TestDynamicVariable value ] onBehalfOf: process. sem1 signal. self assert: result = 123
does not work. The variable accessing is in
DynamicVariable>>#value: anObject during: aBlock | p oldValue | p := Processor activeProcess. oldValue := (p psValueAt: index) ifNil: [ self default ]. ^ [ p psValueAt: index put: anObject. aBlock value ] ensure: [ p psValueAt: index put: oldValue ]
Any ideas?
But what happens when you immediately fork, are you sure the forked process immediately pre-empts the activeProcess? What if you introduce Processor activeProcess yield after the fork?
Ah, I just tried, it's Processor yield. [Transcript cr; show: 'A' ] fork. Processor yield. Transcript cr; show: 'B' . produces the required transcripting order. Without yielding, B comes before A.
Norbert
Am 23.06.2014 um 21:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
On Mon, Jun 23, 2014 at 12:05 PM, Norbert Hartl <norbert@hartl.name> wrote:
Hi Eliot,
thank you very much. I imported your changes in a pharo 3 image and it works awesome. So I'm preparing a slice for pharo.
Thanks again, a very annoying problem seems to be solved,
glad to hear it, and thanks for your prompting me as it's now in Squeak trunk too.
Norbert
Am 23.06.2014 um 19:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda<eliot.miranda@gmail.com> wrote:
Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
*Process methods for accessing* *effectiveProcess* "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
*ProcessorScheduler methods for process state change* *terminateActive* "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
*Process methods for private* *evaluate: aBlock onBehalfOf: aProcess* "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
*Process methods for changing suspended state* *step*
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
*stepToCallee* "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name> wrote:
In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot <trunk4.6EffectiveProcessMethods.st <http://trunk4.6effectiveprocessmethods.st/>>
-- best, Eliot
Am 23.06.2014 um 23:20 schrieb Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>:
2014-06-23 22:50 GMT+02:00 Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>:
2014-06-23 22:38 GMT+02:00 Norbert Hartl <norbert@hartl.name>:
Hmmm,
I'm trying to write a test for it and I wonder why
testDynamicVariableAccessFromDifferentProcess | process sem1 result |
sem1 := Semaphore new. process := [ TestDynamicVariable value: 123 during: [ sem1 wait ] ] fork.
Processor activeProcess evaluate: [ result := TestDynamicVariable value ] onBehalfOf: process. sem1 signal. self assert: result = 123
does not work. The variable accessing is in
DynamicVariable>>#value: anObject during: aBlock | p oldValue | p := Processor activeProcess. oldValue := (p psValueAt: index) ifNil: [ self default ]. ^ [ p psValueAt: index put: anObject. aBlock value ] ensure: [ p psValueAt: index put: oldValue ]
Any ideas?
But what happens when you immediately fork, are you sure the forked process immediately pre-empts the activeProcess? What if you introduce Processor activeProcess yield after the fork?
Ah, I just tried, it's Processor yield.
[Transcript cr; show: 'A' ] fork. Processor yield. Transcript cr; show: 'B' .
produces the required transcripting order. Without yielding, B comes before A.
I knew it was something simple I forgot. Thank you very much, Norbert
Norbert
Am 23.06.2014 um 21:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
On Mon, Jun 23, 2014 at 12:05 PM, Norbert Hartl <norbert@hartl.name> wrote: Hi Eliot,
thank you very much. I imported your changes in a pharo 3 image and it works awesome. So I'm preparing a slice for pharo.
Thanks again, a very annoying problem seems to be solved,
glad to hear it, and thanks for your prompting me as it's now in Squeak trunk too.
Norbert
Am 23.06.2014 um 19:29 schrieb Eliot Miranda <eliot.miranda@gmail.com>:
and here are the changes I've just committed to Squeak trunk.
On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda<eliot.miranda@gmail.com> wrote: Hi Norbert,
[ let me try again. never try and get code out too early in the morning ;-) ]
it is the debugger that needs fixing, not your code !! :-). The debugger needs to respect process identity. Andreas and I (mostly Andreas) came up with the following changes at Qwaq. Your message is a good reminder that I need to add this to Squeak asap.
The idea is for Process to have an additional inst var 'effectiveProcess' that holds the actual process running code. For the most part this is self, but in the debugger we substitute the process being debugged:
Process methods for accessing effectiveProcess "effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code on behalf of processes, so unless some effort is made the identity of Processor activeProcess is not correctly maintained when debugging code. The debugger uses evaluate:onBehalfOf: to assign the debugged process as the effectiveProcess of the process executing the code, preserving process identity." ^effectiveProcess ifNil: [self]
then the relevant methods in Process and processorScheduler defer to effectiveProcess, e.g.
ProcessorScheduler methods for process state change terminateActive "Terminate the process that is currently running."
activeProcess effectiveProcess terminate
and the debugging methods use evaluate:onBehalfOf: to install the process being debugged:
Process methods for private evaluate: aBlock onBehalfOf: aProcess "Evaluate aBlock setting effectiveProcess to aProcess. Used in the execution simulation machinery to ensure that Processor activeProcess evaluates correctly when debugging." | oldEffectiveProcess | oldEffectiveProcess := effectiveProcess. effectiveProcess := aProcess. ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
Process methods for changing suspended state step
^Processor activeProcess evaluate: [suspendedContext := suspendedContext step] onBehalfOf: self
stepToCallee "Step until top context changes"
Processor activeProcess evaluate: [| ctxt | ctxt := suspendedContext. [ctxt == suspendedContext] whileTrue: [ suspendedContext := suspendedContext step]] onBehalfOf: self. ^suspendedContext
etc. Changes from a Qwaq image attached.
HTH
On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <norbert@hartl.name>wrote: In my code I'm using a DynamicVariable to request a context object when needed. Until now I knew the name DynamicVariable only from seaside. There it is called WADynamicVariable and it is an exception. So I blindly assumed the pharo DynamicVariable works the same. I thought this might be a good optimization not to travel the stack all the time but put in the process. Now that I am using it I can see the difference. I find it real hard using it because I don't know how to debug/step in code. DynamicVariable is a process specific variable but as soon as a debugger opens it is very likely to be in another process. This makes stepping in method using the DynamicVariable impossible. The only way round is to set break points after the dynamic lookup and step from there. But this feels just wrong. What would be the best way to have DynamicVariable and be able to debug anything? Or is there a variant that uses the stack instead of the "active" process?
thanks,
Norbert
-- best, Eliot
-- best, Eliot <trunk4.6EffectiveProcessMethods.st>
-- best, Eliot
participants (6)
-
Eliot Miranda -
Esteban A. Maringolo -
Nicolas Cellier -
Norbert Hartl -
stepharo -
Sven Van Caekenberghe