示例#1
0
int
backtrace_full (struct backtrace_state *state, int skip,
		backtrace_full_callback callback,
		backtrace_error_callback error_callback, void *data)
{
  struct backtrace_data bdata;
  void *p;

  bdata.skip = skip + 1;
  bdata.state = state;
  bdata.callback = callback;
  bdata.error_callback = error_callback;
  bdata.data = data;
  bdata.ret = 0;

  /* If we can't allocate any memory at all, don't try to produce
     file/line information.  */
  p = backtrace_alloc (state, 4096, NULL, NULL);
  if (p == NULL)
    bdata.can_alloc = 0;
  else
    {
      backtrace_free (state, p, 4096, NULL, NULL);
      bdata.can_alloc = 1;
    }

  _Unwind_Backtrace (unwind, &bdata);
  return bdata.ret;
}
示例#2
0
void
backtrace_release_view (struct backtrace_state *state,
			struct backtrace_view *view,
			backtrace_error_callback error_callback,
			void *data)
{
  backtrace_free (state, view->base, view->len, error_callback, data);
  view->data = NULL;
  view->base = NULL;
}
示例#3
0
void *
backtrace_alloc (struct backtrace_state *state,
                 size_t size, backtrace_error_callback error_callback,
                 void *data)
{
    void *ret;
    int locked;
    struct backtrace_freelist_struct **pp;
    size_t pagesize;
    size_t asksize;
    void *page;

    ret = NULL;

    /* If we can acquire the lock, then see if there is space on the
       free list.  If we can't acquire the lock, drop straight into
       using mmap.  __sync_lock_test_and_set returns the old state of
       the lock, so we have acquired it if it returns 0.  */

    if (!state->threaded)
        locked = 1;
    else
        locked = __sync_lock_test_and_set (&state->lock_alloc, 1) == 0;

    if (locked)
    {
        for (pp = &state->freelist; *pp != NULL; pp = &(*pp)->next)
        {
            if ((*pp)->size >= size)
            {
                struct backtrace_freelist_struct *p;

                p = *pp;
                *pp = p->next;

                /* Round for alignment; we assume that no type we care about
                is more than 8 bytes.  */
                size = (size + 7) & ~ (size_t) 7;
                if (size < p->size)
                    backtrace_free_locked (state, (char *) p + size,
                                           p->size - size);

                ret = (void *) p;

                break;
            }
        }

        if (state->threaded)
            __sync_lock_release (&state->lock_alloc);
    }

    if (ret == NULL)
    {
        /* Allocate a new page.  */

        pagesize = getpagesize ();
        asksize = (size + pagesize - 1) & ~ (pagesize - 1);
        page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        if (page == NULL)
            error_callback (data, "mmap", errno);
        else
        {
            size = (size + 7) & ~ (size_t) 7;
            if (size < asksize)
                backtrace_free (state, (char *) page + size, asksize - size,
                                error_callback, data);

            ret = page;
        }
    }

    return ret;
}