[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Probably bug in function.c : func_eval()

From: Keith Huntington
Subject: Probably bug in function.c : func_eval()
Date: Tue, 12 Aug 2003 19:51:12 -0400

It's very possible that I'm mistaken ... but I believe 
that I have detected a bug in the 3.80 sources, file
function.c, function func_eval().

The new function func_eval() is passed a char *o,
which points to the current 'index' into the global
variable_output_buffer.  The char *o is also returned
to the caller, following the same pattern as the other
func_xxx functions.

The problem/bug is this:

  func_eval() makes a call to eval_buffer().

    eval_buffer() makes a call to eval().

     eval() makes calls to variable_buffer_output()

Now, so long as the variable_buffer has enough 'extra'
space reserved to service the expansion of the $(eval...)
string, then nothing bad happens.  However, if you happen to
need a bigger variable_buffer during the eval() routine,
then variable_buffer_output() will do a realloc()... and
this will typically move the location of variable_buffer
in memory.

And that makes the char *o pointer back in func_eval()
no longer valid.  And subsequent processing will do 
unexpected and/or disastrous things.

I found this situation myself when making use of the 
$(eval..) function -- I suddenly started getting some
mysterious 'virtual memory exhausted' errors.  In the
debugger, I saw that the reason was that the xrealloc()
call was asking for FFFF9xxx bytes of memory!  Tracing
backwards, I found the reason for the 'big' number was 
that in the function variable_buffer_output (ptr, string, length), 
the 'ptr' variable was LESS THAN the variable_buffer ptr,
resulting in a negative number.  And this was because
the variable_buffer ptr had been previosly realloced/moved,
without func_eval() having any way of knowing about it.

I suspect the long-term fix might be a bit ugly, because
it will require some way to pass the results of a realloc()
back from eval() to eval_buffer() to func_eval()... and I
don't have that solution.

What I did do as a temporary kluge in my own local sources
was to PRE-allocate an extra 8KB of space, before letting
func_eval() make the call to eval_buffer().  My rationale
was that 8KB should be enough for anything I might need.
(Famous last words, there...)  So far this has resolved the 
problem for me... and should continue to do so as long as I
keep my $(eval...) templates under this self-imposed limit.

FYI, my kluge code is:

--- From file function.c --- snippet starts ----

static char *
func_eval (o, argv, funcname)
     char *o;
     char **argv;
     const char *funcname;

                        // kjh - bug-avoidance kluge for eval
                        //       PRE-allocate an additional 8K of space
                        //           in the variable_buffer for the eval
                        //               We do this because the call to
                        //               can alter the variable_buffer, and
the char *o,
                        //               behind our backs! By pre-allocating
a large
                        //               buffer chunk, hopefully we can
avoid eval_buffer
                        //               needing to realloc on its own...
      unsigned int offset = o - variable_buffer;
      variable_buffer_length += 8192;
      variable_buffer = (char *) xrealloc (variable_buffer,
      o = variable_buffer + offset;
                        // kjh

  eval_buffer (argv[0]);

  return o;

--- From file function.c --- snippet ends ----

--- From file variable.h  --- snippet starts ----

extern char *variable_buffer;
extern unsigned int variable_buffer_length;     // kjh - added this extern

--- From file variable.h  --- snippet ends ----

Keith Huntington

reply via email to

[Prev in Thread] Current Thread [Next in Thread]