forked from KolibriOS/kolibrios
libc.obj: add malloc test && use SHELL in system && direct call exit in crt0.asm
This commit is contained in:
Binary file not shown.
@@ -28,7 +28,8 @@ BIN = \
|
||||
pipe.kex \
|
||||
defgen.kex \
|
||||
futex.kex \
|
||||
atexit_test.kex
|
||||
atexit_test.kex \
|
||||
malloc_test.kex
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
|
||||
117
programs/develop/ktcc/trunk/libc.obj/samples/malloc_test.c
Normal file
117
programs/develop/ktcc/trunk/libc.obj/samples/malloc_test.c
Normal file
@@ -0,0 +1,117 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "../source/stdlib/_mem.h"
|
||||
|
||||
#define RUN_TEST(func) \
|
||||
do { \
|
||||
printf("---\tRUN TEST: %s\t---\n", #func); \
|
||||
if (func()) { \
|
||||
printf("[SUCCESS]\tTest %s is ok.\n\n", #func); \
|
||||
} else { \
|
||||
printf("[FAIL]\tTest %s failed.\n\n", #func); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// c behind a and b
|
||||
#define IN_RANGE(a, b, c) (a > c && c > b)
|
||||
|
||||
bool test_malloc_basic_allocation()
|
||||
{
|
||||
return malloc(sizeof(int));
|
||||
}
|
||||
bool test_malloc_zero_bytes()
|
||||
{
|
||||
return malloc(0) == NULL;
|
||||
}
|
||||
|
||||
bool test_malloc_multiple_allocations()
|
||||
{
|
||||
void* ptr[1024];
|
||||
|
||||
for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) {
|
||||
ptr[i] = malloc(i);
|
||||
if (ptr[i] == NULL) {
|
||||
printf("fail alloc %d bytes\n", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) {
|
||||
for (int j = i + 1; j < sizeof(ptr) / sizeof(*ptr) - i - 1; j++) {
|
||||
if (ptr[i] == ptr[j]) {
|
||||
printf("ptrs[%d] == ptrs[%d].\n", i, j);
|
||||
return false;
|
||||
} else if (IN_RANGE(
|
||||
GET_MEM_NODE_HEADER(ptr[i])->size + (char*)GET_MEM_NODE_HEADER(ptr[i]),
|
||||
(char*)ptr[i],
|
||||
(char*)GET_MEM_NODE_HEADER(ptr[j]))) {
|
||||
printf("node %p in node %p", GET_MEM_NODE_HEADER(ptr[i]), GET_MEM_NODE_HEADER(ptr[j]));
|
||||
// additional info
|
||||
printf("node %p\nsize:%p\nfree:%p\nnext: %p\nlast: %p\n", GET_MEM_NODE_HEADER(ptr[i]), GET_MEM_NODE_HEADER(ptr[i])->size, GET_MEM_NODE_HEADER(ptr[i])->free, GET_MEM_NODE_HEADER(ptr[i])->next, GET_MEM_NODE_HEADER(ptr[i])->last);
|
||||
printf("node %p\nsize:%p\nfree:%p\nnext: %p\nlast: %p\n", GET_MEM_NODE_HEADER(ptr[j]), GET_MEM_NODE_HEADER(ptr[j])->size, GET_MEM_NODE_HEADER(ptr[j])->free, GET_MEM_NODE_HEADER(ptr[j])->next, GET_MEM_NODE_HEADER(ptr[j])->last);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool test_malloc_data_integrity()
|
||||
{
|
||||
char* A = (char*)malloc(10);
|
||||
char* B = (char*)malloc(10);
|
||||
char* C = (char*)malloc(10);
|
||||
|
||||
if (!A || !B || !C) {
|
||||
printf("can't alloc\n");
|
||||
free(A);
|
||||
free(B);
|
||||
free(C);
|
||||
return false;
|
||||
}
|
||||
|
||||
strcpy(A, "AAA");
|
||||
strcpy(C, "CCC");
|
||||
|
||||
free(B);
|
||||
|
||||
if (strcmp(A, "AAA") != 0) {
|
||||
printf("A data is broken after free(B). A = '%s'\n", A);
|
||||
free(A);
|
||||
free(C);
|
||||
return false;
|
||||
}
|
||||
if (strcmp(C, "CCC") != 0) {
|
||||
printf("C data is broken after free(B). C = '%s'\n", C);
|
||||
free(A);
|
||||
free(C);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(A);
|
||||
free(C);
|
||||
return true;
|
||||
}
|
||||
bool test_malloc_large_allocation()
|
||||
{
|
||||
return malloc(1024 * 1024 * 8); // alloc 4mb
|
||||
}
|
||||
bool test_malloc_allocation_and_free()
|
||||
{
|
||||
free(malloc(sizeof(int)));
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
RUN_TEST(test_malloc_basic_allocation);
|
||||
RUN_TEST(test_malloc_zero_bytes);
|
||||
RUN_TEST(test_malloc_multiple_allocations);
|
||||
RUN_TEST(test_malloc_data_integrity);
|
||||
RUN_TEST(test_malloc_large_allocation);
|
||||
RUN_TEST(test_malloc_basic_allocation);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -53,11 +53,5 @@ tup.rule("libc.o", "objconv -fcoff32 %f %o " .. tup.getconfig("KPACK_CMD"), "%B.
|
||||
CRT0_ASM_SRC = AddPrefix("crt/", {
|
||||
"crt0.asm",
|
||||
})
|
||||
CRT_C_SRC = AddPrefix("crt/", {
|
||||
"crt_exit.c",
|
||||
})
|
||||
|
||||
tup.rule(CRT0_ASM_SRC, "fasm %f %o", "%B.obj")
|
||||
tup.rule(CRT_C_SRC, CC .. " -c -nostdinc -nostdlib" .. " -I../include" .. " %f -o %o", "%B.o")
|
||||
|
||||
tup.rule({ "crt0.obj", "crt_exit.o" }, "ld -r %f -o %o -m elf_i386", "crt0.o")
|
||||
tup.rule(CRT0_ASM_SRC, "fasm %f %o", "%B.o")
|
||||
|
||||
@@ -14,7 +14,7 @@ public start
|
||||
public start as '_start'
|
||||
|
||||
extrn main
|
||||
extrn crt_exit
|
||||
extrn exit
|
||||
|
||||
include '../../../../../../proc32.inc'
|
||||
include '../../../../../../macros.inc'
|
||||
@@ -88,7 +88,7 @@ start:
|
||||
call main
|
||||
.exit:
|
||||
push eax
|
||||
call crt_exit
|
||||
call dword [exit]
|
||||
dd -1
|
||||
.crash:
|
||||
jmp .exit
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
void crt_exit(int status)
|
||||
{
|
||||
exit(status);
|
||||
}
|
||||
@@ -89,7 +89,7 @@
|
||||
#include "stdlib/atol.c"
|
||||
#include "stdlib/atoll.c"
|
||||
#include "stdlib/calloc.c"
|
||||
#include "stdlib/atexit.c" // должно быть до exit.c
|
||||
#include "stdlib/atexit.c" // must be before exit.c
|
||||
#include "stdlib/_exit.c"
|
||||
#include "stdlib/exit.c"
|
||||
#include "stdlib/free.c"
|
||||
|
||||
@@ -2,51 +2,15 @@
|
||||
#include <string.h>
|
||||
#include <sys/ksys.h>
|
||||
|
||||
static int __system_parse_command(const char* command, char** path, char** args)
|
||||
{
|
||||
if (command == NULL || path == NULL || args == NULL) {
|
||||
return -1;
|
||||
}
|
||||
const char* space = strchr(command, ' ');
|
||||
if (space == NULL) {
|
||||
*path = strdup(command);
|
||||
if (*path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*args = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t path_len = space - command;
|
||||
*path = (char*)malloc(path_len + 1);
|
||||
if (*path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
strncpy(*path, command, path_len);
|
||||
(*path)[path_len] = '\0';
|
||||
|
||||
size_t args_len = strlen(space) + 1;
|
||||
*args = (char*)malloc(args_len + 1);
|
||||
if (*args == NULL) {
|
||||
free(*path);
|
||||
return -1;
|
||||
}
|
||||
strcpy(*args, space);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int system(const char* command)
|
||||
{
|
||||
if (command == NULL || *command == '\0')
|
||||
return 1;
|
||||
char* cmd;
|
||||
char* args;
|
||||
|
||||
int ret = _ksys_exec(cmd, args);
|
||||
int ret = _ksys_exec("/sys/SHELL", (char*)command);
|
||||
|
||||
free(cmd);
|
||||
free(args);
|
||||
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user