From 4997f676d7b1c8d81e8534a66ada4929ffd3e639 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 29 Jan 2010 16:35:23 +0300 Subject: [PATCH] bail if things are taking too long I was trying to test postgresql and there is a bit of code that does: if (!strcmp(foo, bar) || !strcmp(x, y) ... It does around a million strcmp comparisons in a row. And glibc strcmp() is a very complicated macro. Smatch got bogged down trying to figure out all the various code paths and macros. This patch says just bail on that function and go to the next. Signed-off-by: Dan Carpenter --- smatch.h | 1 + smatch_flow.c | 7 ++++--- smatch_implied.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/smatch.h b/smatch.h index 76d235ad..a810cd9c 100644 --- a/smatch.h +++ b/smatch.h @@ -232,6 +232,7 @@ extern struct symbol *cur_func_sym; extern struct expression_list *big_expression_stack; extern struct statement_list *big_statement_stack; extern int __in_pre_condition; +extern int __bail_on_rest_of_function; /* smatch_conditions */ void __split_whole_condition(struct expression *expr); diff --git a/smatch_flow.c b/smatch_flow.c index 37c5b3f8..07421c4b 100644 --- a/smatch_flow.c +++ b/smatch_flow.c @@ -29,7 +29,7 @@ static struct expression_list *switch_expr_stack = NULL; struct expression_list *big_expression_stack; struct statement_list *big_statement_stack; int __in_pre_condition = 0; - +int __bail_on_rest_of_function = 0; char *get_function(void) { return cur_func; } int get_lineno(void) { return __smatch_lineno; } int get_func_pos(void) { return __smatch_lineno - line_func_start; } @@ -331,11 +331,11 @@ void __split_statements(struct statement *stmt) if (!stmt) return; - if (out_of_memory()) { + if (out_of_memory() || __bail_on_rest_of_function) { static char *printed = NULL; if (printed != cur_func) - sm_msg("Function too big. Giving up."); + sm_msg("Function too hairy. Giving up."); printed = cur_func; return; } @@ -577,6 +577,7 @@ static void split_functions(struct symbol_list *sym_list) free_data_info_allocs(); free_expression_stack(&switch_expr_stack); __free_ptr_list((struct ptr_list **)&big_statement_stack); + __bail_on_rest_of_function = 0; } else { __pass_to_client(sym, BASE_HOOK); } diff --git a/smatch_implied.c b/smatch_implied.c index 258e1248..5f5273f9 100644 --- a/smatch_implied.c +++ b/smatch_implied.c @@ -48,6 +48,8 @@ * a pool: a pool is an slist that has been merged with another slist. */ +#include +#include #include "smatch.h" #include "smatch_slist.h" #include "smatch_extra.h" @@ -298,6 +300,10 @@ static void separate_and_filter(struct sm_state *sm_state, int comparison, struc { struct state_list_stack *true_stack = NULL; struct state_list_stack *false_stack = NULL; + struct timeval time_before; + struct timeval time_after; + + gettimeofday(&time_before, NULL); if (!is_merged(sm_state)) { DIMPLIED("%d '%s' is not merged.\n", get_lineno(), sm_state->name); @@ -327,6 +333,10 @@ static void separate_and_filter(struct sm_state *sm_state, int comparison, struc printf("These are the implied states for the false path:\n"); __print_slist(*false_states); } + + gettimeofday(&time_after, NULL); + if (time_after.tv_sec - time_before.tv_sec > 15) + __bail_on_rest_of_function = 1; } static char *get_implication_variable(struct expression *expr, struct symbol **symp) -- 2.11.4.GIT