pike.git / src / main.c

version» Context lines:

pike.git/src/main.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: main.c,v 1.168 2003/03/26 18:53:46 nilsson Exp $ + || $Id: main.c,v 1.169 2003/03/30 02:08:08 mast Exp $   */      #include "global.h" - RCSID("$Id: main.c,v 1.168 2003/03/26 18:53:46 nilsson Exp $"); + RCSID("$Id: main.c,v 1.169 2003/03/30 02:08:08 mast Exp $");   #include "fdlib.h"   #include "backend.h"   #include "module.h"   #include "object.h"   #include "language.h"   #include "lex.h"   #include "pike_types.h"   #include "builtin_functions.h"   #include "array.h"   #include "stralloc.h"
pike.git/src/main.c:811:       init_builtin();       init_builtin_efuns();    init_signals();    init_dynamic_load();   }      void exit_main(void)   { - #ifdef DO_PIKE_CLEANUP -  cleanup_objects(); - #endif +    }      void init_main(void)   {   }      void low_exit_main(void)   {   #ifdef DO_PIKE_CLEANUP    void exit_iterators(void);
pike.git/src/main.c:845: Inside #if defined(DO_PIKE_CLEANUP)
   exit_cpp();    cleanup_interpret();    exit_builtin_constants();    cleanup_module_support();    exit_operators();    exit_iterators();    cleanup_program();    cleanup_compiler();    cleanup_error();    exit_backend(); +  cleanup_gc(); +  cleanup_pike_types();      #ifdef SHARED_NODES    free(node_hash.table);   #endif /* SHARED_NODES */       exit_pike_security();    free_svalue(& throw_value);    throw_value.type=T_INT;    { -  + #ifdef DEBUG_MALLOC +  gc_keep_markers = 1; + #endif    while(1) {    int tmp=num_objects;    do_gc(NULL, 1);    if(num_objects >= tmp) break;    }    }    -  cleanup_gc(); -  -  cleanup_pike_types(); -  +    #if defined(PIKE_DEBUG) && defined(DEBUG_MALLOC)    if(verbose_debug_exit)    { -  INT32 num,size,recount=0; +     fprintf(stderr,"Exited normally, counting bytes.\n");      #ifdef _REENTRANT    if(count_pike_threads()>1)    {    fprintf(stderr,"Byte counting aborted, because all threads have not exited properly.\n");    verbose_debug_exit=0;    return;    }   #endif    -  +     search_all_memheaders_for_references();    -  count_memory_in_arrays(&num, &size); -  if(num) -  { -  recount++; -  fprintf(stderr,"Arrays left: %d (%d bytes) (zapped)\n",num,size); -  } + #define REPORT_LINKED_LIST_LEAKS(TYPE, START, END, T_TYPE, NAME) do { \ +  size_t num = 0; \ +  struct TYPE *x; \ +  for (x = START; x != END; x = x->next) { \ +  struct marker *m = find_marker (x); \ +  num++; \ +  if (!m) { \ +  fprintf (stderr, "Didn't find gc marker as expected for:\n"); \ +  describe_something (x, T_TYPE, 2, 2, 0, NULL); \ +  } \ +  else if (m->refs != x->refs) { \ +  fprintf (stderr, NAME " got %d extra external references:\n", \ +  x->refs - m->refs); \ +  describe_something (x, T_TYPE, 2, 2, 0, NULL); \ +  } \ +  } \ +  if (num) \ +  fprintf (stderr, NAME "s left: %"PRINTSIZET"d\n", num); \ +  } while (0)    -  zap_all_arrays(); +  REPORT_LINKED_LIST_LEAKS (array, &empty_array, &empty_array, T_ARRAY, "Array"); +  REPORT_LINKED_LIST_LEAKS (multiset, first_multiset, NULL, T_MULTISET, "Multiset"); +  REPORT_LINKED_LIST_LEAKS (mapping, first_mapping, NULL, T_MAPPING, "Mapping"); +  REPORT_LINKED_LIST_LEAKS (program, first_program, NULL, T_PROGRAM, "Program"); +  REPORT_LINKED_LIST_LEAKS (object, first_object, NULL, T_OBJECT, "Object");    -  count_memory_in_mappings(&num, &size); -  if(num) -  { -  recount++; -  fprintf(stderr,"Mappings left: %d (%d bytes) (zapped)\n",num,size); -  } + #undef REPORT_LINKED_LIST_LEAKS    -  zap_all_mappings(); +  /* Just remove the extra external refs reported above and do +  * another gc so that we don't report the blocks again in the low +  * level dmalloc reports. */    -  count_memory_in_multisets(&num, &size); -  if(num) -  fprintf(stderr,"Multisets left: %d (%d bytes)\n",num,size); + #define ZAP_LINKED_LIST_LEAKS(TYPE, START, END) do { \ +  struct TYPE *x; \ +  for (x = START; x != END; x = x->next) { \ +  struct marker *m = find_marker (x); \ +  if (m) \ +  while (x->refs > m->refs) \ +  PIKE_CONCAT(free_, TYPE) (x); \ +  } \ +  } while (0)    -  +  ZAP_LINKED_LIST_LEAKS (array, weak_shrink_empty_array.next, &empty_array); +  ZAP_LINKED_LIST_LEAKS (multiset, first_multiset, NULL); +  ZAP_LINKED_LIST_LEAKS (mapping, first_mapping, NULL); +  ZAP_LINKED_LIST_LEAKS (program, first_program, NULL); +  ZAP_LINKED_LIST_LEAKS (object, first_object, NULL);    -  destruct_objects_to_destruct_cb(); -  if(recount) -  { + #undef ZAP_LINKED_LIST_LEAKS    -  fprintf(stderr,"Garbage collecting..\n"); -  do_gc(NULL, 1); +  /* If we stumble on the real refs whose refcounts we've zapped +  * above we should try to handle it gracefully. */ +  gc_external_refs_zapped = 1;    -  count_memory_in_arrays(&num, &size); -  fprintf(stderr,"Arrays left: %d (%d bytes)\n",num,size); -  count_memory_in_mappings(&num, &size); -  fprintf(stderr,"Mappings left: %d (%d bytes)\n",num,size); -  count_memory_in_multisets(&num, &size); -  fprintf(stderr,"Multisets left: %d (%d bytes)\n",num,size); -  } +  gc_keep_markers = 0; +  do_gc (NULL, 1);    -  -  count_memory_in_programs(&num, &size); -  if(num) -  fprintf(stderr,"Programs left: %d (%d bytes)\n",num,size); -  +     { -  struct program *p; -  for(p=first_program;p;p=p->next) -  describe_something(p, T_PROGRAM, 0,2,0, NULL); -  } -  -  -  count_memory_in_objects(&num, &size); -  if(num) -  fprintf(stderr,"Objects left: %d (%d bytes)\n",num,size); -  -  { -  struct object *o; -  for(o=first_object;o;o=o->next) -  describe_something(o, T_OBJECT, 0,2,0, NULL); -  } -  +  INT32 num, size;    count_memory_in_pike_types(&num, &size);    if (num)    fprintf(stderr, "Types left: %d (%d bytes)\n", num, size);    describe_all_types();    } -  +  }   #else -  -  zap_all_arrays(); -  zap_all_mappings(); -  -  destruct_objects_to_destruct_cb(); +  gc_keep_markers = 0; +  do_gc (NULL, 1);   #endif    -  +  cleanup_objects(); +     really_clean_up_interpret();       cleanup_callbacks();    free_all_callable_blocks();    exit_destroy_called_mark_hash();       cleanup_pike_type_table();    cleanup_shared_string_table();       free_dynamic_load();