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