On Fri, Sep 19, 2008 at 02:05, Tony Balinski <[EMAIL PROTECTED]> wrote:
> 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.
Yes I know this, just haven't mentioned it.
I think the right place to do this is FreeRestartData(). There we can unroll the
whole stack and drop references to macro programs.
>
> 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.)
Is this error handling code a separate macro? I.e. run any macro, if
an error accure you can run this error handling macro and see what
happens?
>
> 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.
Definitive!
BTW: How about a graphical debugger for the runtime interpreter. I
think the biggest problem is the widget, the internals shouldn't be a
problem. But it may also suffice to have a commandline debugger
interface.
Bye
Bert
>
> Tony
> --
> NEdit Develop mailing list - [email protected]
> http://www.nedit.org/mailman/listinfo/develop
>
--
NEdit Develop mailing list - [email protected]
http://www.nedit.org/mailman/listinfo/develop