Example #1
0
/* Clear both lists.                                                    */
GC_INNER void GC_print_all_errors(void)
{
    static GC_bool printing_errors = FALSE;
    unsigned i;
    DCL_LOCK_STATE;

    LOCK();
    if (printing_errors) {
        UNLOCK();
        return;
    }
    printing_errors = TRUE;
    UNLOCK();
    if (GC_debugging_started) GC_print_all_smashed();
    for (i = 0; i < GC_n_leaked; ++i) {
        ptr_t p = GC_leaked[i];
        if (HDR(p) -> hb_obj_kind == PTRFREE) {
            GC_err_printf("Leaked atomic object at ");
        } else {
            GC_err_printf("Leaked composite object at ");
        }
        GC_print_heap_obj(p);
        GC_err_printf("\n");
        GC_free(p);
        GC_leaked[i] = 0;
    }
    GC_n_leaked = 0;
    printing_errors = FALSE;
}
Example #2
0
  /* Print back trace for p */
  GC_API void GC_CALL GC_print_backtrace(void *p)
  {
    void *current = p;
    int i;
    GC_ref_kind source;
    size_t offset;
    void *base;

    GC_print_heap_obj(GC_base(current));
    GC_err_printf("\n");
    for (i = 0; ; ++i) {
      source = GC_get_back_ptr_info(current, &base, &offset);
      if (GC_UNREFERENCED == source) {
        GC_err_printf("Reference could not be found\n");
        goto out;
      }
      if (GC_NO_SPACE == source) {
        GC_err_printf("No debug info in object: Can't find reference\n");
        goto out;
      }
      GC_err_printf("Reachable via %d levels of pointers from ", i);
      switch(source) {
        case GC_REFD_FROM_ROOT:
          GC_err_printf("root at %p\n\n", base);
          goto out;
        case GC_REFD_FROM_REG:
          GC_err_printf("root in register\n\n");
          goto out;
        case GC_FINALIZER_REFD:
          GC_err_printf("list of finalizable objects\n\n");
          goto out;
        case GC_REFD_FROM_HEAP:
          GC_err_printf("offset %ld in object:\n", (unsigned long)offset);
          /* Take GC_base(base) to get real base, i.e. header. */
          GC_print_heap_obj(GC_base(base));
          GC_err_printf("\n");
          break;
        default:
          GC_err_printf("INTERNAL ERROR: UNEXPECTED SOURCE!!!!\n");
          goto out;
      }
      current = base;
    }
    out:;
  }
Example #3
0
/* Clear both lists.  Called without the allocation lock held.          */
GC_INNER void GC_print_all_errors(void)
{
    static GC_bool printing_errors = FALSE;
    GC_bool have_errors;
    unsigned i, n_leaked;
    ptr_t leaked[MAX_LEAKED];
    DCL_LOCK_STATE;

    LOCK();
    if (printing_errors) {
        UNLOCK();
        return;
    }
    have_errors = GC_have_errors;
    printing_errors = TRUE;
    n_leaked = GC_n_leaked;
    GC_ASSERT(n_leaked <= MAX_LEAKED);
    BCOPY(GC_leaked, leaked, n_leaked * sizeof(ptr_t));
    GC_n_leaked = 0;
    BZERO(GC_leaked, n_leaked * sizeof(ptr_t));
    UNLOCK();

    if (GC_debugging_started) {
      GC_print_all_smashed();
    } else {
      have_errors = FALSE;
    }

    for (i = 0; i < n_leaked; i++) {
        ptr_t p = leaked[i];
        if (HDR(p) -> hb_obj_kind == PTRFREE) {
            GC_err_printf("Leaked atomic object at ");
        } else {
            GC_err_printf("Leaked composite object at ");
        }
        GC_print_heap_obj(p);
        GC_err_printf("\n");
        GC_free(p);
        have_errors = TRUE;
    }

    if (have_errors
#       ifndef GC_ABORT_ON_LEAK
          && GETENV("GC_ABORT_ON_LEAK") != NULL
#       endif
        ) {
      ABORT("Leaked or smashed objects encountered");
    }

    LOCK();
    printing_errors = FALSE;
    UNLOCK();
}
Example #4
0
/* Clear both lists.  Called without the allocation lock held.          */
GC_INNER void GC_print_all_errors(void)
{
    static GC_bool printing_errors = FALSE;
    GC_bool have_errors;
    unsigned i;
    DCL_LOCK_STATE;

    LOCK();
    if (printing_errors) {
        UNLOCK();
        return;
    }
    have_errors = GC_have_errors;
    printing_errors = TRUE;
    UNLOCK();

    if (GC_debugging_started) {
        GC_print_all_smashed();
    } else {
        have_errors = FALSE;
    }

    for (i = 0; i < GC_n_leaked; ++i) {
        ptr_t p = GC_leaked[i];
        if (HDR(p) -> hb_obj_kind == PTRFREE) {
            GC_err_printf("Leaked atomic object at ");
        } else {
            GC_err_printf("Leaked composite object at ");
        }
        GC_print_heap_obj(p);
        GC_err_printf("\n");
        GC_free(p);
        GC_leaked[i] = 0;
        have_errors = TRUE;
    }
    GC_n_leaked = 0;

    if (have_errors
#       ifndef GC_ABORT_ON_LEAK
            && GETENV("GC_ABORT_ON_LEAK") != NULL
#       endif
       ) {
        ABORT("Leaked or smashed objects encountered");
    }

    printing_errors = FALSE;
}
Example #5
0
void GC_print_back_graph_stats(void)
{
  GC_ASSERT(I_HOLD_LOCK());
  GC_printf("Maximum backwards height of reachable objects at GC %lu is %lu\n",
            (unsigned long) GC_gc_no, (unsigned long)GC_max_height);
  if (GC_max_height > GC_max_max_height) {
    ptr_t obj = GC_deepest_obj;

    GC_max_max_height = GC_max_height;
    UNLOCK();
    GC_err_printf(
            "The following unreachable object is last in a longest chain "
            "of unreachable objects:\n");
    GC_print_heap_obj(obj);
    LOCK();
  }
  GC_COND_LOG_PRINTF("Needed max total of %d back-edge structs\n",
                     GC_n_back_edge_structs);
  GC_apply_to_each_object(reset_back_edge);
  GC_deepest_obj = 0;
}
Example #6
0
/* q are pointers to the object base, i.e. pointers to an oh.           */
static void add_edge(ptr_t p, ptr_t q)
{
    ptr_t pred = GET_OH_BG_PTR(q);
    back_edges * be, *be_cont;
    word i;

    GC_ASSERT(p == GC_base(p) && q == GC_base(q));
    if (!GC_HAS_DEBUG_INFO(q) || !GC_HAS_DEBUG_INFO(p)) {
      /* This is really a misinterpreted free list link, since we saw   */
      /* a pointer to a free list.  Don't overwrite it!                 */
      return;
    }
    if (NULL == pred) {
      static unsigned random_number = 13;
#     define GOT_LUCKY_NUMBER (((++random_number) & 0x7f) == 0)
        /* A not very random number we use to occasionally allocate a   */
        /* back_edges structure even for a single backward edge.  This  */
        /* prevents us from repeatedly tracing back through very long   */
        /* chains, since we will have some place to store height and    */
        /* in_progress flags along the way.                             */

        SET_OH_BG_PTR(q, p);
        if (GOT_LUCKY_NUMBER) ensure_struct(q);
        return;
    }

    /* Check whether it was already in the list of predecessors. */
    {
      back_edges *e = (back_edges *)((word)pred & ~FLAG_MANY);
      word n_edges;
      word total;
      int local = 0;

      if (((word)pred & FLAG_MANY) != 0) {
        n_edges = e -> n_edges;
      } else if (pred != NULL && ((word)pred & 1) == 0) {
        /* A misinterpreted freelist link.      */
        n_edges = 1;
        local = -1;
      } else {
        n_edges = 0;
      }
      for (total = 0; total < n_edges; ++total) {
        if (local == MAX_IN) {
          e = e -> cont;
          local = 0;
        }
        if (local >= 0)
          pred = e -> edges[local++];
        if (pred == p)
          return;
      }
    }

    ensure_struct(q);
    be = (back_edges *)((word)GET_OH_BG_PTR(q) & ~FLAG_MANY);
    for (i = be -> n_edges, be_cont = be; i > MAX_IN; i -= MAX_IN)
        be_cont = be_cont -> cont;
    if (i == MAX_IN) {
        be_cont -> cont = new_back_edges();
        be_cont = be_cont -> cont;
        i = 0;
    }
    be_cont -> edges[i] = p;
    be -> n_edges++;
#   ifdef DEBUG_PRINT_BIG_N_EDGES
      if (GC_print_stats == VERBOSE && be -> n_edges == 100) {
        GC_err_printf("The following object has big in-degree:\n");
        GC_print_heap_obj(q);
      }
#   endif
}