Does stack get unwound when event returns without skip?

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

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

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

Alex F. 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

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

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 F. 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