Check and remove high stack usage

I checked all stack overflow potential problems found with
gcc -Wstack-usage=16384
and
clang -Wframe-larger-than=16384 -no-inline

Fixes:
Added '#pragma clang diagnostic ignored "-Wframe-larger-than="'
  to a lot of function to where stack usage large but resonable.
- Added stack check warnings to BUILD scrips when using clang and debug.

Function changed to use malloc instead allocating things on stack:
- read_bootstrap_query() now allocates line_buffer (20000 bytes) with
  malloc() instead of using stack. This has a small performance impact
  but this is not releant for bootstrap.
- mroonga grn_select() used 65856 bytes on stack. Changed it to use
  malloc().
- Wsrep_schema::replay_transaction() and
  Wsrep_schema::recover_sr_transactions().
- Connect zipOpen3()

Not fixed:
- mroonga/vendor/groonga/lib/expr.c grn_proc_call() uses
  43712 byte on stack.  However this is not easy to fix as the stack
  used is caused by a lot of code generated by defines.
- Most changes in mroonga/groonga where only adding of pragmas to disable
  stack warnings.
- rocksdb/options/options_helper.cc uses 20288 of stack space.
  (no reason to fix except to get rid of the compiler warning)
- Causes using alloca() where the allocation size is resonable.
- An issue in libmariadb (reported to connectors).
This commit is contained in:
Monty 2024-04-19 13:10:58 +03:00
commit 0ccdf54b64
32 changed files with 293 additions and 106 deletions

View file

@ -18,6 +18,7 @@
#include "../grn_proc.h"
#include "../grn_db.h"
#include <my_attribute.h>
#include <groonga/plugin.h>
@ -73,6 +74,8 @@ command_object_list_dump_flags(grn_ctx *ctx, grn_obj_spec *spec)
GRN_OBJ_FIN(ctx, &flags);
}
PRAGMA_DISABLE_CHECK_STACK_FRAME
static grn_obj *
command_object_list(grn_ctx *ctx,
int nargs,
@ -401,6 +404,7 @@ command_object_list(grn_ctx *ctx,
return NULL;
}
PRAGMA_REENABLE_CHECK_STACK_FRAME
void
grn_proc_init_object_list(grn_ctx *ctx)

View file

@ -17,9 +17,8 @@
*/
#include "../grn_proc.h"
#include "../grn_db.h"
#include <my_attribute.h>
#include <groonga/plugin.h>
typedef struct {
@ -572,6 +571,8 @@ command_schema_table_output_token_filters(grn_ctx *ctx, grn_obj *table)
GRN_OBJ_FIN(ctx, &token_filters);
}
PRAGMA_DISABLE_CHECK_STACK_FRAME
static void
command_schema_table_command_collect_arguments(grn_ctx *ctx,
grn_obj *table,
@ -692,6 +693,7 @@ command_schema_table_command_collect_arguments(grn_ctx *ctx,
#undef ADD_OBJECT_NAME
#undef ADD
}
PRAGMA_REENABLE_CHECK_STACK_FRAME
static void
command_schema_table_output_command(grn_ctx *ctx, grn_obj *table)
@ -875,6 +877,8 @@ command_schema_output_indexes(grn_ctx *ctx, grn_obj *object)
}
}
PRAGMA_DISABLE_CHECK_STACK_FRAME
static void
command_schema_column_command_collect_arguments(grn_ctx *ctx,
grn_obj *table,
@ -973,6 +977,7 @@ command_schema_column_command_collect_arguments(grn_ctx *ctx,
#undef ADD_OBJECT_NAME
#undef ADD
}
PRAGMA_REENABLE_CHECK_STACK_FRAME
static void
command_schema_column_output_command(grn_ctx *ctx,

View file

@ -24,6 +24,7 @@
#include "../grn_util.h"
#include "../grn_cache.h"
#include "../grn_ii.h"
#include <my_attribute.h>
#include "../grn_ts.h"
@ -2912,7 +2913,7 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
uint32_t nhits;
grn_obj *outbuf = ctx->impl->output.buf;
grn_content_type output_type = ctx->impl->output.type;
char cache_key[GRN_CACHE_MAX_KEY_SIZE];
char *cache_key_buffer= 0;
uint32_t cache_key_size;
long long int threshold, original_threshold = 0;
grn_cache *cache_obj = grn_cache_current_get(ctx);
@ -2985,8 +2986,9 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
} GRN_HASH_EACH_END(ctx, cursor);
}
#undef DRILLDOWN_CACHE_SIZE
if (cache_key_size <= GRN_CACHE_MAX_KEY_SIZE) {
char *cp = cache_key;
if (cache_key_size <= GRN_CACHE_MAX_KEY_SIZE &&
(cache_key_buffer= (char*) malloc(cache_key_size+1))) {
char *cp = cache_key_buffer;
#define PUT_CACHE_KEY(string) \
if ((string).value) \
@ -3066,11 +3068,12 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
{
grn_rc rc;
rc = grn_cache_fetch(ctx, cache_obj, cache_key, cache_key_size, outbuf);
rc = grn_cache_fetch(ctx, cache_obj, cache_key_buffer, cache_key_size, outbuf);
if (rc == GRN_SUCCESS) {
GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_CACHE,
":", "cache(%" GRN_FMT_LLD ")",
(long long int)GRN_TEXT_LEN(outbuf));
free(cache_key_buffer);
return ctx->rc;
}
}
@ -3119,7 +3122,7 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
data->cache.length != 2 ||
data->cache.value[0] != 'n' ||
data->cache.value[1] != 'o')) {
grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf);
grn_cache_update(ctx, cache_obj, cache_key_buffer, cache_key_size, outbuf);
}
goto exit;
}
@ -3186,7 +3189,7 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
data->cache.length != 2 ||
data->cache.value[0] != 'n' ||
data->cache.value[1] != 'o')) {
grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf);
grn_cache_update(ctx, cache_obj, cache_key_buffer, cache_key_size, outbuf);
}
if (data->taintable > 0) {
grn_db_touch(ctx, DB_OBJ(data->tables.target)->db);
@ -3200,6 +3203,7 @@ exit :
/* GRN_LOG(ctx, GRN_LOG_NONE, "%d", ctx->seqno); */
free(cache_key_buffer);
return ctx->rc;
}
@ -3424,6 +3428,9 @@ grn_select_data_fill_drilldown_columns(grn_ctx *ctx,
strlen(prefix));
}
PRAGMA_DISABLE_CHECK_STACK_FRAME
static grn_bool
grn_select_data_fill_drilldowns(grn_ctx *ctx,
grn_user_data *user_data,
@ -3562,6 +3569,7 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx,
return succeeded;
}
}
PRAGMA_REENABLE_CHECK_STACK_FRAME
static grn_obj *
command_select(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)