初步实现异常捕获机制

This commit is contained in:
ranchuan
2024-06-18 19:37:43 +08:00
commit 9ac75c09ac
13 changed files with 788 additions and 0 deletions

97
soft/exception.c Normal file
View File

@@ -0,0 +1,97 @@
#include "setjmp.h"
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "string.h"
#include "stdarg.h"
#include "exception.h"
#include "mystdlib.h"
exception_def *exception(){
static exception_def frame={0};
return &frame;
}
void __throw(char *file,int line,const char *fmt,...){
exception_def *f=exception();
jmp_fram *h=f->jmp_head;
char *buff=0;
int length=0;
va_list args;
f->file=file;
f->line=line;
buff=f->log;
va_start(args, fmt);
length += vsnprintf(buff + length, THROW_LOG__MAX_SIZE - length - 1, fmt, args);
va_end(args);
longjmp((h->fram),1);
}
char *err_(){
exception_def *f=exception();
return f->log;
}
char *file_(){
exception_def *f=exception();
return f->file;
}
int line_(){
exception_def *f=exception();
return f->line;
}
void func_two();
int test_add(int a, int b)
{
printf("setjmp test.\n");
try_{
printf("first enter setjmp.\n");
try_{
printf("try in try.\n");
func_two();
// throw_("throw two err.");
}catch_{
printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
}
throw_("throw a err.");
}catch_{
printf("sssss\n");
printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
try_{
printf("try in catch.\n");
func_two();
// throw_("throw two err.");
}catch_{
printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
}
}
printf("setjmp end.\n");
return 0;
}
void func_two(){
printf("in func:%s\n",__func__);
void *p=mem_malloc(512);
throw_("throw in func_two. in func:%s",__func__);
mem_free(p);
}

104
soft/exception.h Normal file
View File

@@ -0,0 +1,104 @@
#ifndef exception_h__
#define exception_h__
#include "setjmp.h"
#include "mystdlib.h"
#define THROW_LOG__MAX_SIZE 1024
typedef struct _jmp_fram{
struct _jmp_fram *next;
struct _jmp_fram *last;
map_def *mem;
jmp_buf fram;
}jmp_fram;
typedef struct{
size_t jmp_num;
jmp_fram *jmp_head;
int ret;
char *file;
int line;
char log[THROW_LOG__MAX_SIZE];
}exception_def;
#define jmp_next(j) {\
if((*j)){\
(*j)->next=calloc(sizeof(jmp_fram),1);\
(*j)->next->last=(*j);\
(*j)=(*j)->next;\
}else{\
(*j)=calloc(sizeof(jmp_fram),1);\
}\
}
#define jmp_last(j) {\
if((*j)){\
jmp_fram *l=(*j)->last;\
if(l){\
__mem_mov(&(l)->mem,&(*j)->mem);\
}\
free(*j);\
(*j)=l;\
if(*j){\
(*j)->next=0;\
}\
}\
}
#define jmp_clear(j) {\
if((*j)){\
jmp_fram *l=(*j)->last;\
__mem_clear(&(*j)->mem);\
free(*j);\
(*j)=l;\
if(*j){\
(*j)->next=0;\
}\
}\
}
#define __try(){\
exception_def *f=exception();\
jmp_fram **h=&f->jmp_head;\
int ret;\
jmp_next(h);\
ret= setjmp(((*h)->fram));\
if(ret){\
jmp_clear(h);\
}\
f->ret=ret;\
}
#define try_ __try();if(exception()->ret==0){
#define catch_ {\
exception_def *f=exception();\
jmp_fram **h=&f->jmp_head;\
jmp_last(h);\
}}else
#define throw_(fmt,...) __throw(__FILE__,__LINE__,fmt,##__VA_ARGS__)
exception_def *exception();
void __throw(char *file,int line,const char *fmt,...);
int test_add(int a,int b);
#endif

107
soft/mystdlib.c Normal file
View File

@@ -0,0 +1,107 @@
#include "mystdlib.h"
#include "string.h"
#include "exception.h"
#include "stdio.h"
static void __mem_append_m(map_def **m,void *p);
void __mem_clear(map_def **m){
if(!(*m)){
return;
}
size_t *map=(*m)->mem_map;
size_t size=(*m)->map_size;
for(size_t i=0;i<size;i++){
if(map[i]){
free((void *)map[i]);
printf("clear eme_p=%08lx\n",map[i]);
}
}
free(*m);
*m=0;
}
void __mem_mov(map_def **d,map_def **s){
if(!(*s)){
return;
}
size_t *map=(*s)->mem_map;
for(size_t i=0;i<(*s)->map_size;i++){
if(map[i]){
__mem_append_m(d,(void *)map[i]);
}
}
free(*s);
(*s)=0;
printf("mem mov end.\n");
}
void mem_free(void *p){
exception_def *th=exception();
map_def **m=&th->jmp_head->mem;
if(*m){
for(size_t i=0;i<(*m)->map_size;i++){
if((*m)->mem_map[i]==(size_t)p){
(*m)->mem_map[i]=0;
printf("free eme_p=%08lx\n",(size_t)p);
(*m)->mam_used--;
break;
}
}
}
free(p);
}
static void __mem_append_m(map_def **m,void *p){
if(!(*m)){
(*m)=calloc(sizeof(map_def)+MAP_SIZE_STEP*sizeof(size_t),1);
(*m)->map_size=MAP_SIZE_STEP;
}
if((*m)->mam_used>=(*m)->map_size){
map_def *mt=*m;
*m=calloc(sizeof(map_def)+((*m)->map_size+ MAP_SIZE_STEP)*sizeof(size_t),1);
(*m)->mam_used=mt->mam_used;
(*m)->map_size=mt->map_size+MAP_SIZE_STEP;
memcpy((*m)->mem_map,mt->mem_map,mt->map_size*sizeof(size_t));
free(mt);
}
if((*m)->mam_used<(*m)->map_size){
for(size_t i=0;i<(*m)->map_size;i++){
if((*m)->mem_map[i]==0){
(*m)->mem_map[i]=(size_t)p;
printf("append eme_p=%08lx\n",(size_t)p);
(*m)->mam_used++;
break;
}
}
}
}
static void __mem_append(void *p){
exception_def *th=exception();
map_def **m=&th->jmp_head->mem;
__mem_append_m(m,p);
}
void *mem_malloc(size_t size){
void *p=malloc(size);
__mem_append(p);
return p;
}
void *mem_calloc(size_t memb_size,size_t memb_num){
void *p=calloc(memb_size,memb_num);
__mem_append(p);
return p;
}

28
soft/mystdlib.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef mystdlib_h__
#define mystdlib_h__
#include "stdint.h"
#include "stdlib.h"
#define MAP_SIZE_STEP 50
typedef struct _map_def{
size_t map_size;
size_t mam_used;
size_t mem_map[0];
}map_def;
void __mem_clear(map_def **m);
void __mem_mov(map_def **d,map_def **s);
void *mem_calloc(size_t memb_size,size_t memb_num);
void *mem_malloc(size_t size);
void mem_free(void *p);
#endif

87
soft/mythread.c Normal file
View File

@@ -0,0 +1,87 @@
#include "pthread.h"
#include "unistd.h"
#include "mythread.h"
#include "exception.h"
#include "stdio.h"
typedef struct _myth_def{
struct _myth_def *next;
struct _myth_def *last;
pthread_t th;
exception_def except;
size_t id;
int (*func)(void *);
void *arg;
}myth_def;
typedef struct{
myth_def *head;
}self_def;
static self_def g_self;
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
static void *p_thread(void *t){
myth_def *th=(myth_def *)t;
th->id=(size_t)pthread_self();
printf("func:%08lx start id=%d.\n",(size_t)th->func,th->id);
try_{
if(!th->func){
throw_("th->func was null.");
}
th->func(th->arg);
}catch_{
printf("func:%08lx failed.\n",(size_t)th->func);
printf("file=%s,line=%d,err=%s\n",exception()->file,exception()->line,exception()->log);
}
printf("func:%08lx end.\n",(size_t)th->func);
return 0;
}
int myth_create(int (*func)(void *t),void *t){
myth_def *m=calloc(sizeof(myth_def),1);
m->func=func;
m->arg=t;
pthread_create(&m->th,NULL,p_thread,m);
{
self_def *s=&g_self;
if(s->head==NULL){
s->head=m;
}else{
myth_def *myth=s->head;
while(myth->next){
myth=myth->next;
}
myth->next=m;
m->last=myth;
}
}
return m->id;
}
int myth_join(){
self_def *s=&g_self;
myth_def *myth=s->head;
myth_def *old;
while(myth){
pthread_join(myth->th,NULL);
old=myth;
myth=myth->next;
free(old);
}
s->head=NULL;
return 0;
}

12
soft/mythread.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef mythread_h__
#define mythread_h__
#include "pthread.h"
int myth_create(int (*func)(void *t),void *t);
int myth_join();
#endif