Ejemplo n.º 1
0
void
debug_backtrace_print(FILE *f,
                      const struct debug_stack_frame *backtrace,
                      unsigned nr_frames)
{
   unsigned i;

   for (i = 0; i < nr_frames; ++i) {
      const char *symbol;
      if (!backtrace[i].function)
         break;
      symbol = debug_symbol_name_cached(backtrace[i].function);
      if (symbol)
         fprintf(f, "%s\n", symbol);
   }
}
Ejemplo n.º 2
0
/**
 * Log a reference count change to the log file (if enabled).
 * This is called via the pipe_reference() and debug_reference() functions,
 * basically whenever a reference count is initialized or changed.
 *
 * \param p  the refcount being changed (the value is not changed here)
 * \param get_desc  a function which will be called to print an object's
 *                  name/pointer into a string buffer during logging
 * \param change  the reference count change which must be +/-1 or 0 when
 *                creating the object and initializing the refcount.
 */
void
debug_reference_slowpath(const struct pipe_reference *p,
                         debug_reference_descriptor get_desc, int change)
{
   assert(change >= -1);
   assert(change <= 1);

   if (debug_refcnt_state < 0)
      return;

   if (!debug_refcnt_state) {
      const char *filename = debug_get_option("GALLIUM_REFCNT_LOG", NULL);
      if (filename && filename[0])
         stream = fopen(filename, "wt");

      if (stream)
         debug_refcnt_state = 1;
      else
         debug_refcnt_state = -1;
   }

   if (debug_refcnt_state > 0) {
      struct debug_stack_frame frames[STACK_LEN];
      const char *symbols[STACK_LEN];
      char buf[1024];
      unsigned i;
      unsigned refcnt = p->count;
      unsigned serial;
      boolean existing = debug_serial((void *) p, &serial);

      debug_backtrace_capture(frames, 1, STACK_LEN);
      for (i = 0; i < STACK_LEN; ++i) {
         if (frames[i].function)
            symbols[i] = debug_symbol_name_cached(frames[i].function);
         else
            symbols[i] = 0;
      }

      get_desc(buf, p);

      if (!existing) {
         fprintf(stream, "<%s> %p %u Create\n", buf, (void *) p, serial);
         dump_stack(symbols);

         /* this is here to provide a gradual change even if we don't see
          * the initialization
          */
         for (i = 1; i <= refcnt - change; ++i) {
            fprintf(stream, "<%s> %p %u AddRef %u\n", buf, (void *) p,
                    serial, i);
            dump_stack(symbols);
         }
      }

      if (change) {
         fprintf(stream, "<%s> %p %u %s %u\n", buf, (void *) p, serial,
                 change > 0 ? "AddRef" : "Release", refcnt);
         dump_stack(symbols);
      }

      if (!refcnt) {
         debug_serial_delete((void *) p);
         fprintf(stream, "<%s> %p %u Destroy\n", buf, (void *) p, serial);
         dump_stack(symbols);
      }

      fflush(stream);
   }
}