Пример #1
0
void VT_User_marker__(unsigned int mid, const char* mtext)
{
  uint64_t time;

  VT_INIT;

  VT_MEMHOOKS_OFF();

  time = vt_pform_wtime();
  vt_marker(VT_CURRENT_THREAD, &time, mid, mtext);

  VT_MEMHOOKS_ON();
}
void VT_User_marker__(unsigned int mid, const char* mtext)
{
  uint64_t time;

  VT_INIT;

  VT_SUSPEND_MALLOC_TRACING(VT_CURRENT_THREAD);

  time = vt_pform_wtime();
  vt_marker(VT_CURRENT_THREAD, &time, mid, mtext);

  VT_RESUME_MALLOC_TRACING(VT_CURRENT_THREAD);
}
Пример #3
0
void* vt_malloc_hook(size_t size, const void* caller)
{
  void* result;
  uint64_t bytes;
  uint64_t time;
  uint8_t was_recorded;

  VT_MEMHOOKS_OFF(); /* restore original hooks */

  time = vt_pform_wtime();
  was_recorded = vt_enter(VT_CURRENT_THREAD, &time,
                          memhook_regid[MEMHOOK_REG_MALLOC]);

  result = malloc(size); /* call recursively */

  /* get total allocated memory */
  if ( result != NULL )
  {
    bytes = ( ~ (uint64_t) 3 ) & (uint64_t) *( (size_t*) ( (char*)result - SIZEOF_VOIDP ) );
  }
  else
  {
    bytes = 0;
  }

  /* update counter value */
  memalloc_val += bytes;

  time = vt_pform_wtime();

  if ( was_recorded && bytes > 0 )
  {
    /* write marker, if desired */
    if( memalloc_marker )
    {
      vt_marker(VT_CURRENT_THREAD, &time, memalloc_mid[MEMHOOK_MARK_ALLOC],
                "Allocated %llu Bytes", (unsigned long long)bytes);
    }

    /* write counter value */
    vt_count(VT_CURRENT_THREAD, &time, memalloc_cid, memalloc_val);
  }

  vt_exit(VT_CURRENT_THREAD, &time);

  VT_MEMHOOKS_ON(); /* restore our own hooks */

  return result;
}
Пример #4
0
void vt_free_hook(void* ptr, const void* caller)
{
  uint64_t bytes;
  uint64_t time;
  uint8_t was_recorded;

  VT_MEMHOOKS_OFF(); /* restore original hooks */

  time = vt_pform_wtime();
  was_recorded = vt_enter(VT_CURRENT_THREAD, &time,
                          memhook_regid[MEMHOOK_REG_FREE]);

  if ( NULL != ptr )
  {
    bytes = ( ~ (uint64_t) 3 ) & (uint64_t) *( (size_t*) ( (char*)ptr - SIZEOF_VOIDP ) );
  }
  else
  {
    bytes = 0;
  }

  free(ptr); /* call recursively */

  /* update counter value */
  if ( bytes <= memalloc_val )
    memalloc_val -= bytes;
  else
    memalloc_val = 0;

  time = vt_pform_wtime();

  if ( was_recorded && bytes > 0 )
  {
    /* write marker, if desired */
    if( memalloc_marker )
    {
      vt_marker(VT_CURRENT_THREAD, &time, memalloc_mid[MEMHOOK_MARK_FREE],
                "Freed %llu Bytes", (unsigned long long)bytes);
    }

    /* write counter value */
    vt_count(VT_CURRENT_THREAD, &time, memalloc_cid, memalloc_val);
  }

  vt_exit(VT_CURRENT_THREAD, &time);

  VT_MEMHOOKS_ON(); /* restore our own hooks */
}
/* -- stdlib.h:realloc -- */
void* realloc(void* ptr, size_t size)
{
  void* ret;

  /* initialize this wrapper function */
  MALLOCWRAP_FUNC_INIT("realloc", void*, (void*, size_t));

  /* once, get the actual function pointer */
  MALLOCWRAP_GET_FUNC_PTR();

  if( MALLOCWRAP_DO_TRACE() )
  {
    uint32_t tid;
    uint64_t time;
    uint64_t bytes;
    uint64_t bytes1;
    uint64_t bytes2;
    uint64_t* counter_val;
    uint8_t was_recorded;

    /* get calling thread id */
    tid = VT_MY_THREAD;

    /* suspend LIBC memory (de)allocation tracing */
    VT_SUSPEND_MALLOC_TRACING(tid);

    /* get current timestamp for the following function enter event */
    time = vt_pform_wtime();

    /* once, get unique function identifier */
    MALLOCWRAP_GET_FUNC_ID();

    /* record function enter event */
    was_recorded = vt_enter(tid, &time, VT_LIBWRAP_FUNC_ID);

    /* get total allocated memory before realloc */
    if( ptr != NULL )
    {
/*      bytes1 = ( ~ (uint64_t) 3 ) & (uint64_t) *( (size_t*) ( (char*)ptr - SIZEOF_VOIDP ) );*/
      bytes1 = (uint64_t)malloc_usable_size(ptr);
    }
    else
    {
      bytes1 = bytes = 0;
    }

    /* call the actual library function */
    ret = MALLOCWRAP_FUNC_CALL((ptr, size));

    /* get total allocated memory after realloc */
    if( ret != NULL )
    {
/*      bytes2 = ( ~ (uint64_t) 3 ) & (uint64_t) *( (size_t*) ( (char*)ret - SIZEOF_VOIDP ) );*/
      bytes2 = (uint64_t)malloc_usable_size(ret);
      bytes = bytes2 < bytes1 ? bytes1 - bytes2 : bytes2 - bytes1;
    }
    else
    {
      bytes2 = bytes = 0;
    }

    /* get pointer to thread's memory allocation counter value and update */
    counter_val = &(VTTHRD_MALLOC_TRACING_COUNTER_VAL(VTThrdv[tid]));
    if( bytes2 < bytes1 )
    {
      if( bytes <= *counter_val )
        *counter_val -= bytes;
      else
        *counter_val = 0;
    }
    else
    {
      *counter_val += bytes;
    }

    /* get timestamp for the following function exit event [+ marker] */
    time = vt_pform_wtime();

    if( was_recorded && bytes > 0 )
    {
      /* write marker, if desired */
      if( mallocwrap_write_markers )
      {
        static const char* marker_prefix_alloced = "Allocated";
        static const char* marker_prefix_freed   = "Freed";

        uint32_t marker_id;
        const char* marker_prefix;

        if ( bytes2 < bytes1 )
        {
          marker_id = mallocwrap_marker_free_id;
          marker_prefix = marker_prefix_freed;
        }
        else
        {
          marker_id = mallocwrap_marker_alloc_id;
          marker_prefix = marker_prefix_alloced;
        }

        vt_marker(tid, &time, marker_id,
          "%s %llu Bytes", marker_prefix, (unsigned long long)bytes);
      }

      /* write counter value */
      vt_count(tid, &time, mallocwrap_counter_id, *counter_val);
    }

    /* record function exit event */
    vt_exit(tid, &time);

    /* resume LIBC memory (de)allocation tracing */
    VT_RESUME_MALLOC_TRACING(tid);
  }
  else
  {
    /* call the actual library function */
    ret = MALLOCWRAP_FUNC_CALL((ptr, size));
  }

  /* get errno from external LIBC (not necessary if using RTLD_NEXT) */
  /*errno = vt_libwrap_get_libc_errno();*/

  return ret;
}
/* -- stdlib.h:calloc -- */
void* calloc(size_t nmemb, size_t size)
{
  void* ret;

  /* initialize this wrapper function */
  MALLOCWRAP_FUNC_INIT("calloc", void*, (size_t, size_t));

  /* once, get the actual function pointer

     NOTE: The dlsym function which is used to determine the actual function
     pointer of calloc uses itself this function, which would ends up in an
     infinite recursion.
     In order to make it work we have to perform a quite dirty hack found on
     http://blog.bigpixel.ro/2010/09/interposing-calloc-on-linux:
     While we are trying to get the actual function pointer, we're returning
     NULL for the memory which needs to be allocated by dlsym, in hope that
     dlsym can handle this situation.
     If this workaround causes any problems, just undefine the MALLOCWRAP_CALLOC
     macro above to disable the calloc wrapper function completely. */
  if( VT_LIBWRAP_FUNC_PTR == VT_LIBWRAP_NULL )
  {
    /* flag for indicating that we are trying to get the actual function
       pointer of calloc */
    static uint8_t getting_func_ptr = 0;
    if( !getting_func_ptr )
    {
      /* before trying to get the actual function pointer of calloc, set
         an indicator in order to return NULL from the next calloc called from
         dlsym */
      getting_func_ptr = 1;
      VTLibwrap_func_init(mallocwrap_lw, VT_LIBWRAP_FUNC_NAME, NULL, 0,
        (void**)(&VT_LIBWRAP_FUNC_PTR), NULL);
      getting_func_ptr = 0;
    }
    else
    {
      /* assumed that this calloc is called from dlsym, return NULL */
      return NULL;
    }
  }

  if( MALLOCWRAP_DO_TRACE() )
  {
    uint32_t tid;
    uint64_t time;
    uint64_t bytes;
    uint64_t* counter_val;
    uint8_t was_recorded;

    /* get calling thread id */
    tid = VT_MY_THREAD;

    /* suspend LIBC memory (de)allocation tracing */
    VT_SUSPEND_MALLOC_TRACING(tid);

    /* get current timestamp for the following function enter event */
    time = vt_pform_wtime();

    /* once, get unique function identifier */
    MALLOCWRAP_GET_FUNC_ID();

    /* record function enter event */
    was_recorded = vt_enter(tid, &time, VT_LIBWRAP_FUNC_ID);

    /* call the actual library function */
    ret = MALLOCWRAP_FUNC_CALL((nmemb, size));

    /* get total allocated memory */
    if( ret != NULL )
    {
/*      bytes = ( ~ (uint64_t) 3 ) & (uint64_t) *( (size_t*) ( (char*)ret - SIZEOF_VOIDP ) );*/
      bytes = (uint64_t)malloc_usable_size(ret);
    }
    else
    {
      bytes = 0;
    }

    /* get pointer to thread's memory allocation counter value and update */
    counter_val = &(VTTHRD_MALLOC_TRACING_COUNTER_VAL(VTThrdv[tid]));
    *counter_val += bytes;

    /* get timestamp for the following function exit event [+ marker] */
    time = vt_pform_wtime();

    if( was_recorded && bytes > 0 )
    {
      /* write marker, if desired */
      if( mallocwrap_write_markers )
      {
        vt_marker(tid, &time, mallocwrap_marker_alloc_id,
          "Allocated %llu Bytes", (unsigned long long)bytes);
      }

      /* write counter value */
      vt_count(tid, &time, mallocwrap_counter_id, *counter_val);
    }

    /* record function exit event */
    vt_exit(tid, &time);

    /* resume LIBC memory (de)allocation tracing */
    VT_RESUME_MALLOC_TRACING(tid);
  }
  else
  {
    /* call the actual library function */
    ret = MALLOCWRAP_FUNC_CALL((nmemb, size));
  }

  /* get errno from external LIBC (not necessary if using RTLD_NEXT) */
  /*errno = vt_libwrap_get_libc_errno();*/

  return ret;
}
Пример #7
0
void* vt_realloc_hook(void* ptr, size_t size, const void* caller)
{
  void* result;
  uint64_t bytes;
  uint64_t bytes1;
  uint64_t bytes2;
  uint64_t time;
  uint8_t was_recorded;

  VT_MEMHOOKS_OFF(); /* restore original hooks */

  time = vt_pform_wtime();
  was_recorded = vt_enter(VT_CURRENT_THREAD, &time,
                          memhook_regid[MEMHOOK_REG_REALLOC]);

  /* get total allocated memory before realloc */
  if ( NULL != ptr )
  {
    bytes1 = ( ~ (uint64_t) 3 ) & (uint64_t) *( (size_t*) ( (char*)ptr - SIZEOF_VOIDP ) );
  }
  else
  {
    bytes1 = bytes = 0;
  }

  result = realloc(ptr, size); /* call recursively */

  /* get total allocated memory after realloc */
  if ( NULL != result )
  {
    bytes2 = ( ~ (uint64_t) 3 ) & (uint64_t) *( (size_t*) ( (char*)result - SIZEOF_VOIDP ) );
    bytes = bytes2 < bytes1 ? bytes1 - bytes2 : bytes2 - bytes1;
  }
  else
  {
    bytes2 = bytes = 0;
  }

  /* update counter value */
  if ( bytes2 < bytes1 )
  {
    if ( bytes <= memalloc_val )
      memalloc_val -= bytes;
    else
      memalloc_val = 0;
  }
  else
  {
    memalloc_val += bytes;
  }

  time = vt_pform_wtime();

  if( was_recorded && bytes > 0 )
  {
    /* write marker, if desired */
    if( memalloc_marker )
    {
      uint32_t marker_type;
      char* marker_prefix;

      if ( bytes2 < bytes1 )
      {
        marker_type = MEMHOOK_MARK_FREE;
        marker_prefix = "Freed";
      }
      else
      {
        marker_type = MEMHOOK_MARK_ALLOC;
        marker_prefix = "Allocated";
      }

      /* write marker */
      vt_marker(VT_CURRENT_THREAD, &time, memalloc_mid[marker_type],
                "%s %llu Bytes", marker_prefix, (unsigned long long)bytes);
    }

    /* write counter value */
    vt_count(VT_CURRENT_THREAD, &time, memalloc_cid, memalloc_val);
  }

  vt_exit(VT_CURRENT_THREAD, &time);

  VT_MEMHOOKS_ON(); /* restore our own hooks */

  return result;
}