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.202 2004/09/26 15:18:10 marcus Exp $ + || $Id: main.c,v 1.203 2004/09/27 21:37:13 mast Exp $   */      #include "global.h" - RCSID("$Id: main.c,v 1.202 2004/09/26 15:18:10 marcus Exp $"); + RCSID("$Id: main.c,v 1.203 2004/09/27 21:37:13 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:911:    init_builtin_efuns();    init_signals();    init_dynamic_load();   }      void exit_main(void)   {   #ifdef DO_PIKE_CLEANUP    size_t count;    - #ifdef PIKE_DEBUG -  if (verbose_debug_exit) -  fprintf(stderr,"Exited normally, counting bytes.\n"); - #endif -  +  if (exit_with_cleanup) {    /* Destruct all remaining objects while we have a proper execution    * environment. 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;    count = do_gc (NULL, 1);    while (count) {    size_t new_count = do_gc (NULL, 1);    if (new_count >= count) {    fprintf (stderr, "Some destroy function is creating new objects "    "during final cleanup - can't exit cleanly.\n");    break;    }    count = new_count;    }    gc_destruct_everything = 0; -  +  }       /* Unload dynamic modules before static ones. */    exit_dynamic_load();   #endif   }      void init_main(void)   {   }   
pike.git/src/main.c:983: Inside #if defined(DO_PIKE_CLEANUP) and #if defined(SHARED_NODES)
  #ifdef SHARED_NODES    free(node_hash.table);   #endif /* SHARED_NODES */       exit_pike_security();    free_svalue(& throw_value);    throw_value.type=T_INT;       do_gc(NULL, 1);    - #ifdef PIKE_DEBUG -  if(verbose_debug_exit) +  if (exit_with_cleanup)    { -  +  int leak_found = 0; +    #ifdef _REENTRANT    if(count_pike_threads()>1)    {    fprintf(stderr,"Byte counting aborted, because all threads have not exited properly.\n"); -  verbose_debug_exit=0; +  exit_with_cleanup = 0;    return;    }   #endif      #ifdef DEBUG_MALLOC    search_all_memheaders_for_references();   #endif       /* The use of markers below only works after a gc run where it    * hasn't freed anything. Since we've destructed all objects in    * exit_main, nothing should be left after the run above, so only    * one more run is necessary. */    gc_keep_markers = 1;    do_gc (NULL, 1);      #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); \    if (!m) { \    DO_IF_DEBUG ( \    fprintf (stderr, "Didn't find gc marker as expected for:\n"); \    describe_something (x, T_TYPE, 2, 2, 0, NULL); \    ); \    } \    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", \ +  if (!leak_found) { \ +  fputs ("Leak(s) found at exit:\n", stderr); \ +  leak_found = 1; \ +  } \ +  fprintf (stderr, NAME " got %d unaccounted references: ", \    x->refs - (m->refs + is_static)); \ -  describe_something (x, T_TYPE, 2, 2, 0, NULL); \ +  print_short_svalue (stderr, (union anything *) &x, T_TYPE); \ +  fputc ('\n', stderr); \    } \    } \    } \ -  if (num) \ -  fprintf (stderr, NAME "s left: %"PRINTSIZET"d\n", num); \ +     } while (0)       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   
pike.git/src/main.c:1062:    for (x = START; x; x = x->next) { \    struct marker *m = find_marker (x); \    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) { \ -  m->flags |= GC_CLEANUP_FREED; \ +  DO_IF_DEBUG (m->flags |= GC_CLEANUP_FREED); \    PIKE_CONCAT(free_, TYPE) (x); \    } \    } \    } \    } while (0)       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    -  + #ifdef PIKE_DEBUG    /* 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; -  + #endif       do_gc (NULL, 1);       gc_keep_markers = 0;    exit_gc();      #ifdef DEBUG_MALLOC    {    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();    }   #endif    } - #endif +        destruct_objects_to_destruct_cb();       /* Now there are no arrays/objects/programs/anything left. */       really_clean_up_interpret();       cleanup_callbacks();    free_all_callable_blocks();    exit_destroy_called_mark_hash();