From 3c0c282ac55f12128086d8ff4e92ee1d6187fdb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Mon, 26 Jan 1998 12:01:58 -0800 Subject: [PATCH] many minor memory leaks fixed Rev: NT/.cvsignore:1.3 Rev: src/array.c:1.23 Rev: src/dmalloc.h:1.2 Rev: src/dynamic_buffer.c:1.7 Rev: src/dynamic_buffer.h:1.5 Rev: src/dynamic_load.c:1.23 Rev: src/error.h:1.10 Rev: src/interpret.c:1.62 Rev: src/interpret.h:1.17 Rev: src/language.yacc:1.55 Rev: src/las.c:1.45 Rev: src/las.h:1.12 Rev: src/lex.c:1.41 Rev: src/main.c:1.37 Rev: src/main.h:1.5 Rev: src/modules/Gmp/mpz_glue.c:1.25 Rev: src/modules/Image/font.c:1.27 Rev: src/object.c:1.34 Rev: src/object.h:1.14 Rev: src/operators.c:1.23 Rev: src/pike_memory.c:1.5 Rev: src/pike_types.c:1.30 Rev: src/pike_types.h:1.8 Rev: src/program.c:1.55 Rev: src/program.h:1.28 Rev: src/stralloc.c:1.25 Rev: src/stralloc.h:1.13 Rev: src/svalue.h:1.10 Rev: src/threads.c:1.54 --- NT/.cvsignore | 1 + NT/.gitignore | 1 + src/array.c | 8 +- src/dmalloc.h | 6 +- src/dynamic_buffer.c | 6 +- src/dynamic_buffer.h | 18 ++- src/dynamic_load.c | 2 + src/error.h | 2 + src/interpret.c | 7 +- src/interpret.h | 25 ++-- src/language.yacc | 233 ++++++++++++++++++++++--------------- src/las.c | 78 ++++++++++++- src/las.h | 5 + src/lex.c | 24 +++- src/main.c | 24 ++-- src/main.h | 4 +- src/modules/Gmp/mpz_glue.c | 11 +- src/modules/Image/font.c | 5 +- src/object.c | 18 ++- src/object.h | 8 +- src/operators.c | 7 +- src/pike_memory.c | 30 ++++- src/pike_types.c | 11 +- src/pike_types.h | 3 + src/program.c | 20 ++-- src/program.h | 12 +- src/stralloc.c | 11 +- src/stralloc.h | 10 +- src/svalue.h | 4 +- src/threads.c | 4 +- 30 files changed, 412 insertions(+), 186 deletions(-) diff --git a/NT/.cvsignore b/NT/.cvsignore index 0676347fc2..cb995873dd 100644 --- a/NT/.cvsignore +++ b/NT/.cvsignore @@ -25,3 +25,4 @@ test3.lib test3.mk1 test3.tgt test4.c +testsuite diff --git a/NT/.gitignore b/NT/.gitignore index cd2d92df2c..95aa3ebd8e 100644 --- a/NT/.gitignore +++ b/NT/.gitignore @@ -25,3 +25,4 @@ /test3.mk1 /test3.tgt /test4.c +/testsuite diff --git a/src/array.c b/src/array.c index 577aafe4b5..fe1fe0db5d 100644 --- a/src/array.c +++ b/src/array.c @@ -1138,11 +1138,7 @@ node *make_node_from_array(struct array *a) break; if(e == a->size) { - return mkefuncallnode("allocate", - mknode(F_ARG_LIST, - mkintnode(a->size), - mkstrnode(make_shared_string("mixed")) - )); + return mkefuncallnode("allocate",mkintnode(a->size)); } } if(check_that_array_is_constant(a)) @@ -1562,7 +1558,7 @@ void zap_all_arrays(void) { #if defined(DEBUG) && defined(DEBUG_MALLOC) - if(verbose_debug_exit) + if(verbose_debug_exit && a!=&empty_array) debug_dump_array(a); #endif diff --git a/src/dmalloc.h b/src/dmalloc.h index a62fcdf1be..815a42a437 100644 --- a/src/dmalloc.h +++ b/src/dmalloc.h @@ -2,7 +2,6 @@ extern int verbose_debug_malloc; extern int verbose_debug_exit; -#define main dbm_main extern void *debug_malloc(size_t, const char *, int); extern char *debug_xalloc(long, const char *, int); extern void *debug_calloc(size_t, size_t, const char *, int); @@ -17,8 +16,13 @@ void *debug_malloc_update_location(void *,const char *, int); #define free(x) debug_free((x), __FILE__, __LINE__) #define strdup(x) debug_strdup((x), __FILE__, __LINE__) #define DO_IF_DMALLOC(X) X +#define debug_malloc_touch(X) debug_malloc_update_location((X),__FILE__,__LINE__) +#define debug_malloc_pass(X) debug_malloc_update_location((X),__FILE__,__LINE__) #else +#define dbm_main main #define DO_IF_DMALLOC(X) extern char *xalloc(long); #define debug_malloc_update_location(X,Y,Z) (X) +#define debug_malloc_touch(X) +#define debug_malloc_pass(X) (X) #endif diff --git a/src/dynamic_buffer.c b/src/dynamic_buffer.c index 8efd326753..155be97951 100644 --- a/src/dynamic_buffer.c +++ b/src/dynamic_buffer.c @@ -110,7 +110,7 @@ char *simple_free_buf(void) return complex_free_buf().str; } -struct pike_string *low_free_buf(dynamic_buffer *buf) +struct pike_string *debug_low_free_buf(dynamic_buffer *buf) { struct pike_string *q; if(!buf->s.str) return 0; @@ -121,14 +121,14 @@ struct pike_string *low_free_buf(dynamic_buffer *buf) return q; } -struct pike_string *free_buf(void) { return low_free_buf(&buff); } +struct pike_string *debug_free_buf(void) { return low_free_buf(&buff); } char *make_buf_space(INT32 space) { return low_make_buf_space(space,&buff); } void my_putchar(char b) { low_my_putchar(b,&buff); } void my_binary_strcat(const char *b,INT32 l) { low_my_binary_strcat(b,l,&buff); } void my_strcat(const char *b) { my_binary_strcat(b,strlen(b)); } void init_buf(void) { low_reinit_buf(&buff); } void init_buf_with_string(string s) { low_init_buf_with_string(s,&buff); } -char *return_buf(void) +char *debug_return_buf(void) { my_putchar(0); return buff.s.str; diff --git a/src/dynamic_buffer.h b/src/dynamic_buffer.h index d791778622..6b6892f3a6 100644 --- a/src/dynamic_buffer.h +++ b/src/dynamic_buffer.h @@ -34,23 +34,35 @@ void low_init_buf_with_string(string s, dynamic_buffer *buf); string complex_free_buf(void); void toss_buffer(dynamic_buffer *buf); char *simple_free_buf(void); -struct pike_string *low_free_buf(dynamic_buffer *buf); -struct pike_string *free_buf(void); +struct pike_string *debug_low_free_buf(dynamic_buffer *buf); +struct pike_string *debug_free_buf(void); char *make_buf_space(INT32 space); void my_putchar(char b); void my_binary_strcat(const char *b,INT32 l); void my_strcat(const char *b); void init_buf(void); void init_buf_with_string(string s); -char *return_buf(void); +char *debug_return_buf(void); /* Prototypes end here */ #ifdef DEBUG_MALLOC #define initialize_buf(X) \ do { dynamic_buffer *b_=(X); debug_initialize_buf(b_); \ debug_malloc_update_location(b_->s.str,__FILE__,__LINE__); } while(0) +#define low_free_buf(X) \ + ((struct pike_string *)debug_malloc_touch(debug_low_free_buf(X))) + +#define free_buf() \ + ((struct pike_string *)debug_malloc_touch(debug_free_buf())) + +#define return_buf() \ + ((char *)debug_malloc_touch(debug_return_buf())) + #else #define initialize_buf debug_initialize_buf +#define low_free_buf debug_low_free_buf +#define free_buf debug_free_buf +#define return_buf debug_return_buf #endif #endif diff --git a/src/dynamic_load.c b/src/dynamic_load.c index 75565d8621..b5a9ce8463 100644 --- a/src/dynamic_load.c +++ b/src/dynamic_load.c @@ -157,7 +157,9 @@ void exit_dynamic_load(void) struct module_list *tmp=dynamic_module_list; dynamic_module_list=tmp->next; (*tmp->exit)(); +#ifndef DEBUG_MALLOC dlclose(tmp->module); +#endif free((char *)tmp); } #endif diff --git a/src/error.h b/src/error.h index 9c275f159e..acc5186cfc 100644 --- a/src/error.h +++ b/src/error.h @@ -55,6 +55,7 @@ extern int throw_severity; #define SET_ONERROR(X,Y,Z) \ do{ \ + if(!recoveries) break; \ X.func=(error_call)(Y); \ X.arg=(void *)(Z); \ X.previous=recoveries->onerror; \ @@ -63,6 +64,7 @@ extern int throw_severity; #ifdef DEBUG #define UNSET_ONERROR(X) do {\ + if(!recoveries) break; \ if(recoveries->onerror != &(X)) fatal("UNSET_ONERROR out of sync.\n"); \ recoveries->onerror=(X).previous; \ } while(0) diff --git a/src/interpret.c b/src/interpret.c index 1c645e071f..6db1c6c13e 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: interpret.c,v 1.61 1998/01/25 08:25:07 hubbe Exp $"); +RCSID("$Id: interpret.c,v 1.62 1998/01/26 19:59:53 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -1816,6 +1816,11 @@ static int o_catch(unsigned char *pc) } } +void f_call_function(INT32 args) +{ + mega_apply(APPLY_STACK,args,0,0); +} + int apply_low_safe_and_stupid(struct object *o, INT32 offset) { JMP_BUF tmp; diff --git a/src/interpret.h b/src/interpret.h index 8a7d46afc1..3e69ce67ce 100644 --- a/src/interpret.h +++ b/src/interpret.h @@ -34,23 +34,23 @@ struct frame #define pop_stack() do{ free_svalue(--sp); debug_check_stack(); }while(0) -#define push_program(P) do{ struct program *_=(P); sp->u.program=_; sp++->type=T_PROGRAM; }while(0) +#define push_program(P) do{ struct program *_=(P); debug_malloc_touch(_); sp->u.program=_; sp++->type=T_PROGRAM; }while(0) #define push_int(I) do{ INT32 _=(I); sp->u.integer=_;sp->type=T_INT;sp++->subtype=NUMBER_NUMBER; }while(0) -#define push_mapping(M) do{ struct mapping *_=(M); sp->u.mapping=_; sp++->type=T_MAPPING; }while(0) -#define push_array(A) do{ struct array *_=(A); sp->u.array=_ ;sp++->type=T_ARRAY; }while(0) -#define push_multiset(L) do{ struct multiset *_=(L); sp->u.multiset=_; sp++->type=T_MULTISET; }while(0) -#define push_string(S) do{ struct pike_string *_=(S); sp->subtype=0; sp->u.string=_; sp++->type=T_STRING; }while(0) -#define push_object(O) do{ struct object *_=(O); sp->u.object=_; sp++->type=T_OBJECT; }while(0) +#define push_mapping(M) do{ struct mapping *_=(M); debug_malloc_touch(_); sp->u.mapping=_; sp++->type=T_MAPPING; }while(0) +#define push_array(A) do{ struct array *_=(A); debug_malloc_touch(_); sp->u.array=_ ;sp++->type=T_ARRAY; }while(0) +#define push_multiset(L) do{ struct multiset *_=(L); debug_malloc_touch(_); sp->u.multiset=_; sp++->type=T_MULTISET; }while(0) +#define push_string(S) do{ struct pike_string *_=(S); debug_malloc_touch(_); sp->subtype=0; sp->u.string=_; sp++->type=T_STRING; }while(0) +#define push_object(O) do{ struct object *_=(O); debug_malloc_touch(_); sp->u.object=_; sp++->type=T_OBJECT; }while(0) #define push_float(F) do{ float _=(F); sp->u.float_number=_; sp++->type=T_FLOAT; }while(0) #define push_text(T) push_string(make_shared_string((T))) #define push_constant_text(T) do{ sp->subtype=0; MAKE_CONSTANT_SHARED_STRING(sp->u.string,T); sp++->type=T_STRING; }while(0) -#define ref_push_program(P) do{ struct program *_=(P); _->refs++; sp->u.program=_; sp++->type=T_PROGRAM; }while(0) -#define ref_push_mapping(M) do{ struct mapping *_=(M); _->refs++; sp->u.mapping=_; sp++->type=T_MAPPING; }while(0) -#define ref_push_array(A) do{ struct array *_=(A); _->refs++; sp->u.array=_ ;sp++->type=T_ARRAY; }while(0) -#define ref_push_multiset(L) do{ struct multiset *_=(L); _->refs++; sp->u.multiset=_; sp++->type=T_MULTISET; }while(0) -#define ref_push_string(S) do{ struct pike_string *_=(S); _->refs++; sp->subtype=0; sp->u.string=_; sp++->type=T_STRING; }while(0) -#define ref_push_object(O) do{ struct object *_=(O); _->refs++; sp->u.object=_; sp++->type=T_OBJECT; }while(0) +#define ref_push_program(P) do{ struct program *_=(P); debug_malloc_touch(_); _->refs++; sp->u.program=_; sp++->type=T_PROGRAM; }while(0) +#define ref_push_mapping(M) do{ struct mapping *_=(M); debug_malloc_touch(_); _->refs++; sp->u.mapping=_; sp++->type=T_MAPPING; }while(0) +#define ref_push_array(A) do{ struct array *_=(A); debug_malloc_touch(_); _->refs++; sp->u.array=_ ;sp++->type=T_ARRAY; }while(0) +#define ref_push_multiset(L) do{ struct multiset *_=(L); debug_malloc_touch(_); _->refs++; sp->u.multiset=_; sp++->type=T_MULTISET; }while(0) +#define ref_push_string(S) do{ struct pike_string *_=(S); debug_malloc_touch(_); _->refs++; sp->subtype=0; sp->u.string=_; sp++->type=T_STRING; }while(0) +#define ref_push_object(O) do{ struct object *_=(O); debug_malloc_touch(_); _->refs++; sp->u.object=_; sp++->type=T_OBJECT; }while(0) #define push_svalue(S) do { struct svalue *_=(S); assign_svalue_no_free(sp,_); sp++; }while(0) @@ -118,6 +118,7 @@ void reset_evaluator(void); struct backlog; void dump_backlog(void); void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2); +void f_call_function(INT32 args); int apply_low_safe_and_stupid(struct object *o, INT32 offset); void safe_apply_low(struct object *o,int fun,int args); void safe_apply(struct object *o, char *fun ,INT32 args); diff --git a/src/language.yacc b/src/language.yacc index dc141a3e9b..24e77a9118 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -161,7 +161,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.54 1998/01/25 08:25:08 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.55 1998/01/26 19:59:54 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -221,12 +221,7 @@ static void __yy_memcpy(char *to, char *from, int count); { int number; FLOAT_TYPE fnum; - unsigned int address; /* Address of an instruction */ - struct pike_string *string; - char *str; - unsigned short type; struct node_s *n; - struct efun *efun; } %{ @@ -235,15 +230,6 @@ int yylex(YYSTYPE *yylval); %type <fnum> F_FLOAT -%type <string> F_IDENTIFIER -%type <string> F_STRING -%type <string> cast -%type <string> simple_type -%type <string> low_string -%type <string> optional_identifier -%type <string> optional_rename_inherit -%type <string> string_constant - %type <number> F_ARRAY_ID %type <number> F_BREAK %type <number> F_CASE @@ -293,6 +279,14 @@ int yylex(YYSTYPE *yylval); /* The following symbos return type information */ +%type <n> cast +%type <n> simple_type +%type <n> string_constant +%type <n> string +%type <n> F_STRING +%type <n> optional_rename_inherit +%type <n> optional_identifier +%type <n> F_IDENTIFIER %type <n> assoc_pair %type <n> block %type <n> failsafe_block @@ -336,7 +330,6 @@ int yylex(YYSTYPE *yylval); %type <n> sscanf %type <n> statement %type <n> statements -%type <n> string %type <n> switch %type <n> typeof %type <n> unused @@ -356,10 +349,17 @@ optional_semi_colon: /* empty */ | ';' ; -string_constant: low_string - | string_constant '+' low_string +string_constant: string + | string_constant '+' string { - $$=add_and_free_shared_strings($1,$3); + struct pike_string *a,*b; + copy_shared_string(a,$1->u.sval.u.string); + copy_shared_string(b,$3->u.sval.u.string); + free_node($1); + free_node($3); + a=add_and_free_shared_strings(a,b); + $$=mkstrnode(a); + free_string(a); } ; @@ -369,13 +369,14 @@ optional_rename_inherit: ':' F_IDENTIFIER { $$=$2; } low_program_ref: string_constant { - ref_push_string($1); - push_string($1); + ref_push_string($1->u.sval.u.string); + ref_push_string($1->u.sval.u.string); ref_push_string(lex.current_file); SAFE_APPLY_MASTER("handle_inherit", 2); if(sp[-1].type != T_PROGRAM) - my_yyerror("Couldn't cast string \"%s\" to program",$1->str); + my_yyerror("Couldn't cast string \"%s\" to program",$1->u.sval.u.string->str); + free_node($1); $$=mksvaluenode(sp-1); pop_stack(); } @@ -384,7 +385,6 @@ low_program_ref: string_constant if(last_identifier) { ref_push_string(last_identifier); - last_identifier->refs++; }else{ push_constant_text(""); } @@ -394,7 +394,8 @@ low_program_ref: string_constant program_ref: low_program_ref { - resolv_program($1); + resolv_program($1); + free_node($1); } ; @@ -403,10 +404,10 @@ inheritance: modifiers F_INHERIT low_program_ref optional_rename_inherit ';' if(!(new_program->flags & PROGRAM_PASS_1_DONE)) { struct pike_string *s=sp[-1].u.string; - if($4) s=$4; + if($4) s=$4->u.sval.u.string; compiler_do_inherit($3,$1,s); } - if($4) free_string($4); + if($4) free_node($4); pop_n_elems(1); free_node($3); } @@ -435,7 +436,7 @@ constant_name: F_IDENTIFIER '=' expr0 { if(compiler_pass==2) yyerror("Constant definition is not constant."); - add_constant($1,0, current_modifiers); /* Prototype */ + add_constant($1->u.sval.u.string,0, current_modifiers); /* Prototype */ } else { tmp=eval_low($3); if(tmp < 1) @@ -443,12 +444,12 @@ constant_name: F_IDENTIFIER '=' expr0 yyerror("Error in constant definition."); }else{ pop_n_elems(tmp-1); - add_constant($1,sp-1,current_modifiers); + add_constant($1->u.sval.u.string,sp-1,current_modifiers); pop_stack(); } } if($3) free_node($3); - free_string($1); + free_node($1); } ; @@ -471,11 +472,14 @@ type_or_error: simple_type { if(compiler_frame->current_type) free_string(compiler_frame->current_type); - compiler_frame->current_type=$1; + copy_shared_string(compiler_frame->current_type,$1->u.sval.u.string); + free_node($1); } | /* empty */ { yyerror("Missing type."); + if(compiler_frame->current_type) + free_string(compiler_frame->current_type); copy_shared_string(compiler_frame->current_type, mixed_type_string); } @@ -524,13 +528,17 @@ def: modifiers type_or_error optional_stars F_IDENTIFIER push_finished_type(compiler_frame->variable[e].type); } push_type(T_FUNCTION); - - $<string>$=pop_type(); + + { + struct pike_string *s=pop_type(); + $<n>$=mkstrnode(s); + free_string(s); + } if(compiler_pass==1) { - define_function($4, - $<string>$, + define_function($4->u.sval.u.string, + $<n>$->u.sval.u.string, $1, IDENTIFIER_PIKE_FUNCTION, 0); @@ -550,15 +558,15 @@ def: modifiers type_or_error optional_stars F_IDENTIFIER } } - dooptcode($4, $10, $<string>9, $1); + dooptcode($4->u.sval.u.string, $10, $<n>9->u.sval.u.string, $1); #ifdef DEBUG if(recoveries && sp-evaluator_stack < recoveries->sp) fatal("Stack error (underflow)\n"); #endif } pop_compiler_frame(); - free_string($4); - free_string($<string>9); + free_node($4); + free_node($<n>9); } | modifiers type_or_error name_list ';' {} | inheritance {} @@ -589,14 +597,21 @@ new_arg_name: type optional_dot_dot_dot optional_identifier push_type(T_ARRAY); varargs=1; } + if(!$3) - MAKE_CONSTANT_SHARED_STRING($3,""); + { + struct pike_string *s; + MAKE_CONSTANT_SHARED_STRING(s,""); + $3=mkstrnode(s); + free_string(s); + } - if(islocal($3) >= 0) + if(islocal($3->u.sval.u.string) >= 0) my_yyerror("Variable '%s' appears twice in argument list.", - $3->str); + $3->u.sval.u.string->str); - add_local_name($3, pop_type()); + add_local_name($3->u.sval.u.string, pop_type()); + free_node($3); } ; @@ -631,15 +646,25 @@ optional_stars: optional_stars '*' { $$=$1 + 1; } | /* empty */ { $$=0; } ; -cast: '(' type ')' { $$=pop_type(); } +cast: '(' type ')' + { + struct pike_string *s=pop_type(); + $$=mkstrnode(s); + free_string(s); + } ; type: type '*' { push_type(T_ARRAY); } | type2 ; -simple_type: type2 { $$=pop_type(); } - ; +simple_type: type2 + { + struct pike_string *s=pop_type(); + $$=mkstrnode(s); + free_string(s); + } + ; type2: type2 '|' type3 { push_type(T_OR); } | type3 @@ -756,9 +781,9 @@ new_name: optional_stars F_IDENTIFIER push_finished_type(compiler_frame->current_type); while($1--) push_type(T_ARRAY); type=pop_type(); - define_variable($2, type, current_modifiers); + define_variable($2->u.sval.u.string, type, current_modifiers); free_string(type); - free_string($2); + free_node($2); } | optional_stars F_IDENTIFIER '=' { @@ -766,7 +791,7 @@ new_name: optional_stars F_IDENTIFIER push_finished_type(compiler_frame->current_type); while($1--) push_type(T_ARRAY); type=pop_type(); - $<number>$=define_variable($2, type, current_modifiers); + $<number>$=define_variable($2->u.sval.u.string, type, current_modifiers); free_string(type); } expr0 @@ -775,7 +800,7 @@ new_name: optional_stars F_IDENTIFIER mkcastnode(void_type_string, mknode(F_ASSIGN,$5, mkidentifiernode($<number>4)))); - free_string($2); + free_node($2); } ; @@ -784,15 +809,17 @@ new_local_name: optional_stars F_IDENTIFIER { push_finished_type(compiler_frame->current_type); while($1--) push_type(T_ARRAY); - add_local_name($2, pop_type()); - $$=mknode(F_ASSIGN,mkintnode(0), mklocalnode(islocal($2))); + add_local_name($2->u.sval.u.string, pop_type()); + $$=mknode(F_ASSIGN,mkintnode(0), mklocalnode(islocal($2->u.sval.u.string))); + free_node($2); } | optional_stars F_IDENTIFIER '=' expr0 { push_finished_type(compiler_frame->current_type); while($1--) push_type(T_ARRAY); - add_local_name($2, pop_type()); - $$=mknode(F_ASSIGN,$4,mklocalnode(islocal($2))); + add_local_name($2->u.sval.u.string, pop_type()); + $$=mknode(F_ASSIGN,$4,mklocalnode(islocal($2->u.sval.u.string))); + free_node($2); } ; @@ -918,19 +945,22 @@ class: modifiers F_CLASS optional_identifier { if(!$3) { + struct pike_string *s; char buffer[42]; sprintf(buffer,"__class_%ld",local_class_counter++); - $3=make_shared_string(buffer); + s=make_shared_string(buffer); + $3=mkstrnode(s); + free_string(s); $1|=ID_PRIVATE; } if(compiler_pass==1) { - low_start_new_program(0, $3, $1); + low_start_new_program(0, $3->u.sval.u.string, $1); }else{ int i; struct program *p; struct identifier *id; - i=isidentifier($3); + i=isidentifier($3->u.sval.u.string); if(i<0) { low_start_new_program(new_program,0,0); @@ -943,7 +973,7 @@ class: modifiers F_CLASS optional_identifier s=PROG_FROM_INT(new_program,i)->constants+id->func.offset; if(s->type==T_PROGRAM) { - low_start_new_program(s->u.program, $3, $1); + low_start_new_program(s->u.program, $3->u.sval.u.string, $1); }else{ yyerror("Pass 2: constant redefined!"); low_start_new_program(new_program, 0,0); @@ -963,14 +993,16 @@ class: modifiers F_CLASS optional_identifier else p=end_program(); - $$=mkidentifiernode(isidentifier($3)); + $$=mkidentifiernode(isidentifier($3->u.sval.u.string)); if(!p) yyerror("Class definition failed."); else free_program(p); - free_string($3); + free_node($3); + check_tree($$,0); + } ; @@ -1178,8 +1210,8 @@ expr1: expr2 expr2: expr3 | cast expr2 { - $$=mkcastnode($1,$2); - free_string($1); + $$=mkcastnode($1->u.sval.u.string,$2); + free_node($1); } | F_INC expr4 { $$=mknode(F_INC,$2,0); } | F_DEC expr4 { $$=mknode(F_DEC,$2,0); } @@ -1218,19 +1250,18 @@ expr4: string { $$=mkefuncallnode("aggregate_multiset",$2); } | expr4 F_ARROW F_IDENTIFIER { - $$=mknode(F_ARROW,$1,mkstrnode($3)); - free_string($3); + $$=mknode(F_ARROW,$1,$3); } ; idents: low_idents | idents '.' F_IDENTIFIER { - $$=index_node($1, $3); + $$=index_node($1, $3->u.sval.u.string); free_node($1); if(last_identifier) free_string(last_identifier); - copy_shared_string(last_identifier, $3); - free_string($3); + copy_shared_string(last_identifier, $3->u.sval.u.string); + free_node($3); } ; @@ -1239,20 +1270,20 @@ low_idents: F_IDENTIFIER int i; struct efun *f; if(last_identifier) free_string(last_identifier); - copy_shared_string(last_identifier, $1); - if((i=islocal($1))>=0) + copy_shared_string(last_identifier, $1->u.sval.u.string); + if((i=islocal(last_identifier))>=0) { $$=mklocalnode(i); - }else if((i=isidentifier($1))>=0){ + }else if((i=isidentifier(last_identifier))>=0){ $$=mkidentifiernode(i); - }else if(!($$=find_module_identifier($1))){ + }else if(!($$=find_module_identifier(last_identifier))){ $$=0; if(!num_parse_error) { if(get_master()) { - reference_shared_string($1); - push_string($1); + reference_shared_string(last_identifier); + push_string(last_identifier); ref_push_string(lex.current_file); SAFE_APPLY_MASTER("resolv", 2); @@ -1266,7 +1297,7 @@ low_idents: F_IDENTIFIER else if(IS_ZERO(sp-1) && sp[-1].subtype==1) { if(compiler_pass==2) - my_yyerror("'%s' undefined.", $1->str); + my_yyerror("'%s' undefined.", last_identifier->str); else $$=mknode(F_UNDEFINED,0,0); }else{ @@ -1276,14 +1307,14 @@ low_idents: F_IDENTIFIER }else{ if(compiler_pass==2) { - my_yyerror("'%s' undefined.", $1->str); + my_yyerror("'%s' undefined.", last_identifier->str); }else{ $$=mknode(F_UNDEFINED,0,0); } } } } - free_string($1); + free_node($1); } | F_PREDEF F_COLON_COLON F_IDENTIFIER { @@ -1295,27 +1326,30 @@ low_idents: F_IDENTIFIER #endif /* __CHECKER__ */ tmp.u.mapping=get_builtin_constants(); tmp2=mkconstantsvaluenode(&tmp); - $$=index_node(tmp2, $3); + $$=index_node(tmp2, $3->u.sval.u.string); free_node(tmp2); - free_string($3); + free_node($3); } | F_IDENTIFIER F_COLON_COLON F_IDENTIFIER { int f; struct reference *idp; - f=reference_inherited_identifier($1,$3); + f=reference_inherited_identifier($1->u.sval.u.string, + $3->u.sval.u.string); idp=new_program->identifier_references+f; if (f<0) { - my_yyerror("Undefined identifier %s::%s", $1->str,$3->str); + my_yyerror("Undefined identifier %s::%s", + $1->u.sval.u.string->str, + $3->u.sval.u.string->str); $$=mkintnode(0); } else { $$=mkidentifiernode(f); } - free_string($1); - free_string($3); + free_node($1); + free_node($3); } | F_COLON_COLON F_IDENTIFIER { @@ -1325,7 +1359,7 @@ low_idents: F_IDENTIFIER for(e=1;e<(int)new_program->num_inherits;e++) { if(new_program->inherits[e].inherit_level!=1) continue; - i=low_reference_inherited_identifier(e,$2); + i=low_reference_inherited_identifier(e,$2->u.sval.u.string); if(i==-1) continue; if($$) { @@ -1340,7 +1374,7 @@ low_idents: F_IDENTIFIER }else{ if($$->token==F_ARG_LIST) $$=mkefuncallnode("aggregate",$$); } - free_string($2); + free_node($2); } ; @@ -1374,14 +1408,13 @@ gauge: F_GAUGE catch_arg typeof: F_TYPEOF '(' expr0 ')' { + struct pike_string *s; node *tmp; tmp=mknode(F_ARG_LIST,$3,0); - if($3 && $3->type) - { - $$=mkstrnode(describe_type($3->type)); - }else{ - $$=mkstrnode(describe_type(mixed_type_string)); - } + + s=describe_type( $3 && $3->type ? $3->type : mixed_type_string); + $$=mkstrnode(s); + free_string(s); free_node(tmp); } ; @@ -1400,24 +1433,29 @@ sscanf: F_SSCANF '(' expr0 ',' expr0 lvalue_list ')' lvalue: expr4 | type F_IDENTIFIER { - add_local_name($2,pop_type()); - $$=mklocalnode(islocal($2)); + add_local_name($2->u.sval.u.string,pop_type()); + $$=mklocalnode(islocal($2->u.sval.u.string)); + free_node($2); } lvalue_list: /* empty */ { $$ = 0; } | ',' lvalue lvalue_list { $$ = mknode(F_LVALUE_LIST,$2,$3); } ; -low_string: F_STRING - | low_string F_STRING +string: F_STRING + | string F_STRING { - $$=add_and_free_shared_strings($1,$2); + struct pike_string *a,*b; + copy_shared_string(a,$1->u.sval.u.string); + copy_shared_string(b,$2->u.sval.u.string); + free_node($1); + free_node($2); + a=add_and_free_shared_strings(a,b); + $$=mkstrnode(a); + free_string(a); } ; -string: low_string { $$=mkstrnode($1); free_string($1); } ; - - %% void yyerror(char *str) @@ -1456,10 +1494,11 @@ void yyerror(char *str) } } -/* argument must be a shared string (no need to free it) */ +/* argument must be a shared string */ void add_local_name(struct pike_string *str, struct pike_string *type) { + reference_shared_string(str); if (compiler_frame->current_number_of_locals == MAX_LOCAL) { yyerror("Too many local variables"); diff --git a/src/las.c b/src/las.c index b876d4e1b0..26a0e69bc5 100644 --- a/src/las.c +++ b/src/las.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: las.c,v 1.44 1998/01/26 02:34:50 grubba Exp $"); +RCSID("$Id: las.c,v 1.45 1998/01/26 19:59:54 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -73,9 +73,45 @@ int cdr_is_node(node *n) } } +#ifdef DEBUG +void check_tree(node *n, int depth) +{ + if(!d_flag) return; + if(!n) return; + if(n->token==USHRT_MAX) + fatal("Free node in tree.\n"); + + if(!(depth & 1023)) + { + node *q; + for(q=n->parent;q;q=q->parent) + if(q->parent==n) + fatal("Cyclic node structure found.\n"); + } + depth++; + + if(car_is_node(n)) + { + if(CAR(n)->parent != n) + fatal("Parent is wrong.\n"); + + check_tree(CAR(n),depth); + } + + if(cdr_is_node(n)) + { + if(CDR(n)->parent != n) + fatal("Parent is wrong.\n"); + + check_tree(CDR(n),depth); + } +} +#endif + INT32 count_args(node *n) { int a,b; + check_tree(n,0); if(!n) return 0; switch(n->token) { @@ -129,6 +165,8 @@ struct pike_string *find_return_type(node *n) { struct pike_string *a,*b; + check_tree(n,0); + if(!n) return 0; if(!(n->tree_info & OPT_RETURN)) return 0; if(car_is_node(n)) @@ -169,9 +207,10 @@ void free_all_nodes() struct node_chunk *tmp2; int e=0; - +#ifndef DEBUG if(cumulative_parse_error) { +#endif for(tmp2=node_chunks;tmp2;tmp2=tmp2->next) e+=NODES; for(tmp=free_nodes;tmp;tmp=CAR(tmp)) e--; @@ -192,7 +231,9 @@ void free_all_nodes() #ifdef DEBUG if(!cumulative_parse_error) { - fprintf(stderr,"Free node at %p.\n",tmp); + fprintf(stderr,"Free node at %p, (%s:%d) (token=%d).\n",tmp, tmp->current_file->str, tmp->line_number, tmp->token); + if(tmp->token==F_CONSTANT) + print_tree(tmp); } else #endif @@ -201,6 +242,7 @@ void free_all_nodes() /* Make sure we don't free any nodes twice */ if(car_is_node(tmp)) CAR(tmp)=0; if(cdr_is_node(tmp)) CDR(tmp)=0; + debug_malloc_touch(tmp->type); free_node(tmp); } } @@ -211,7 +253,9 @@ void free_all_nodes() fatal("Failed to free %d nodes when compiling!\n",e2); #endif } +#ifndef DEBUG } +#endif while(node_chunks) { tmp2=node_chunks; @@ -242,6 +286,9 @@ void free_node(node *n) } n->token=USHRT_MAX; if(n->type) free_string(n->type); +#ifdef DEBUG + if(n->current_file) free_string(n->current_file); +#endif CAR(n)=free_nodes; free_nodes=n; } @@ -267,6 +314,9 @@ static node *mkemptynode(void) free_nodes=CAR(res); res->token=0; res->line_number=lex.current_line; +#ifdef DEBUG + copy_shared_string(res->current_file, lex.current_file); +#endif res->type=0; res->node_info=0; res->tree_info=0; @@ -277,6 +327,8 @@ static node *mkemptynode(void) node *mknode(short token,node *a,node *b) { node *res; + check_tree(a,0); + check_tree(b,0); res = mkemptynode(); CAR(res) = a; CDR(res) = b; @@ -342,7 +394,11 @@ node *mknode(short token,node *a,node *b) if(b) b->parent = res; if(!num_parse_error && compiler_pass==2) + { + check_tree(res,0); optimize(res); + check_tree(res,0); + } #ifdef DEBUG if(d_flag > 3) @@ -454,6 +510,7 @@ node *mkidentifiernode(int i) CDR(res)=0; #endif res->u.number = i; + check_tree(res,0); return res; } @@ -505,6 +562,8 @@ void resolv_constant(node *n) struct program *p; INT32 numid; + check_tree(n,0); + if(!n) { push_int(0); @@ -562,6 +621,8 @@ void resolv_constant(node *n) void resolv_program(node *n) { + check_tree(n,0); + resolv_constant(n); switch(sp[-1].type) { @@ -595,6 +656,9 @@ node *index_node(node *n, struct pike_string * id) { node *ret; JMP_BUF tmp; + + check_tree(n,0); + if(SETJMP(tmp)) { ONERROR tmp; @@ -644,6 +708,9 @@ node *index_node(node *n, struct pike_string * id) int node_is_eq(node *a,node *b) { + check_tree(a,0); + check_tree(b,0); + if(a == b) return 1; if(!a || !b) return 0; if(a->token != b->token) return 0; @@ -737,6 +804,7 @@ node *mksvaluenode(struct svalue *s) node *copy_node(node *n) { node *b; + check_tree(n,0); if(!n) return n; switch(n->token) { @@ -989,6 +1057,7 @@ static void low_print_tree(node *foo,int needlval) void print_tree(node *n) { + check_tree(n,0); low_print_tree(n,0); printf("\n"); fflush(stdout); @@ -1540,6 +1609,7 @@ static void optimize(node *n) } } fix_type_field(n); + debug_malloc_touch(n->type); #ifdef DEBUG if(l_flag > 3 && n) @@ -2153,6 +2223,8 @@ int dooptcode(struct pike_string *name, int args, vargs, ret; struct svalue *foo; + check_tree(n,0); + #ifdef DEBUG if(a_flag > 1) fprintf(stderr,"Doing function '%s' at %x\n",name->str,PC); diff --git a/src/las.h b/src/las.h index c6ca978291..43c2b9b618 100644 --- a/src/las.h +++ b/src/las.h @@ -60,6 +60,7 @@ struct compiler_frame /* Prototypes begin here */ int car_is_node(node *n); int cdr_is_node(node *n); +void check_tree(node *n, int depth); INT32 count_args(node *n); struct pike_string *find_return_type(node *n); struct node_chunk; @@ -117,4 +118,8 @@ int dooptcode(struct pike_string *name, #define INHERIT(i) (new_program->inherits+(i)) #define PC (new_program->num_program) +#ifndef DEBUG +#define check_tree(X,Y) +#endif + #endif diff --git a/src/lex.c b/src/lex.c index c62b6ab02b..8dc93d78c4 100644 --- a/src/lex.c +++ b/src/lex.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: lex.c,v 1.40 1998/01/25 08:25:09 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.41 1998/01/26 19:59:55 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -539,8 +539,12 @@ static int yylex2(YYSTYPE *yylval) return F_NUMBER; case '"': - yylval->string=readstring(); + { + struct pike_string *s=readstring(); + yylval->n=mkstrnode(s); + free_string(s); return F_STRING; + } case ':': if(GOBBLE(':')) return F_COLON_COLON; @@ -735,8 +739,12 @@ static int yylex2(YYSTYPE *yylval) break; } - yylval->string=make_shared_string(tmp+offset); - return F_IDENTIFIER; + { + struct pike_string *s=make_shared_string(tmp+offset); + yylval->n=mkstrnode(s); + free_string(s); + return F_IDENTIFIER; + } } @@ -855,8 +863,12 @@ static int yylex2(YYSTYPE *yylval) break; } } - yylval->string=make_shared_binary_string(buf,len); - return F_IDENTIFIER; + { + struct pike_string *tmp=make_shared_binary_string(buf,len); + yylval->n=mkstrnode(tmp); + free_string(tmp); + return F_IDENTIFIER; + } }else{ char buff[100]; sprintf(buff, "Illegal character (hex %02x) '%c'", c, c); diff --git a/src/main.c b/src/main.c index a64871a7f4..156d0e17e7 100644 --- a/src/main.c +++ b/src/main.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: main.c,v 1.36 1998/01/25 09:15:47 hubbe Exp $"); +RCSID("$Id: main.c,v 1.37 1998/01/26 19:59:56 hubbe Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -69,7 +69,7 @@ struct callback *add_exit_callback(callback_func call, return add_to_callback(&exit_callbacks, call, arg, free_func); } -int main(int argc, char **argv) +int dbm_main(int argc, char **argv) { JMP_BUF back; int e, num, do_backend; @@ -304,9 +304,13 @@ int main(int argc, char **argv) UNSETJMP(back); do_exit(num); + return num; /* avoid warning */ } -void do_exit(int num) +#undef ATTRIBUTE +#define ATTRIBUTE(X) + +void do_exit(int num) ATTRIBUTE((noreturn)) { call_callback(&exit_callbacks, (void *)0); free_callback(&exit_callbacks); @@ -361,7 +365,7 @@ void low_exit_main(void) INT32 num,size,recount=0; count_memory_in_arrays(&num, &size); - if(num || size) + if(num) { recount++; fprintf(stderr,"Arrays left: %d (%d bytes) (zapped)\n",num,size); @@ -370,7 +374,7 @@ void low_exit_main(void) zap_all_arrays(); count_memory_in_mappings(&num, &size); - if(num || size) + if(num) { recount++; fprintf(stderr,"Mappings left: %d (%d bytes) (zapped)\n",num,size); @@ -379,7 +383,7 @@ void low_exit_main(void) zap_all_mappings(); count_memory_in_multisets(&num, &size); - if(num || size) + if(num) fprintf(stderr,"Multisets left: %d (%d bytes)\n",num,size); @@ -398,7 +402,7 @@ void low_exit_main(void) count_memory_in_programs(&num, &size); - if(num || size) + if(num) fprintf(stderr,"Programs left: %d (%d bytes)\n",num,size); { @@ -411,13 +415,9 @@ void low_exit_main(void) count_memory_in_objects(&num, &size); - if(num || size) + if(num) fprintf(stderr,"Objects left: %d (%d bytes)\n",num,size); - count_memory_in_strings(&num, &size); - if(num || size) - fprintf(stderr,"Strings left: %d (%d bytes) (zapped)\n",num,size); - cleanup_shared_string_table(); } #else diff --git a/src/main.h b/src/main.h index 64e65a9927..54698c0a6d 100644 --- a/src/main.h +++ b/src/main.h @@ -17,8 +17,8 @@ struct callback *add_post_master_callback(callback_func call, struct callback *add_exit_callback(callback_func call, void *arg, callback_func free_func); -int main(int argc, char **argv); -void do_exit(int num); +int dbm_main(int argc, char **argv); +void do_exit(int num) ATTRIBUTE((noreturn)); void low_init_main(void); void exit_main(void); void init_main(void); diff --git a/src/modules/Gmp/mpz_glue.c b/src/modules/Gmp/mpz_glue.c index 56916f4e7f..116835f98f 100644 --- a/src/modules/Gmp/mpz_glue.c +++ b/src/modules/Gmp/mpz_glue.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: mpz_glue.c,v 1.24 1997/10/29 11:20:41 hubbe Exp $"); +RCSID("$Id: mpz_glue.c,v 1.25 1998/01/26 20:01:17 hubbe Exp $"); #include "gmp_machine.h" #if !defined(HAVE_LIBGMP) @@ -297,8 +297,15 @@ static void mpzmod_cast(INT32 args) error("mpz->cast() to other type than string, int or float.\n"); } +#ifdef DEBUG_MALLOC +#define get_mpz(X,Y) \ + (debug_get_mpz((X),(Y)),( (X)->type==T_OBJECT? debug_malloc_touch((X)->u.object) :0 ),debug_get_mpz((X),(Y))) +#else +#define get_mpz debug_get_mpz +#endif + /* Converts an svalue, located on the stack, to an mpz object */ -static MP_INT *get_mpz(struct svalue *s, int throw_error) +static MP_INT *debug_get_mpz(struct svalue *s, int throw_error) { #define ERROR(x) if (throw_error) error(x) struct object *o; diff --git a/src/modules/Image/font.c b/src/modules/Image/font.c index a21aa39e44..9251e6b5b0 100644 --- a/src/modules/Image/font.c +++ b/src/modules/Image/font.c @@ -1,4 +1,4 @@ -/* $Id: font.c,v 1.26 1998/01/16 22:09:10 grubba Exp $ */ +/* $Id: font.c,v 1.27 1998/01/26 20:01:58 hubbe Exp $ */ #include <config.h> #define SPACE_CHAR 'i' @@ -6,7 +6,7 @@ /* **! module Image **! note -**! $Id: font.c,v 1.26 1998/01/16 22:09:10 grubba Exp $ +**! $Id: font.c,v 1.27 1998/01/26 20:01:58 hubbe Exp $ **! class font **! **! note @@ -134,6 +134,7 @@ Kerningtable types: #include <sys/mman.h> #endif +#include "dmalloc.h" static struct program *font_program; extern struct program *image_program; diff --git a/src/object.c b/src/object.c index 3ea12bf304..3360b32e3a 100644 --- a/src/object.c +++ b/src/object.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: object.c,v 1.33 1998/01/25 08:25:12 hubbe Exp $"); +RCSID("$Id: object.c,v 1.34 1998/01/26 19:59:56 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -128,11 +128,20 @@ static void call_pike_initializers(struct object *o, int args) pop_stack(); } -struct object *clone_object(struct program *p, int args) +void do_free_object(struct object *o) { + free_object(o); +} + +struct object *debug_clone_object(struct program *p, int args) +{ + ONERROR tmp; struct object *o=low_clone(p); + SET_ONERROR(tmp, do_free_object, o); + debug_malloc_touch(o); call_c_initializers(o); call_pike_initializers(o,args); + UNSET_ONERROR(tmp); return o; } @@ -141,12 +150,16 @@ struct object *parent_clone_object(struct program *p, int parent_identifier, int args) { + ONERROR tmp; struct object *o=low_clone(p); + SET_ONERROR(tmp, do_free_object, o); + debug_malloc_touch(o); o->parent=parent; parent->refs++; o->parent_identifier=parent_identifier; call_c_initializers(o); call_pike_initializers(o,args); + UNSET_ONERROR(tmp); return o; } @@ -202,6 +215,7 @@ struct object *get_master(void) } } master_object=low_clone(master_program); + debug_malloc_touch(master_object); call_c_initializers(master_object); call_pike_initializers(master_object,0); diff --git a/src/object.h b/src/object.h index 04aea59f01..ee127e8bc8 100644 --- a/src/object.h +++ b/src/object.h @@ -41,7 +41,7 @@ extern struct program *master_program; /* Prototypes begin here */ void setup_fake_object(void); struct object *low_clone(struct program *p); -struct object *clone_object(struct program *p, int args); +struct object *debug_clone_object(struct program *p, int args); struct object *parent_clone_object(struct program *p, struct object *parent, int parent_identifier, @@ -84,5 +84,11 @@ void gc_free_all_unreferenced_objects(void); void count_memory_in_objects(INT32 *num_, INT32 *size_); /* Prototypes end here */ +#ifdef MALLOC_DEBUG +#define clone_object(X,Y) ((struct object *)debug_malloc_touch(debug_clone_object((X),(Y)))) +#else +#define clone_object debug_clone_object +#endif + #endif /* OBJECT_H */ diff --git a/src/operators.c b/src/operators.c index 504471bfa0..fa7b28b113 100644 --- a/src/operators.c +++ b/src/operators.c @@ -5,7 +5,7 @@ \*/ #include <math.h> #include "global.h" -RCSID("$Id: operators.c,v 1.22 1998/01/13 22:56:47 hubbe Exp $"); +RCSID("$Id: operators.c,v 1.23 1998/01/26 19:59:57 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "multiset.h" @@ -1418,11 +1418,6 @@ static int generate_sizeof(node *n) return 1; } -void f_call_function(INT32 args) -{ - mega_apply(APPLY_STACK,args,0,0); -} - static int generate_call_function(node *n) { node **arg; diff --git a/src/pike_memory.c b/src/pike_memory.c index 5b4b88783d..102443801f 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -478,6 +478,7 @@ struct memloc_block static struct memloc_block *memloc_blocks=0; static struct memloc *free_memlocs=0; +static struct memhdr no_leak_memlocs; static struct memloc *alloc_memloc(void) { @@ -534,6 +535,15 @@ static void add_location(struct memhdr *mh, const char *fn, int line) mh->locations=ml; } +static int find_location(struct memhdr *mh, const char *fn, int line) +{ + struct memloc *ml; + for(ml=mh->locations;ml;ml=ml->next) + if(ml->filename==fn && ml->line==line) + return 1; + return 0; +} + static void make_memhdr(void *p, int s, const char *fn, int line) { struct memhdr *mh=alloc_memhdr(); @@ -563,6 +573,7 @@ static int remove_memhdr(void *p) struct memloc *ml; while((ml=mh->locations)) { + add_location(&no_leak_memlocs, ml->filename, ml->line); mh->locations=ml->next; ml->next=free_memlocs; free_memlocs=ml; @@ -655,9 +666,15 @@ static void cleanup_memhdrs() for(m=hash[h];m;m=m->next) { struct memloc *l; - fprintf(stderr, "LEAK: (%p) %d bytes (%ld refs?)\n",m->data, m->size,(long)*(INT32 *)m->data); + fprintf(stderr, "LEAK: (%p) %d bytes\n",m->data, m->size); for(l=m->locations;l;l=l->next) - fprintf(stderr," *** %s:%d (%d times)\n",l->filename, l->line, l->times); + fprintf(stderr," *** %s:%d (%d times) %s\n", + l->filename, + l->line, + l->times, + find_location(&no_leak_memlocs, + l->filename, + l->line) ? "" : " *"); } } } @@ -672,9 +689,12 @@ int main(int argc, char *argv[]) void * debug_malloc_update_location(void *p,const char *fn, int line) { - struct memhdr *mh=find_memhdr(p); - if(mh) - add_location(mh, fn, line); + if(p) + { + struct memhdr *mh; + if((mh=find_memhdr(p))) + add_location(mh, fn, line); + } return p; } diff --git a/src/pike_types.c b/src/pike_types.c index f83fc612bb..c19dd598b8 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: pike_types.c,v 1.29 1998/01/25 08:25:13 hubbe Exp $"); +RCSID("$Id: pike_types.c,v 1.30 1998/01/26 19:59:58 hubbe Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -914,9 +914,14 @@ int match_types(struct pike_string *a,struct pike_string *b) } +#ifdef DEBUG_MALLOC +#define low_index_type(X,Y) ((struct pike_string *)debug_malloc_touch(debug_low_index_type((X),(Y)))) +#else +#define low_index_type debug_low_index_type +#endif /* FIXME, add the index */ -static struct pike_string *low_index_type(char *t, node *n) +static struct pike_string *debug_low_index_type(char *t, node *n) { switch(EXTRACT_UCHAR(t++)) { @@ -969,6 +974,8 @@ static struct pike_string *low_index_type(char *t, node *n) if(!a) return b; push_finished_type(b); push_finished_type(a); + free_string(a); + free_string(b); push_type(T_OR); return pop_unfinished_type(); } diff --git a/src/pike_types.h b/src/pike_types.h index 00646b53a4..0c449555f2 100644 --- a/src/pike_types.h +++ b/src/pike_types.h @@ -14,6 +14,9 @@ struct node_s INT16 line_number; INT16 node_info; INT16 tree_info; +#ifdef DEBUG + struct pike_string *current_file; +#endif struct pike_string *type; struct node_s *parent; union diff --git a/src/program.c b/src/program.c index 3c5ea79646..546f989a33 100644 --- a/src/program.c +++ b/src/program.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: program.c,v 1.54 1998/01/25 08:25:14 hubbe Exp $"); +RCSID("$Id: program.c,v 1.55 1998/01/26 19:59:59 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -478,9 +478,14 @@ void really_free_program(struct program *p) for(e=1; e<p->num_inherits; e++) { - free_program(p->inherits[e].prog); - if(p->inherits[e].parent) - free_object(p->inherits[e].parent); + if(p->inherits[e].name) + free_string(p->inherits[e].name); + if(e) + { + free_program(p->inherits[e].prog); + if(p->inherits[e].parent) + free_object(p->inherits[e].parent); + } } if(p->prev) @@ -777,7 +782,7 @@ struct program *end_first_pass(int finish) /* * Finish this program, returning the newly built program */ -struct program *end_program(void) +struct program *debug_end_program(void) { return end_first_pass(1); } @@ -937,8 +942,7 @@ void low_inherit(struct program *p, { if(e==0) { - inherit.name=name; - reference_shared_string(name); + copy_shared_string(inherit.name,name); } else if(inherit.name) { @@ -1397,7 +1401,7 @@ int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 fl } -int end_class(char *name, INT32 flags) +int debug_end_class(char *name, INT32 flags) { INT32 ret; struct svalue tmp; diff --git a/src/program.h b/src/program.h index de26fe64c2..e18f49936d 100644 --- a/src/program.h +++ b/src/program.h @@ -240,7 +240,7 @@ void really_free_program(struct program *p); void dump_program_desc(struct program *p); void check_program(struct program *p); struct program *end_first_pass(int finish); -struct program *end_program(void); +struct program *debug_end_program(void); SIZE_T add_storage(SIZE_T size); void set_init_callback(void (*init)(struct object *)); void set_exit_callback(void (*exit)(struct object *)); @@ -301,7 +301,7 @@ int add_program_constant(char *name, struct program *p, INT32 flags); int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags); -int end_class(char *name, INT32 flags); +int debug_end_class(char *name, INT32 flags); INT32 define_function(struct pike_string *name, struct pike_string *type, INT16 flags, @@ -343,3 +343,11 @@ void yywarning(char *fmt, ...) ATTRIBUTE((format(printf,1,2))); #endif + +#ifdef DEBUG_MALLOC +#define end_program() ((struct program *)debug_malloc_touch(debug_end_program())) +#define end_class(NAME, FLAGS) do { debug_malloc_touch(new_program); debug_end_class(NAME, FLAGS); }while(0) +#else +#define end_class debug_end_class +#define end_program debug_end_program +#endif diff --git a/src/stralloc.c b/src/stralloc.c index 576674f22e..660a72adcd 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -397,7 +397,7 @@ void dump_stralloc_strings(void) struct pike_string *p; for(e=0;e<htable_size;e++) for(p=base_table[e];p;p=p->next) - printf("%ld refs \"%s\"\n",(long)p->refs,p->str); + printf("0x%p: %ld refs \"%s\"\n",p,(long)p->refs,p->str); } #endif @@ -669,8 +669,13 @@ void cleanup_shared_string_table(void) if(verbose_debug_exit) { - fprintf(stderr,"Leaked strings \n"); - dump_stralloc_strings(); + INT32 num,size; + count_memory_in_strings(&num,&size); + if(num) + { + fprintf(stderr,"Strings left: %d (%d bytes) (zapped)\n",num,size); + dump_stralloc_strings(); + } } #endif for(e=0;e<htable_size;e++) diff --git a/src/stralloc.h b/src/stralloc.h index 35388541b2..18f709dd53 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -31,11 +31,11 @@ struct pike_string *debug_findstring(const struct pike_string *foo); #define my_order_strcmp(X,Y) ((char *)(X)-(char *)(Y)) #define is_same_string(X,Y) ((X)==(Y)) -#define reference_shared_string(s) (s)->refs++ -#define copy_shared_string(to,s) ((to)=(s))->refs++ - #ifdef DEBUG_MALLOC +#define reference_shared_string(s) do { struct pike_string *S_=(s); debug_malloc_touch(S_); S_->refs++; }while(0) +#define copy_shared_string(to,s) do { struct pike_string *S_=(to)=(s); debug_malloc_touch(S_); S_->refs++; }while(0) + struct shared_string_location { struct pike_string *s; @@ -56,6 +56,10 @@ extern struct shared_string_location *all_shared_string_locations; #else + +#define reference_shared_string(s) (s)->refs++ +#define copy_shared_string(to,s) ((to)=(s))->refs++ + #define MAKE_CONSTANT_SHARED_STRING(var, text) \ do { static struct pike_string *str_; \ if(!str_) str_=make_shared_string((text)); \ diff --git a/src/svalue.h b/src/svalue.h index 5ed08d1b38..e198ff8377 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -182,8 +182,8 @@ do{ \ #endif -#define free_svalue(X) do { struct svalue *_s=(X); check_type(_s->type); check_refs(_s); if(_s->type<=MAX_REF_TYPE && --*(_s->u.refs) <=0) really_free_svalue(_s); }while(0) -#define assign_svalue_no_free(X,Y) do { struct svalue _tmp, *_to=(X), *_from=(Y); check_type(_from->type); check_refs(_from); *_to=_tmp=*_from; if(_tmp.type <= MAX_REF_TYPE) _tmp.u.refs[0]++; }while(0) +#define free_svalue(X) do { struct svalue *_s=(X); check_type(_s->type); check_refs(_s); if(_s->type<=MAX_REF_TYPE) { debug_malloc_touch(_s->u.refs); if(--*(_s->u.refs) <=0) really_free_svalue(_s); } }while(0) +#define assign_svalue_no_free(X,Y) do { struct svalue _tmp, *_to=(X), *_from=(Y); check_type(_from->type); check_refs(_from); *_to=_tmp=*_from; if(_tmp.type <= MAX_REF_TYPE) { debug_malloc_touch(_tmp.u.refs); _tmp.u.refs[0]++; } }while(0) #define assign_svalue(X,Y) do { struct svalue *_to2=(X), *_from2=(Y); free_svalue(_to2); assign_svalue_no_free(_to2, _from2); }while(0) extern struct svalue dest_ob_zero; diff --git a/src/threads.c b/src/threads.c index 98f621e4d1..27bb724746 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.53 1998/01/25 08:25:16 hubbe Exp $"); +RCSID("$Id: threads.c,v 1.54 1998/01/26 20:00:01 hubbe Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -14,6 +14,7 @@ int threads_disabled = 0; #include "constants.h" #include "program.h" #include "gc.h" +#include "main.h" #ifdef __NT__ @@ -214,7 +215,6 @@ void *new_thread_func(void * data) free((char *)data); /* Moved by per, to avoid some bugs.... */ UNSETJMP(back); - destruct(thread_id); THREADS_FPRINTF((stderr,"THREADS_ALLOW() Thread %08x done\n", (unsigned int)thread_id)); -- GitLab