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.192 2004/03/15 22:47:15 mast Exp $ + || $Id: main.c,v 1.193 2004/03/16 14:10:05 mast Exp $   */      #include "global.h" - RCSID("$Id: main.c,v 1.192 2004/03/15 22:47:15 mast Exp $"); + RCSID("$Id: main.c,v 1.193 2004/03/16 14:10:05 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:896:    init_builtin();       init_builtin_efuns();    init_signals();    init_dynamic_load();   }      void exit_main(void)   {   #ifdef DO_PIKE_CLEANUP + #ifdef DEBUG_MALLOC +  gc_keep_markers = verbose_debug_exit; +  if (verbose_debug_exit) +  fprintf(stderr,"Exited normally, counting bytes.\n"); + #endif +     /* Destruct all remaining objects before modules are shut down, so    * that they don't get calls to object exit callbacks after their    * module exit callback. The downside is that the leak report below    * will always report destructed objects. We use the gc in a special    * mode for this to get a reasonably sane destruct order. */    gc_destruct_everything = 1;    do_gc (NULL, 1);    gc_destruct_everything = 0;       /* Unload dynamic modules before static ones. */
pike.git/src/main.c:953: Inside #if defined(DO_PIKE_CLEANUP)
   th_cleanup();      #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 = verbose_debug_exit; - #endif -  while(1) { -  int tmp=num_objects; +     do_gc(NULL, 1); -  if(num_objects >= tmp) break; -  } -  } +       #ifdef DEBUG_MALLOC    if(verbose_debug_exit)    { -  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();    - #define REPORT_LINKED_LIST_LEAKS(TYPE, START, T_TYPE, NAME) do { \ + #define STATIC_ARRAYS {&empty_array, &weak_empty_array, &weak_shrink_empty_array} +  + #define REPORT_LINKED_LIST_LEAKS(TYPE, START, STATICS, T_TYPE, NAME) do { \    size_t num = 0; \    struct TYPE *x; \    for (x = START; x; 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) { \ +  else { \ +  int is_static = 0; \ +  static const struct TYPE *statics[] = STATICS; \ +  ptrdiff_t i; /* Use signed type to avoid warnings from gcc. */ \ +  for (i = 0; i < (ptrdiff_t) NELEM (statics); i++) \ +  if (x == statics[i]) \ +  is_static = 1; \ +  if (x->refs != m->refs + is_static) { \ +  num++; \    fprintf (stderr, NAME " got %d unaccounted references:\n", \ -  x->refs - m->refs); \ +  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)    -  REPORT_LINKED_LIST_LEAKS (array, first_array, T_ARRAY, "Array"); -  REPORT_LINKED_LIST_LEAKS (multiset, first_multiset, T_MULTISET, "Multiset"); -  REPORT_LINKED_LIST_LEAKS (mapping, first_mapping, T_MAPPING, "Mapping"); -  REPORT_LINKED_LIST_LEAKS (program, first_program, T_PROGRAM, "Program"); -  REPORT_LINKED_LIST_LEAKS (object, first_object, T_OBJECT, "Object"); +  REPORT_LINKED_LIST_LEAKS (array, first_array, STATIC_ARRAYS, T_ARRAY, "Array"); +  REPORT_LINKED_LIST_LEAKS (multiset, first_multiset, {}, T_MULTISET, "Multiset"); +  REPORT_LINKED_LIST_LEAKS (mapping, first_mapping, {}, T_MAPPING, "Mapping"); +  REPORT_LINKED_LIST_LEAKS (program, first_program, {}, T_PROGRAM, "Program"); +  REPORT_LINKED_LIST_LEAKS (object, first_object, {}, T_OBJECT, "Object");      #undef REPORT_LINKED_LIST_LEAKS       /* 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. */    - #define ZAP_LINKED_LIST_LEAKS(TYPE, START) do { \ + #define ZAP_LINKED_LIST_LEAKS(TYPE, START, STATICS) do { \    struct TYPE *x; \    for (x = START; x; x = x->next) { \    struct marker *m = find_marker (x); \ -  if (m) \ -  while (x->refs > m->refs) \ +  if (m) { \ +  int is_static = 0; \ +  static const struct TYPE *statics[] = STATICS; \ +  ptrdiff_t i; /* Use signed type to avoid warnings from gcc. */ \ +  for (i = 0; i < (ptrdiff_t) NELEM (statics); i++) \ +  if (x == statics[i]) \ +  is_static = 1; \ +  while (x->refs > m->refs + is_static) \    PIKE_CONCAT(free_, TYPE) (x); \ -  +  } \ +  PIKE_CONCAT (zap_next_, TYPE):; \    } \    } while (0)    -  ZAP_LINKED_LIST_LEAKS (array, first_array); -  ZAP_LINKED_LIST_LEAKS (multiset, first_multiset); -  ZAP_LINKED_LIST_LEAKS (mapping, first_mapping); -  ZAP_LINKED_LIST_LEAKS (program, first_program); -  ZAP_LINKED_LIST_LEAKS (object, first_object); +  ZAP_LINKED_LIST_LEAKS (array, first_array, STATIC_ARRAYS); +  ZAP_LINKED_LIST_LEAKS (multiset, first_multiset, {}); +  ZAP_LINKED_LIST_LEAKS (mapping, first_mapping, {}); +  ZAP_LINKED_LIST_LEAKS (program, first_program, {}); +  ZAP_LINKED_LIST_LEAKS (object, first_object, {});      #undef ZAP_LINKED_LIST_LEAKS       /* 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;       gc_keep_markers = 0;    do_gc (NULL, 1);