Forum: wxRuby Does stack get unwound when event returns without skip?

Posted by Ross Goodell (rossgoodell)
on 2010-05-06 01:27
I'm using a TextCtrl in an editor and in my evt_key_down, evt_key_up,
etc. handlers I've been avoiding using event.skip in order to get the
behavior I want, but it looks like that is making the stack grow.  Can
someone tell me if the stack gets unwound when an event handler finishes
without using skip?  And, if it doesn't, if there is another good way
get it unwound before exiting.

Any help would be appreciated.

Thanks,
Ross
Posted by Ross Goodell (rossgoodell)
on 2010-05-07 18:20
Ross Goodell wrote:
> I'm using a TextCtrl in an editor and in my evt_key_down, evt_key_up,
> etc. handlers I've been avoiding using event.skip in order to get the
> behavior I want, but it looks like that is making the stack grow.  Can
> someone tell me if the stack gets unwound when an event handler finishes
> without using skip?  And, if it doesn't, if there is another good way
> get it unwound before exiting.
> 
> Any help would be appreciated.
> 
> Thanks,
> Ross

Further experimentation has shown me that whatever the problem is, it 
has nothing to do with not using skip.

Ross
Posted by Alex Fenton (Guest)
on 2010-05-19 02:10
(Received via mailing list)
Hi Ross

On 06/05/2010 00:27, Ross Goodell wrote:
> I'm using a TextCtrl in an editor and in my evt_key_down, evt_key_up,
> etc. handlers I've been avoiding using event.skip in order to get the
> behavior I want, but it looks like that is making the stack grow.  Can
> someone tell me if the stack gets unwound when an event handler finishes
> without using skip?  And, if it doesn't, if there is another good way
> get it unwound before exiting.
>    

I'm not totally sure what you mean by "unwound" here. It sounds like
you're concerned that the Event object isn't getting released and
garbage collected, and so the total world of Ruby objects is growing and
consuming memory.

As your later post suggests, skip() shouldn't affect this - it just
signals whether the event should be passed on to other handlers for
processing. There is some special and careful handling of Events in the
wxRuby interface to C++, so if you've found a memory leak, I'd be really
grateful if you could provide a simple example which demonstrates.

thanks
alex
Posted by Ross Goodell (rossgoodell)
on 2010-05-19 03:12
Alex Fenton wrote:
> Hi Ross
> 
> On 06/05/2010 00:27, Ross Goodell wrote:
>> I'm using a TextCtrl in an editor and in my evt_key_down, evt_key_up,
>> etc. handlers I've been avoiding using event.skip in order to get the
>> behavior I want, but it looks like that is making the stack grow.  Can
>> someone tell me if the stack gets unwound when an event handler finishes
>> without using skip?  And, if it doesn't, if there is another good way
>> get it unwound before exiting.
>>    
> 
> I'm not totally sure what you mean by "unwound" here. It sounds like
> you're concerned that the Event object isn't getting released and
> garbage collected, and so the total world of Ruby objects is growing and
> consuming memory.
> 
> As your later post suggests, skip() shouldn't affect this - it just
> signals whether the event should be passed on to other handlers for
> processing. There is some special and careful handling of Events in the
> wxRuby interface to C++, so if you've found a memory leak, I'd be really
> grateful if you could provide a simple example which demonstrates.
> 
> thanks
> alex

Thanks Alex.  By not getting "unwound" I meant that the stack that was 
displayed when I gave the "w" command in the Ruby debugger continued to 
show entries for methods called by an exception handler, e.g. rescue 
NameError => noMethodErrorObj during the processing for an event handler 
such as evt_key_up, after the exception handler had completed.  (Also by 
using the "up" command in the Ruby debugger I found that the old stacked 
local variables really were still available.)

Further experiments since I made that last post suggested to me that at 
least much of it was caused by my using logic in Ruby rescue clauses to 
complete the processing and assuming that the subsequent return from the 
method would "unwind" the stack in the same way as a normal method 
return.  Some experimentation seemed to indicate that I need to use 
retry if I want to get the stack "unwound" normally.  I'm now in the 
process of making that change everywhere I need to and seeing if that 
solves my problem.

My hypothesis in this is that rescue must be intended only for logic 
that will terminate the program unless retry is given.  If that's wrong 
and there is a problem in wxRuby, I will certainly get a simple example 
together and pass it on to you.  However, I'm about to go on vacation, 
so it may be a few weeks before I get it done.

Thanks very much for your response,
Ross
Posted by Alex Fenton (Guest)
on 2010-05-19 13:29
(Received via mailing list)
On 19/05/2010 02:12, Ross Goodell wrote:
> Thanks Alex.  By not getting "unwound" I meant that the stack that was
> displayed when I gave the "w" command in the Ruby debugger continued to
> show entries for methods called by an exception handler, e.g. rescue
> NameError =>  noMethodErrorObj during the processing for an event handler
> such as evt_key_up, after the exception handler had completed.  (Also by
> using the "up" command in the Ruby debugger I found that the old stacked
> local variables really were still available.)
>    

That's interesting to know. From debugging on the C++ side, how I think
it should look is that a wxRuby app is constantly within a main_loop
method. Within that it's sequentially in a series of event handlers,
which are called Procs. So perhaps if the next event hasn't started, the
old stack context is still there, even if practically it's finished.

> Further experiments since I made that last post suggested to me that at
> least much of it was caused by my using logic in Ruby rescue clauses to
> complete the processing and assuming that the subsequent return from the
> method would "unwind" the stack in the same way as a normal method
> return.  Some experimentation seemed to indicate that I need to use
> retry if I want to get the stack "unwound" normally.  I'm now in the
> process of making that change everywhere I need to and seeing if that
> solves my problem.
>    

What's the problem that it's causing for your app? I would limit using
rescue/retry to genuine Ruby exception conditions; there should be a
more straightforward way to do it if it's ordinary event processing. PS
- I expect you've already noted this, but never hold a reference to a
Wx::Event object (eg in an @instance_variable). wxRuby is likely to
delete the object from under you causing crashes or other problems.

> My hypothesis in this is that rescue must be intended only for logic
> that will terminate the program unless retry is given.  If that's wrong
> and there is a problem in wxRuby, I will certainly get a simple example
> together and pass it on to you.  However, I'm about to go on vacation,
> so it may be a few weeks before I get it done.
>    

Rescue should work as in "normal" ruby; it's just that all the code
running in a GUI app is the event handling code, with the main_loop as
the root context of the stack.

Hope you have a good holiday, please get in touch if further questions
come up.

a
Posted by Ross Goodell (rossgoodell)
on 2010-08-27 02:27
Alex,

I apologize for being so late in responding.  I’d intended to come up 
with a small example of the problem, but it turned out to be more 
difficult than I’d expected.  Then vacation and other activities wiped 
out most of about 7 weeks.

I eventually was able to reduce the stack build-up significantly, by 
avoiding passing the Wx::Event objects and other clean-ups.  I also 
moved my working logic out of all the rescue blocks.  I understand that 
shouldn’t make a difference.  I had the impression that it did reduce 
the stack build-up, but I could very well be mistaken.  Perhaps your 
conjecture--that if the next event hasn't started, the old stack context 
is still there--is correct.

I did not eliminate all of my use of exception handling for non-terminal 
errors.  I use exception handling to improve the program’s performance 
when checking for those problems ahead of time in my program when I 
believe that it would be a significant performance hit.

I was never able to reproduce any of the remaining stack build-up 
problems in my simplified example, so I still don’t know what is going 
on.  The stack build-up is slow enough that I’ve never been aware of it 
interfering with my program’s behavior.

Thanks again for all your help.

My regards,
Ross


Alex Fenton wrote:
> On 19/05/2010 02:12, Ross Goodell wrote:
>> Thanks Alex.  By not getting "unwound" I meant that the stack that was
>> displayed when I gave the "w" command in the Ruby debugger continued to
>> show entries for methods called by an exception handler, e.g. rescue
>> NameError =>  noMethodErrorObj during the processing for an event handler
>> such as evt_key_up, after the exception handler had completed.  (Also by
>> using the "up" command in the Ruby debugger I found that the old stacked
>> local variables really were still available.)
>>    
> 
> That's interesting to know. From debugging on the C++ side, how I think
> it should look is that a wxRuby app is constantly within a main_loop
> method. Within that it's sequentially in a series of event handlers,
> which are called Procs. So perhaps if the next event hasn't started, the
> old stack context is still there, even if practically it's finished.
> 
>> Further experiments since I made that last post suggested to me that at
>> least much of it was caused by my using logic in Ruby rescue clauses to
>> complete the processing and assuming that the subsequent return from the
>> method would "unwind" the stack in the same way as a normal method
>> return.  Some experimentation seemed to indicate that I need to use
>> retry if I want to get the stack "unwound" normally.  I'm now in the
>> process of making that change everywhere I need to and seeing if that
>> solves my problem.
>>    
> 
> What's the problem that it's causing for your app? I would limit using
> rescue/retry to genuine Ruby exception conditions; there should be a
> more straightforward way to do it if it's ordinary event processing. PS
> - I expect you've already noted this, but never hold a reference to a
> Wx::Event object (eg in an @instance_variable). wxRuby is likely to
> delete the object from under you causing crashes or other problems.
> 
>> My hypothesis in this is that rescue must be intended only for logic
>> that will terminate the program unless retry is given.  If that's wrong
>> and there is a problem in wxRuby, I will certainly get a simple example
>> together and pass it on to you.  However, I'm about to go on vacation,
>> so it may be a few weeks before I get it done.
>>    
> 
> Rescue should work as in "normal" ruby; it's just that all the code
> running in a GUI app is the event handling code, with the main_loop as
> the root context of the stack.
> 
> Hope you have a good holiday, please get in touch if further questions
> come up.
> 
> a
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.