[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Probable bug in function.c : func_eval()
From: |
Keith Huntington |
Subject: |
Probable bug in function.c : func_eval() |
Date: |
Tue, 12 Aug 2003 19:57:52 -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
block
//
// We do this because the call to
eval_buffer()
// 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,
variable_buffer_length);
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