mirror of
https://github.com/LIV2/libnix.git
synced 2025-12-06 00:23:08 +00:00
improved TRACK_AND_CHECK malloc.
This commit is contained in:
parent
28b91a9573
commit
82511e51d6
@ -10,15 +10,53 @@
|
||||
#include <proto/exec.h>
|
||||
#include <proto/dos.h>
|
||||
#include "stabs.h"
|
||||
#include "stdio.h"
|
||||
#include "amistdio.h"
|
||||
|
||||
#ifdef TRACK_AND_CHECK
|
||||
|
||||
int __track_max;
|
||||
long * __track;
|
||||
|
||||
void __trackMe(int no, int sz) {
|
||||
if (no >= __track_max) {
|
||||
long * t = (long *) AllocVec(__track_max * sizeof(long) * 2, MEMF_CLEAR);
|
||||
memcpy(t, __track, __track_max * sizeof(long));
|
||||
FreeVec(__track);
|
||||
__track = t;
|
||||
__track_max += __track_max;
|
||||
}
|
||||
__track[no] = sz;
|
||||
}
|
||||
|
||||
void __untrackMe(int no) {
|
||||
if (no >= __track_max) {
|
||||
printf("invalid track no %ld\n", no);
|
||||
return;
|
||||
}
|
||||
__track[no] = 0;
|
||||
}
|
||||
|
||||
void __initmalloc() {
|
||||
__track_max = 1000;
|
||||
__track = (long*)AllocVec(__track_max*sizeof(long), MEMF_CLEAR);
|
||||
}
|
||||
void __exitmalloc() {
|
||||
for (int i = 0; i < __track_max; ++i) {
|
||||
int sz = __track[i];
|
||||
if (sz)
|
||||
printf("not freed #%ld size=%ld\n", i, sz);
|
||||
}
|
||||
FreeVec(__track);
|
||||
}
|
||||
ADD2INIT(__initmalloc,-50);
|
||||
ADD2EXIT(__exitmalloc,-50);
|
||||
|
||||
#if 0
|
||||
|
||||
__attribute__((noinline)) void foo(void * p, int sz, int no, int na, int nz) {
|
||||
printf("trashed mem at %p sz=%d alloc #%d damaged: before %d, behind %d\n", p, sz, no, na, nz);
|
||||
printf("trashed mem at %08lx sz=%ld alloc #%ld damaged: before %ld, behind %ld\n", p, sz, no, na, nz);
|
||||
}
|
||||
__attribute__((noinline)) void faa(void * p) {
|
||||
printf("invalid free%p\n", p);
|
||||
printf("invalid free%08lx\n", p);
|
||||
}
|
||||
#if 0
|
||||
#define N 256
|
||||
@ -37,14 +75,16 @@ void * malloc(size_t size) {
|
||||
size = (size + 3) & ~3; // round up
|
||||
|
||||
// protect the memory
|
||||
char * const p = (char *)AllocVec(size + X + ADD + N, MEMF_PUBLIC);
|
||||
char * p = (char *)AllocVec(size + X + ADD + N, MEMF_PUBLIC);
|
||||
|
||||
char * q = p;
|
||||
// size
|
||||
*(int*)q = size;
|
||||
q += 4;
|
||||
// no
|
||||
*(int*)q = ++NO;
|
||||
int no = ++NO;
|
||||
__trackMe(no, size);
|
||||
*(int*)q = no;
|
||||
q += 4;
|
||||
// 0 1 2 3 ... 255 before
|
||||
for (int i = 0; i < N; ++i)
|
||||
@ -72,6 +112,7 @@ void free(void * _p) {
|
||||
int size = *(int*)q;
|
||||
q += 4;
|
||||
int no = *(int*)q;
|
||||
__untrackMe(no);
|
||||
q += 4;
|
||||
int bada = 0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
@ -90,6 +131,7 @@ void free(void * _p) {
|
||||
FreeVec(p);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
extern ULONG *__MEMORY_STEP;
|
||||
|
||||
@ -124,6 +166,8 @@ void *malloc(size_t size)
|
||||
size2=(size2+4095)&~4095; /* Blow up to full MMU Page */
|
||||
if((b=(struct MemHeader *)AllocMem(size2,MEMF_ANY))!=NULL)
|
||||
{
|
||||
// printf("AllocMem(%ld) -> %08lx\n", size2, b);
|
||||
|
||||
b->mh_Lower=b->mh_First=(struct MemChunk *)(b+1);
|
||||
b->mh_First->mc_Next=NULL;
|
||||
b->mh_Free=b->mh_First->mc_Bytes=size2-sizeof(struct MemHeader);
|
||||
@ -138,7 +182,7 @@ void *malloc(size_t size)
|
||||
end:
|
||||
ReleaseSemaphore(__memsema);
|
||||
|
||||
// printf("malloc %08x: %8d\n", a, size); fflush(stdout);
|
||||
// printf("malloc %08lx: %ld\n", a, size); fflush(stdout);
|
||||
|
||||
return a;
|
||||
}
|
||||
@ -158,6 +202,7 @@ void free(void *ptr) {
|
||||
for (;;) {
|
||||
if (((struct MinNode *) a)->mln_Succ == NULL) /* Is not in list ????? */
|
||||
{
|
||||
puts("OUCH!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -172,6 +217,7 @@ void free(void *ptr) {
|
||||
if (a->mh_Free == (size_t)((char *) a->mh_Upper - (char *) a->mh_Lower)) /* All free ? */
|
||||
{
|
||||
Remove(&a->mh_Node);
|
||||
// printf("FreeMem(%08lx, %ld)\n", a, (char *)a->mh_Upper-(char *)a);
|
||||
FreeMem(a, (char * )a->mh_Upper - (char * )a);
|
||||
}
|
||||
ReleaseSemaphore(__memsema);
|
||||
@ -192,8 +238,10 @@ void __initmalloc(void)
|
||||
|
||||
void __exitmalloc(void)
|
||||
{ struct MemHeader *a;
|
||||
while((a=(struct MemHeader *)RemHead((struct List *)&__memorylist))!=NULL)
|
||||
while((a=(struct MemHeader *)RemHead((struct List *)&__memorylist))!=NULL) {
|
||||
// printf("FreeMem(%08lx, %ld)\n", a, (char *)a->mh_Upper-(char *)a);
|
||||
FreeMem(a,(char *)a->mh_Upper-(char *)a); /* free all memory */
|
||||
}
|
||||
FreeMem(__memsema, sizeof(struct SignalSemaphore));
|
||||
}
|
||||
|
||||
|
||||
@ -1,150 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <clib/alib_protos.h>
|
||||
#include <proto/dos.h>
|
||||
#include <proto/exec.h>
|
||||
#include <dos/dostags.h>
|
||||
#include <exec/execbase.h>
|
||||
|
||||
#include <inline/bsdsocket.h>
|
||||
int system(const char *string) {
|
||||
if (string == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#ifndef __KICK13__
|
||||
if (((struct Library*) DOSBase)->lib_Version >= 36) {
|
||||
static struct TagItem notags[] = { { TAG_END, 0 } };
|
||||
return SystemTagList((CONST_STRPTR )string, notags);
|
||||
} else
|
||||
#endif
|
||||
return (int) ~Execute((STRPTR )string, Input(), Output());
|
||||
}
|
||||
|
||||
__attribute__((__noinline__))
|
||||
__regargs int clutch(int cmdlen, void * cmdline, __regargs int (*realProc)(int cmdlen, void * cmdline)) {
|
||||
return realProc(cmdlen, cmdline);
|
||||
}
|
||||
|
||||
static __regargs __entrypoint
|
||||
int startProc(int cmdlen, void * cmdline) {
|
||||
volatile struct ExecBase * SysBase = *(struct ExecBase **)4;
|
||||
struct Process *self = (struct Process*) SysBase->ThisTask;
|
||||
for(;;) {
|
||||
struct Message * m = GetMsg(&self->pr_MsgPort);
|
||||
if (!m)
|
||||
continue;
|
||||
self->pr_Task.tc_UserData = m;
|
||||
__regargs int (*realProc)(int cmdlen, void * cmdline) = (__regargs int (*)(int, void *))m->mn_Node.ln_Name;
|
||||
int r = clutch(cmdlen, cmdline, realProc);
|
||||
SysBase = *(struct ExecBase **)4;
|
||||
Forbid();
|
||||
self = (struct Process*) SysBase->ThisTask;
|
||||
m = (struct Message *)self->pr_Task.tc_UserData;
|
||||
m->mn_Node.ln_Name = (char *)r;
|
||||
ReplyMsg(m);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
int execvp(const char *file, char *const argv[]) {
|
||||
return execv(file, argv);
|
||||
}
|
||||
int execv(const char *path, char *const argv[]) {
|
||||
char *const*p;
|
||||
char *cmd;
|
||||
|
||||
// if (1)
|
||||
// return 0;
|
||||
|
||||
BPTR seg = LoadSeg((UBYTE * )path);
|
||||
printf("execv: %s -> %p\n", path, seg);
|
||||
if (!seg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int r, len = 1
|
||||
+ strlen(cmd)
|
||||
;
|
||||
for (p = argv; *p; ++p) {
|
||||
len += 3 + strlen(*p);
|
||||
}
|
||||
cmd = malloc(len);
|
||||
//*cmd = 0;
|
||||
strcpy(cmd, path);
|
||||
|
||||
if (*argv)
|
||||
for (p = argv+1; *p; ++p) {
|
||||
strcat(cmd, " \"");
|
||||
strcat(cmd, *p);
|
||||
strcat(cmd, "\"");
|
||||
}
|
||||
if (1) {
|
||||
int r = system(cmd);
|
||||
free(cmd);
|
||||
exit(r);
|
||||
}
|
||||
|
||||
|
||||
printf("execv: %s %s\n", path, cmd);
|
||||
|
||||
// BPTR inp = DupLock(Input());
|
||||
// BPTR out = DupLock(Output());
|
||||
BPTR stdio = Open((UBYTE* )"*", MODE_READWRITE);
|
||||
struct Process *proc = (struct Process*) CreateNewProcTags(
|
||||
NP_Entry, (ULONG) startProc,
|
||||
NP_Input, (ULONG) stdio,
|
||||
NP_Output, (ULONG) stdio,
|
||||
NP_Arguments, (ULONG) cmd,
|
||||
NP_FreeSeglist, seg,
|
||||
NP_StackSize, 100000,
|
||||
NP_Cli, 1,
|
||||
NP_Name, (ULONG )path,
|
||||
0);
|
||||
|
||||
free(cmd);
|
||||
|
||||
printf("execv: %s -> proc %p\n", path, proc);
|
||||
|
||||
struct Process *self = (struct Process*) SysBase->ThisTask;
|
||||
struct MsgPort * mp = &self->pr_MsgPort;
|
||||
struct Message msg;
|
||||
msg.mn_Node.ln_Succ = 0;
|
||||
msg.mn_Node.ln_Pred = 0;
|
||||
msg.mn_Node.ln_Type = NT_MESSAGE;
|
||||
msg.mn_Node.ln_Pri = 42;
|
||||
msg.mn_Node.ln_Name = (char *)(1 + (ULONG *) BADDR(seg)); // real program start
|
||||
msg.mn_ReplyPort = mp;
|
||||
msg.mn_Length = sizeof(struct Message);
|
||||
|
||||
PutMsg(&proc->pr_MsgPort, &msg);
|
||||
printf("execv: put msg -> %p\n", &proc->pr_MsgPort);
|
||||
for(;;) {
|
||||
WaitPort(mp);
|
||||
if (GetMsg(mp) == &msg)
|
||||
break;
|
||||
}
|
||||
int rc = (int)msg.mn_Node.ln_Name;
|
||||
printf("execv: done rc=%d\n", rc);
|
||||
exit(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
//int execvp(const char *file, char *const argv[]) {
|
||||
//}
|
||||
|
||||
int pipe(int pipefd[2]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pid_t fork(void) {
|
||||
return 0;
|
||||
}
|
||||
@ -301,7 +301,9 @@ void __exitstdio(void) {
|
||||
sfd->lx_inuse = 1; // force closing
|
||||
close(i);
|
||||
}
|
||||
// free(sfd); // freed by __exitmalloc
|
||||
}
|
||||
// free(__stdfiledes); // freed by __exitmalloc
|
||||
|
||||
if (stderrdes)
|
||||
Close(stderrdes);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user