Preventing stack-overflow crashes (improving on max_expr_depth)
От | Tom Lane |
---|---|
Тема | Preventing stack-overflow crashes (improving on max_expr_depth) |
Дата | |
Msg-id | 6410.1072829720@sss.pgh.pa.us обсуждение исходный текст |
Ответы |
Re: Preventing stack-overflow crashes (improving on max_expr_depth)
Re: Preventing stack-overflow crashes (improving on max_expr_depth) |
Список | pgsql-hackers |
We've had a couple of complaints in the past about recursive functions crashing the server by overflowing the C execution stack. There is a GUC variable max_expr_depth that is intended to prevent this sort of problem for the particular case of overly complex arithmetic expressions, but it's difficult to apply a similar solution to function calls. A function nesting depth limit would necessarily be pretty arbitrary, since different functions might use very different amounts of stack space. It occurred to me today that it would not be difficult to implement a direct check on the physical size of the execution stack. We could have PostgresMain do this: /* global variables: */char *stack_base_ptr;int max_stack_size; /* settable through GUC */ PostgresMain(...){ char stack_base_loc; stack_base_ptr = &stack_base_loc; ... server main loop here ...} Then, in key recursive routines such as ExecQual, add a stack depth test that looks like void check_stack_depth(void){ char stack_top_loc; if (abs(stack_base_ptr - &stack_top_loc) > max_stack_size) elog(ERROR, "Stack depth limit exceeded");} Essentially we're measuring the distance between the local variables of PostgresMain and those of the current recursive routine. (The abs() operation is needed since the stack grows up on some machines and down on others.) Now, instead of a max_expr_depth variable that no one really knows how to set intelligently, we have a max_stack_size variable that we can tell people exactly how to set: a megabyte or so less than your "ulimit -s" value should work fine for most cases. And it works for everything; recursive function calls, whatever. I imagine that somewhere in the fine print of the ANSI C standard, it says that this maneuver doesn't give well-defined results --- but I cannot think of any platform where it wouldn't work. Comments? regards, tom lane
В списке pgsql-hackers по дате отправления: