Quoting Bert Wesarg <[EMAIL PROTECTED]>:
> This is my proposal for fixing several issues with the handling of compiled
> macro programs.
>
> The first is a memory leak in source/macro.c::readCheckMacroString(), if we
> the caller wants to parse only the macro, i.e. passing runWindow == NULL.
> This was reported as SF BUG#2078867.
Still haven't tried this out.
> The second is more subtile: if a macro function definition overwrites a
> previously one we unconditionaly free the old program. But this old
> program
> is may be currently in use. To solve this I have introduced a reference
> count
> for the program and FreeProgram() really releases the program only if this
> drops to zero. To track references to the program it is needed to put the
> program pointer into the stack frame and increment the reference count.
>
> There are currently 3 places were we build up a stacke frame, each needs
> different handling of the program pointer:
>
> 1) ExecuteMacro():
> The caller is already responsible for freeing the prog (its runMacro()).
> Therefore we put a NULL pointer for the prog into the frame.
>
> 2) RunMacroAsSubrCall():
> Here the caller passes the reference count to this function, so we don't
> need to increment the reference.
> The callers are runMacro() and readCheckMacroString().
>
> 3) callSubroutine():
> This is the usual usage: increment the reference and put it into the
> stack
> frame.
Your patch ups the refcount on function call and lowers it on return. A
great improvement. However, you don't deal with a macro crash. This should
do the lowering (FreeMacro()) for every frame still in the stack before
freeing it.
BTW did you try my macro-bug-location tracker yet? I've implemented a
built-in array variable called $failure containing the last crash's error
message, its invoking window (document), focus window, current function,
where this is defined (menu entry/macro file) and textual position of the
offending statement. Another new built-in, edit_macro(), allows you to open
a macro menu definition and position the cursor in its text. (You can use
existing functions to open a macro file.) This means you can write a macro
which will take you to the offending code directly!
For example, the macro:
dialog(2 + 1 / 0)
crashes with division by zero. $failure gives text positions 11 to 16 (with
'd' at position 0), so you highlight the operator and arguments causing the
crash as follows:
err = $failure
if (err.menu != "") {
edit_macro(err.menu, err.menu_item, err.start, err.end)
dialog("Error calling " err.menu " entry " err.menu_item "\n" \
"from window " err.called_from "\n" \
"Error was:\n" err.error)
}
(The above doesn't check $failure for valid content; so if you run it before
any failure occurs, it'll fail. Run it a second time and it'll identify the
problem as the array key ".menu" in the second line.)
Step one of built-in macro debugging now works...
The "whole works" tarball is here:
http://ajbj.free.fr/nedit/neditHome/neditHome-2008-09-19.tar.gz
You'll see that parse.y has a whole load of extra stuff to support position
tracking. If you have a moment, give it a go.
Tony
--
NEdit Develop mailing list - [email protected]
http://www.nedit.org/mailman/listinfo/develop