Example #1
0
void* operator new (std::size_t len) throw(std::bad_alloc)
{
  void* data = nullptr;

  if (enable_buffer_protection) {
    // Allocate requested memory + enough to fit checksum at start and end
    data = malloc(len + sizeof(buffer_protection_checksum) * 2);

    // Write checksums
    auto* temp = reinterpret_cast<char*>(data);
    memcpy(temp,
           &buffer_protection_checksum,
           sizeof(buffer_protection_checksum));

    memcpy(temp + sizeof(buffer_protection_checksum) + len,
           &buffer_protection_checksum,
           sizeof(buffer_protection_checksum));

  } else {
    data = malloc(len);
  }

  if (enable_debugging_verbose) {
    DPRINTF("malloc(%llu bytes) == %p\n", (unsigned long long) len, data);
    safe_print_symbol(1, __builtin_return_address(0));
    safe_print_symbol(2, __builtin_return_address(1));
  }

  if (UNLIKELY(!data)) {
      print_backtrace();
      DPRINTF("malloc(%llu bytes): FAILED\n", (unsigned long long) len);
      throw std::bad_alloc();
  }

  if (enable_debugging) {
    if (!free_allocs.empty()) {
      auto* x = free_allocs.pop();
      new(x) allocation((char*) data, len,
                        __builtin_return_address(0),
                        __builtin_return_address(1),
                        __builtin_return_address(2));
    } else if (!allocs.free_capacity()) {
      DPRINTF("[WARNING] Internal fixed vectors are FULL, expect bogus double free messages\n");
    } else {
      allocs.emplace((char*) data, len,
                      __builtin_return_address(0),
                      __builtin_return_address(1),
                      __builtin_return_address(2));
    }
  }

  if (enable_buffer_protection) {
    // We need to return a pointer to the allocated memory + 4
    // e.g. after our first checksum
    return reinterpret_cast<void*>(reinterpret_cast<char*>(data) +
                                   sizeof(buffer_protection_checksum));
  } else {
    return data;
  }
}
Example #2
0
void print_heap_allocations(heap_print_func func)
{
  DPRINTF("Listing %u allocations...\n", allocs.size());
  for (auto& x : allocs) {
    if (x.addr != nullptr && func(x.addr, x.len)) {
      // entry
      DPRINTF("[%p] %llu bytes\n", x.addr, (unsigned long long) x.len);
      // backtrace
      safe_print_symbol(1, x.level1);
      safe_print_symbol(2, x.level2);
      safe_print_symbol(3, x.level3);
    }
  }
}
Example #3
0
  void add(void* ra)
  {
    // need free space to take more samples
    if (samplerq->free_capacity())
        samplerq->add((uintptr_t) ra);

    // return when its not our turn
    if (lockless) return;

    // transfer all the built up samplings
    transferq->copy(samplerq->first(), samplerq->size());
    samplerq->clear();
    lockless = 1;
  }
Example #4
0
fixedvector<T,kmax>::fixedvector(const fixedvector<T,kmax>& rhs)
	: misize( rhs.size() )
{
	for(u32 i = 0; i < size(); ++i)
		mArray[i] = rhs.mArray[i];
}
Example #5
0
int _get_heap_debugging_buffers_total()
{
  return allocs.capacity();
}
Example #6
0
int _get_heap_debugging_buffers_usage()
{
  return allocs.size();
}
Example #7
0
inline static void deleted_ptr(void* ptr)
{
  if (enable_buffer_protection) {
    // Calculate where the real allocation starts (at our first checksum)
    ptr = reinterpret_cast<void*>(reinterpret_cast<char*>(ptr) -
                                  sizeof(buffer_protection_checksum));
  }

  if (enable_debugging) {
    auto* x = find_alloc((char*) ptr);
    if (x == nullptr) {
      if (ptr < heap_begin || ptr > heap_end) {
          DPRINTF("[ERROR] Free on invalid non-heap address: %p\n", ptr);
      } else {
          DPRINTF("[ERROR] Possible double free on address: %p\n", ptr);
      }
      print_backtrace();
      return;
    }
    else if (x->addr == ptr) {
      if (enable_debugging_verbose) {
        DPRINTF("free(%p) == %llu bytes\n", x->addr, (unsigned long long) x->len);
        safe_print_symbol(1, __builtin_return_address(1));
        safe_print_symbol(2, __builtin_return_address(2));
      }

      // This is the only place where we can verify the buffer protection
      // checksums, since we need to know the length of the allocation
      if (enable_buffer_protection)
      {
        auto* temp = reinterpret_cast<char*>(ptr);
        auto underflow = memcmp(temp,
                                &buffer_protection_checksum,
                                sizeof(buffer_protection_checksum));
        auto overflow = memcmp(temp + sizeof(buffer_protection_checksum) + x->len,
                               &buffer_protection_checksum,
                               sizeof(buffer_protection_checksum));

        if (underflow)
        {
          DPRINTF("[ERROR] Buffer underflow found on address: %p\n", ptr);
          // TODO: print stacktrace
        }

        if (overflow)
        {
          DPRINTF("[ERROR] Buffer overflow found on address: %p\n", ptr);
          // TODO: print stacktrace
        }
      }

      // perfect match
      x->addr = nullptr;
      x->len  = 0;
      free_allocs.add(x);
    }
    else if (x->addr != ptr) {
      DPRINTF("[ERROR] Free on misaligned address: %p inside %p:%llu",
             ptr, x->addr, (unsigned long long) x->len);
      print_backtrace();
      return;
    }
  }
  free(ptr);
}