mirror of
https://github.com/google/pebble.git
synced 2025-06-21 00:30:36 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
238
tests/fakes/fake_pbl_malloc.h
Normal file
238
tests/fakes/fake_pbl_malloc.h
Normal file
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <util/heap.h>
|
||||
#include "util/list.h"
|
||||
#include "util/math.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
ListNode list_node;
|
||||
size_t bytes;
|
||||
void *ptr;
|
||||
void *lr;
|
||||
} PointerListNode;
|
||||
|
||||
static PointerListNode *s_pointer_list = NULL;
|
||||
|
||||
static bool prv_pointer_list_filter(ListNode *node, void *ptr) {
|
||||
return ((PointerListNode *)node)->ptr == ptr;
|
||||
}
|
||||
|
||||
static void prv_pointer_list_add(void *ptr, size_t bytes, void *lr) {
|
||||
PointerListNode *node = malloc(sizeof(PointerListNode));
|
||||
list_init(&node->list_node);
|
||||
node->ptr = ptr;
|
||||
node->bytes = bytes;
|
||||
node->lr = lr;
|
||||
s_pointer_list = (PointerListNode *)list_prepend((ListNode *)s_pointer_list, &node->list_node);
|
||||
}
|
||||
|
||||
static void prv_pointer_list_remove(void *ptr) {
|
||||
ListNode *node = list_find((ListNode *)s_pointer_list, prv_pointer_list_filter, ptr);
|
||||
if (!node && ptr) {
|
||||
printf("*** INVALID FREE: %p\n", ptr);
|
||||
cl_fail("Pointer has not been alloc'd (maybe a double free?)");
|
||||
}
|
||||
|
||||
list_remove(node, (ListNode **)&s_pointer_list, NULL);
|
||||
free(node);
|
||||
}
|
||||
|
||||
static size_t s_max_size_allowed = ~0;
|
||||
|
||||
static Heap s_heap;
|
||||
Heap *task_heap_get_for_current_task(void) {
|
||||
return &s_heap;
|
||||
}
|
||||
|
||||
static void *malloc_and_track(size_t bytes, void *lr) {
|
||||
if (bytes >= s_max_size_allowed) {
|
||||
return NULL;
|
||||
}
|
||||
void *rt = malloc(bytes);
|
||||
prv_pointer_list_add(rt, bytes, lr);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static void *calloc_and_track(int n, size_t bytes, void *lr) {
|
||||
if ((bytes * n) >= s_max_size_allowed) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *rt = calloc(n, bytes);
|
||||
prv_pointer_list_add(rt, bytes, lr);
|
||||
return rt;
|
||||
}
|
||||
|
||||
void fake_malloc_set_largest_free_block(size_t bytes) {
|
||||
s_max_size_allowed = bytes;
|
||||
}
|
||||
|
||||
static void free_and_track(void *ptr) {
|
||||
prv_pointer_list_remove(ptr);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void *realloc_and_track(void *ptr, size_t bytes, void *lr) {
|
||||
void *new_ptr = malloc_and_track(bytes, lr);
|
||||
if (new_ptr && ptr) {
|
||||
ListNode *node = list_find((ListNode *)s_pointer_list, prv_pointer_list_filter, ptr);
|
||||
cl_assert(node);
|
||||
memcpy(new_ptr, ptr, MIN(((PointerListNode*)node)->bytes, bytes));
|
||||
free_and_track(ptr);
|
||||
}
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
int fake_pbl_malloc_num_net_allocs(void) {
|
||||
return list_count((ListNode *)s_pointer_list);
|
||||
}
|
||||
|
||||
void fake_pbl_malloc_check_net_allocs(void) {
|
||||
if (fake_pbl_malloc_num_net_allocs() > 0) {
|
||||
ListNode *node = (ListNode *)s_pointer_list;
|
||||
while (node) {
|
||||
PointerListNode *ptr_node = (PointerListNode *)node;
|
||||
printf("Still allocated: %p (%zu bytes, lr %p)\n",
|
||||
ptr_node->ptr, ptr_node->bytes, ptr_node->lr);
|
||||
node = list_get_next(node);
|
||||
}
|
||||
}
|
||||
cl_assert_equal_i(fake_pbl_malloc_num_net_allocs(), 0);
|
||||
}
|
||||
|
||||
void fake_pbl_malloc_clear_tracking(void) {
|
||||
while (s_pointer_list) {
|
||||
ListNode *new_head = list_pop_head((ListNode *)s_pointer_list);
|
||||
free(s_pointer_list);
|
||||
s_pointer_list = (PointerListNode *)new_head;
|
||||
}
|
||||
s_max_size_allowed = ~0;
|
||||
}
|
||||
|
||||
void *task_malloc(size_t bytes) {
|
||||
return malloc_and_track(bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void *task_malloc_check(size_t bytes) {
|
||||
return malloc_and_track(bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void *task_realloc(void *ptr, size_t bytes) {
|
||||
return realloc_and_track(ptr, bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void *task_zalloc(size_t bytes) {
|
||||
void *ptr = task_malloc(bytes);
|
||||
if (ptr) {
|
||||
memset(ptr, 0, bytes);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *task_zalloc_check(size_t bytes) {
|
||||
void *ptr = task_malloc_check(bytes);
|
||||
memset(ptr, 0, bytes);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *task_calloc(size_t count, size_t size) {
|
||||
return calloc_and_track(count, size, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void *task_calloc_check(size_t count, size_t size) {
|
||||
return calloc_and_track(count, size, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void task_free(void *ptr) {
|
||||
free_and_track(ptr);
|
||||
}
|
||||
|
||||
void *applib_zalloc(size_t bytes) {
|
||||
return calloc_and_track(1, bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void applib_free(void *ptr) {
|
||||
free_and_track(ptr);
|
||||
}
|
||||
|
||||
void *app_malloc(size_t bytes) {
|
||||
return malloc_and_track(bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void *app_malloc_check(size_t bytes) {
|
||||
return malloc_and_track(bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void app_free(void *ptr) {
|
||||
free_and_track(ptr);
|
||||
}
|
||||
|
||||
void *kernel_malloc(size_t bytes) {
|
||||
return malloc_and_track(bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void *kernel_zalloc(size_t bytes) {
|
||||
return calloc_and_track(1, bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void *kernel_zalloc_check(size_t bytes) {
|
||||
return kernel_zalloc(bytes);
|
||||
}
|
||||
|
||||
void *kernel_malloc_check(size_t bytes) {
|
||||
return malloc_and_track(bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void *kernel_realloc(void *ptr, size_t bytes) {
|
||||
return realloc_and_track(ptr, bytes, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
void kernel_free(void *ptr) {
|
||||
free_and_track(ptr);
|
||||
}
|
||||
|
||||
void* kernel_calloc(size_t count, size_t size) {
|
||||
return calloc_and_track(count, size, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
char* kernel_strdup(const char* s) {
|
||||
char *r = malloc_and_track(strlen(s) + 1, __builtin_return_address(0));
|
||||
if (!r) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(r, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
char* kernel_strdup_check(const char* s) {
|
||||
return kernel_strdup(s);
|
||||
}
|
||||
|
||||
char* task_strdup(const char* s) {
|
||||
return kernel_strdup(s);
|
||||
}
|
||||
|
||||
void smart_free(void *ptr) {
|
||||
free_and_track(ptr);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue