-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f9432ea
Showing
10 changed files
with
687 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"configurations": [ | ||
{ | ||
"name": "Mac", | ||
"includePath": [ | ||
"${workspaceFolder}/**" | ||
], | ||
"defines": [], | ||
"macFrameworkPath": [ | ||
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks" | ||
], | ||
"compilerPath": "/opt/homebrew/bin/gcc", | ||
"cStandard": "c17", | ||
"cppStandard": "c++17", | ||
"intelliSenseMode": "macos-clang-arm64" | ||
} | ||
], | ||
"version": 4 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"tasks": [ | ||
{ | ||
"type": "cppbuild", | ||
"label": "C/C++: gcc kompiluj aktywny plik", | ||
"command": "/opt/homebrew/bin/gcc", | ||
"args": [ | ||
"-Wall", "-Wextra", "-Wno-implicit-fallthrough", "-std=gnu17", "-fPIC", "-O2", | ||
"${file}", | ||
"-o", | ||
"${fileDirname}/${fileBasenameNoExtension}" | ||
], | ||
"options": { | ||
"cwd": "${fileDirname}" | ||
}, | ||
"problemMatcher": [ | ||
"$gcc" | ||
], | ||
"group": { | ||
"kind": "build", | ||
"isDefault": true | ||
}, | ||
"detail": "Zadanie wygenerowane przez debuger." | ||
} | ||
], | ||
"version": "2.0.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
#ifndef _MALLOC_H | ||
#define _MALLOC_H 1 | ||
|
||
#ifdef _LIBC | ||
#include <features.h> | ||
#endif | ||
|
||
#if defined(__STDC__) || defined(__cplusplus) | ||
#include <stddef.h> | ||
#define __malloc_ptr_t void * | ||
#else | ||
#undef size_t | ||
#define size_t unsigned int | ||
#undef ptrdiff_t | ||
#define ptrdiff_t int | ||
#define __malloc_ptr_t char * | ||
#endif | ||
|
||
#ifdef _LIBC | ||
/* Used by GNU libc internals. */ | ||
#define __malloc_size_t size_t | ||
#define __malloc_ptrdiff_t ptrdiff_t | ||
#elif !defined __attribute_malloc__ | ||
#define __attribute_malloc__ | ||
#endif | ||
|
||
#ifdef __GNUC__ | ||
|
||
/* GCC can always grok prototypes. For C++ programs we add throw() | ||
to help it optimize the function calls. But this works only with | ||
gcc 2.8.x and egcs. */ | ||
#if defined __cplusplus && (__GNUC__ >= 3 || __GNUC_MINOR__ >= 8) | ||
#define __THROW throw() | ||
#else | ||
#define __THROW | ||
#endif | ||
#define __MALLOC_P(args) args __THROW | ||
/* This macro will be used for functions which might take C++ callback | ||
functions. */ | ||
#define __MALLOC_PMT(args) args | ||
|
||
#else /* Not GCC. */ | ||
|
||
#define __THROW | ||
|
||
#if (defined __STDC__ && __STDC__) || defined __cplusplus | ||
|
||
#define __MALLOC_P(args) args | ||
#define __MALLOC_PMT(args) args | ||
|
||
#else /* Not ANSI C or C++. */ | ||
|
||
#define __MALLOC_P(args) () /* No prototypes. */ | ||
#define __MALLOC_PMT(args) () | ||
|
||
#endif /* ANSI C or C++. */ | ||
|
||
#endif /* GCC. */ | ||
|
||
#ifndef NULL | ||
#ifdef __cplusplus | ||
#define NULL 0 | ||
#else | ||
#define NULL ((__malloc_ptr_t)0) | ||
#endif | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
extern "C" | ||
{ | ||
#endif | ||
|
||
/* Allocate SIZE bytes of memory. */ | ||
extern __malloc_ptr_t malloc __MALLOC_P((size_t __size)) __attribute_malloc__; | ||
|
||
/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ | ||
extern __malloc_ptr_t calloc __MALLOC_P((size_t __nmemb, size_t __size)) | ||
__attribute_malloc__; | ||
|
||
/* Re-allocate the previously allocated block in __ptr, making the new | ||
block SIZE bytes long. */ | ||
extern __malloc_ptr_t realloc __MALLOC_P((__malloc_ptr_t __ptr, | ||
size_t __size)) | ||
__attribute_malloc__; | ||
|
||
/* Free a block allocated by `malloc', `realloc' or `calloc'. */ | ||
extern void free __MALLOC_P((__malloc_ptr_t __ptr)); | ||
|
||
/* Free a block allocated by `calloc'. */ | ||
extern void cfree __MALLOC_P((__malloc_ptr_t __ptr)); | ||
|
||
/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ | ||
extern __malloc_ptr_t memalign __MALLOC_P((size_t __alignment, size_t __size)); | ||
|
||
/* Allocate SIZE bytes on a page boundary. */ | ||
extern __malloc_ptr_t valloc __MALLOC_P((size_t __size)) __attribute_malloc__; | ||
|
||
/* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up | ||
__size to nearest pagesize. */ | ||
extern __malloc_ptr_t pvalloc __MALLOC_P((size_t __size)) | ||
__attribute_malloc__; | ||
|
||
/* Underlying allocation function; successive calls should return | ||
contiguous pieces of memory. */ | ||
extern __malloc_ptr_t(*__morecore) __MALLOC_PMT((ptrdiff_t __size)); | ||
|
||
/* Default value of `__morecore'. */ | ||
extern __malloc_ptr_t __default_morecore __MALLOC_P((ptrdiff_t __size)) | ||
__attribute_malloc__; | ||
|
||
/* SVID2/XPG mallinfo structure */ | ||
|
||
struct mallinfo | ||
{ | ||
int arena; /* non-mmapped space allocated from system */ | ||
int ordblks; /* number of free chunks */ | ||
int smblks; /* number of fastbin blocks */ | ||
int hblks; /* number of mmapped regions */ | ||
int hblkhd; /* space in mmapped regions */ | ||
int usmblks; /* maximum total allocated space */ | ||
int fsmblks; /* space available in freed fastbin blocks */ | ||
int uordblks; /* total allocated space */ | ||
int fordblks; /* total free space */ | ||
int keepcost; /* top-most, releasable (via malloc_trim) space */ | ||
}; | ||
|
||
/* Returns a copy of the updated current mallinfo. */ | ||
extern struct mallinfo mallinfo __MALLOC_P((void)); | ||
|
||
/* SVID2/XPG mallopt options */ | ||
#ifndef M_MXFAST | ||
#define M_MXFAST 1 /* maximum request size for "fastbins" */ | ||
#endif | ||
#ifndef M_NLBLKS | ||
#define M_NLBLKS 2 /* UNUSED in this malloc */ | ||
#endif | ||
#ifndef M_GRAIN | ||
#define M_GRAIN 3 /* UNUSED in this malloc */ | ||
#endif | ||
#ifndef M_KEEP | ||
#define M_KEEP 4 /* UNUSED in this malloc */ | ||
#endif | ||
|
||
/* mallopt options that actually do something */ | ||
#define M_TRIM_THRESHOLD -1 | ||
#define M_TOP_PAD -2 | ||
#define M_MMAP_THRESHOLD -3 | ||
#define M_MMAP_MAX -4 | ||
#define M_CHECK_ACTION -5 | ||
|
||
/* General SVID/XPG interface to tunable parameters. */ | ||
extern int mallopt __MALLOC_P((int __param, int __val)); | ||
|
||
/* Release all but __pad bytes of freed top-most memory back to the | ||
system. Return 1 if successful, else 0. */ | ||
extern int malloc_trim __MALLOC_P((size_t __pad)); | ||
|
||
/* Report the number of usable allocated bytes associated with allocated | ||
chunk __ptr. */ | ||
extern size_t malloc_usable_size __MALLOC_P((__malloc_ptr_t __ptr)); | ||
|
||
/* Prints brief summary statistics on stderr. */ | ||
extern void malloc_stats __MALLOC_P((void)); | ||
|
||
/* Record the state of all malloc variables in an opaque data structure. */ | ||
extern __malloc_ptr_t malloc_get_state __MALLOC_P((void)); | ||
|
||
/* Restore the state of all malloc variables from data obtained with | ||
malloc_get_state(). */ | ||
extern int malloc_set_state __MALLOC_P((__malloc_ptr_t __ptr)); | ||
|
||
/* Called once when malloc is initialized; redefining this variable in | ||
the application provides the preferred way to set up the hook | ||
pointers. */ | ||
extern void(*__malloc_initialize_hook) __MALLOC_PMT((void)); | ||
/* Hooks for debugging and user-defined versions. */ | ||
extern void(*__free_hook) __MALLOC_PMT((__malloc_ptr_t __ptr, | ||
__const __malloc_ptr_t)); | ||
extern __malloc_ptr_t(*__malloc_hook) __MALLOC_PMT((size_t __size, | ||
__const __malloc_ptr_t)); | ||
extern __malloc_ptr_t(*__realloc_hook) __MALLOC_PMT((__malloc_ptr_t __ptr, | ||
size_t __size, | ||
__const __malloc_ptr_t)); | ||
extern __malloc_ptr_t(*__memalign_hook) __MALLOC_PMT((size_t __alignment, | ||
size_t __size, | ||
__const __malloc_ptr_t)); | ||
extern void(*__after_morecore_hook) __MALLOC_PMT((void)); | ||
|
||
/* Activate a standard set of debugging hooks. */ | ||
extern void __malloc_check_init __MALLOC_P((void)); | ||
|
||
#ifdef __cplusplus | ||
}; /* end of extern "C" */ | ||
#endif | ||
|
||
#endif /* malloc.h */ |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#include "memory_tests.h" | ||
#include <errno.h> | ||
#include "malloc.h" | ||
#include <stdbool.h> | ||
#include <stddef.h> | ||
|
||
// Ten plik musi kompilowany z opcjami -std=gnu17 i -fPIC, | ||
// a linkowany z opcjami -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=realloc | ||
// -Wl,--wrap=reallocarray -Wl,--wrap=free -Wl,--wrap=strdup -Wl,--wrap=strndup. | ||
|
||
// Przechwytujemy funkcje alokujące i zwalniające pamięć. | ||
void *__real_malloc(size_t size) __attribute__((weak)); | ||
void *__real_calloc(size_t nmemb, size_t size) __attribute__((weak)); | ||
void *__real_realloc(void *ptr, size_t size) __attribute__((weak)); | ||
void *__real_reallocarray(void *ptr, size_t nmemb, size_t size) __attribute__((weak)); | ||
char *__real_strdup(const char *s) __attribute__((weak)); | ||
char *__real_strndup(const char *s, size_t size) __attribute__((weak)); | ||
void __real_free(void *ptr) __attribute__((weak)); | ||
|
||
// Trzymamy globalnie informacje o alokacjach i zwolnieniach pamięci. | ||
static memory_test_data_t test_data; | ||
|
||
// To jest prosty akcesor potrzebny do testowania. | ||
memory_test_data_t *get_memory_test_data(void) | ||
{ | ||
return &test_data; | ||
} | ||
|
||
// To jest prosty akcesor potrzebny do testowania. | ||
char const *get_magic_string(void) | ||
{ | ||
static char const *magic = "quite long magic string"; | ||
return magic; | ||
} | ||
|
||
// W zadanym momencie alokacja pamięci zawodzi. | ||
static bool should_fail(void) | ||
{ | ||
return ++test_data.call_counter == test_data.fail_counter; | ||
} | ||
|
||
// Realokacja musi się udać, jeśli nie zwiększamy rozmiaru alokowanej pamięci. | ||
static bool can_fail(void const *old_ptr, size_t new_size) | ||
{ | ||
if (old_ptr == NULL) | ||
return true; | ||
else | ||
return new_size > malloc_usable_size((void *)old_ptr); | ||
} | ||
|
||
// Symulujemy brak pamięci. | ||
#define UNRELIABLE_ALLOC(ptr, size, fun, name) \ | ||
do \ | ||
{ \ | ||
test_data.call_total++; \ | ||
if (ptr != NULL && size == 0) \ | ||
{ \ | ||
/* Takie wywołanie realloc jest równoważne wywołaniu free(ptr). */ \ | ||
test_data.free_counter++; \ | ||
return fun; \ | ||
} \ | ||
void *p = can_fail(ptr, size) && should_fail() ? NULL : (fun); \ | ||
if (p) \ | ||
{ \ | ||
test_data.alloc_counter += ptr != p; \ | ||
test_data.free_counter += ptr != p && ptr != NULL; \ | ||
} \ | ||
else \ | ||
{ \ | ||
errno = ENOMEM; \ | ||
test_data.function_name = name; \ | ||
} \ | ||
return p; \ | ||
} while (0) | ||
|
||
void *__wrap_malloc(size_t size) | ||
{ | ||
UNRELIABLE_ALLOC(NULL, size, __real_malloc(size), "malloc"); | ||
} | ||
|
||
void *__wrap_calloc(size_t nmemb, size_t size) | ||
{ | ||
UNRELIABLE_ALLOC(NULL, nmemb * size, __real_calloc(nmemb, size), "calloc"); | ||
} | ||
|
||
void *__wrap_realloc(void *ptr, size_t size) | ||
{ | ||
UNRELIABLE_ALLOC(ptr, size, __real_realloc(ptr, size), "realloc"); | ||
} | ||
|
||
void *__wrap_reallocarray(void *ptr, size_t nmemb, size_t size) | ||
{ | ||
UNRELIABLE_ALLOC(ptr, nmemb * size, __real_reallocarray(ptr, nmemb, size), "reallocarray"); | ||
} | ||
|
||
char *__wrap_strdup(const char *s) | ||
{ | ||
UNRELIABLE_ALLOC(NULL, 0, __real_strdup(s), "strdup"); | ||
} | ||
|
||
char *__wrap_strndup(const char *s, size_t size) | ||
{ | ||
UNRELIABLE_ALLOC(NULL, 0, __real_strndup(s, size), "strndup"); | ||
} | ||
|
||
// Zwalnianie pamięci zawsze się udaje. Odnotowujemy jedynie fakt zwolnienia. | ||
void __wrap_free(void *ptr) | ||
{ | ||
test_data.call_total++; | ||
__real_free(ptr); | ||
if (ptr) | ||
test_data.free_counter++; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#ifndef MEMORY_TESTS_H | ||
#define MEMORY_TESTS_H | ||
|
||
// To jest struktura przechowująca informacje o operacjach na pamięci. | ||
// Nie pozwalamy kompilatorowi optymalizować operacji na tych wartościach. | ||
typedef struct { | ||
volatile unsigned call_total; // licznik wszystkich wywołań funkcji | ||
volatile unsigned call_counter; // licznik wywołań alokacji | ||
volatile unsigned fail_counter; // numer błędnej alokacji | ||
volatile unsigned alloc_counter; // liczba wykonanych alokacji | ||
volatile unsigned free_counter; // liczba wykonanych zwolnień | ||
volatile char *function_name; // nazwa nieudanej funkcji | ||
} memory_test_data_t; | ||
|
||
// Zapewnia dostęp do wyżej zdefiniowanej struktury. | ||
memory_test_data_t * get_memory_test_data(void); | ||
|
||
// Daje wskaźnik na unikalny napis. | ||
char const * get_magic_string(void); | ||
|
||
#endif |
Oops, something went wrong.