添加debug,每个线程都维护一个jump帧

This commit is contained in:
ranchuan
2024-06-21 15:20:47 +08:00
parent 9ac75c09ac
commit 474a58e53d
10 changed files with 329 additions and 47 deletions

View File

@@ -8,7 +8,8 @@
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
"_UNICODE",
"LINUX"
],
"windowsSdkVersion": "10.0.22621.0",
"compilerPath": "C:/cygwin64/bin/gcc.exe",

View File

@@ -5,6 +5,8 @@
"test1.h": "c",
"stdint.h": "c",
"exception.h": "c",
"mythread.h": "c"
"mythread.h": "c",
"ipc.h": "c",
"errno.h": "c"
}
}

15
main.c
View File

@@ -5,10 +5,11 @@
#include "soft/exception.h"
#include "soft/mythread.h"
#include "unistd.h"
#include "soft/debug.h"
int thread_fun(void *t){
printf("run in thread_fun.\n");
DBG_INFO("run in thread_fun.\n");
while(1){
sleep(5);
@@ -22,8 +23,8 @@ int thread_fun(void *t){
void SystemInit();
extern char **environ;
int main(int argc,char *argv[]){
int id;
printf("hello world.\n");
debug_init(NULL);
DBG_INFO("hello world.%ld\n",(size_t)pthread_self());
@@ -33,8 +34,8 @@ int main(int argc,char *argv[]){
// }
// printf("a+b=%d",test_add(3,5));
id=myth_create(thread_fun,NULL);
id=myth_create(NULL,NULL);
myth_create(thread_fun,NULL);
myth_create(NULL,NULL);
// sleep(10);
myth_join();
}
@@ -56,11 +57,11 @@ typedef void (*slot_fun_def)(size_t a,size_t b,size_t c,size_t d,size_t e,size_t
void funptr_test(){
printf("print from funptr_test fun.\n");
DBG_INFO("print from funptr_test fun.\n");
}
void add_test(int a,int b,void (*f)()){
printf("add_fun:%d+%d=%d\n",a,b,a+b);
DBG_INFO("add_fun:%d+%d=%d\n",a,b,a+b);
f();
}

34
make.py
View File

@@ -28,17 +28,19 @@ CSRC = []
CINC = ['-Isoft']
CDEF = ["-DTEST"]
CDEF = ["-DTEST","-DLINUX"]
ASRC = []
BUILD_DIR = 'build'
TARGET = 'hello'
TARGET = 'hello.exe'
# CFLAG = ["-Wall -pedantic -specs=nano.specs -mcpu=cortex-m3 -mthumb -lc -lm -lnosys -Og -Tstm32_boot.ld",
# f"-Wl,-Map={BUILD_DIR}/{TARGET}.map,--cref -Wl,--gc-sections"]
CFLAG = ["-Wall -pedantic -g"]
# -pedantic <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ISO<53><EFBFBD><EFB7A8><EFBFBD><EFBFBD>
CFLAG = ["-Wall -g"]
# <20>ҵ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>׺<EFBFBD><D7BA><EFBFBD>ļ<EFBFBD>
def find_type(path:str,fix:list[str]):
@@ -82,6 +84,7 @@ def tran_path(path:str):
# <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
def check_rebuild(dst:str,src:list[str]):
# print(f"src:{src}")
if(not os.path.exists(dst)):
return True
dst_time=os.path.getmtime(dst)
@@ -91,6 +94,9 @@ def check_rebuild(dst:str,src:list[str]):
src_time.sort()
if(src_time[-1]>dst_time):
return True
# for item in src_time:
# if(item>dst_time):
# return True
return False
@@ -98,7 +104,14 @@ def check_rebuild(dst:str,src:list[str]):
# <20><>ȡ.d<>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>б<EFBFBD>
def read_depend_files(name:str):
with open(name) as f:
t=f.readline()
lines=f.readlines()
t=''
for line in lines:
line=line.strip()
if(line[-1]=='\\'):
t+=line[:-1]
else:
t+=line
t=t.split(':')[-1].strip()
t=t.split(' ')
# print(f"<22><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>{t}")
@@ -118,7 +131,8 @@ def build_depend(src:list[str]):
ret=os.system(cmd)
if(ret):
exit()
else:
print(f"{i} û<>и<EFBFBD><D0B8><EFBFBD>Դ<EFBFBD>ļ<EFBFBD>")
# <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC>ļ<EFBFBD>
def build_object(src:list[str]):
@@ -135,9 +149,13 @@ def build_object(src:list[str]):
cd=os.path.join(BUILD_DIR,cd)
if(check_rebuild(dst,read_depend_files(cd))):
cmd=f"{CC} -c {i} -o {dst} {flags}"
else:
print(f"{i} û<>и<EFBFBD><D0B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ")
elif(file_type in ['s','S','asm','ASM']):
if(check_rebuild(dst,[i])):
cmd=f"{AS} -c {i} -o {dst} {flags}"
else:
print(f"{i} û<>и<EFBFBD><D0B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ")
if(len(cmd)>0):
print(cmd)
ret=os.system(cmd)
@@ -160,13 +178,13 @@ def build_target(src:list[str]):
if(ret):
exit()
else:
print("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>Ŀ<EFBFBD><EFBFBD>")
print(f"{dst} û<>и<EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>")
def main():
global CSRC
global ASRC
CSRC+=find_type('./',['c','C'])
CSRC+=find_type('.\\',['c','C'])
# ASRC+=find_type('./',['s','S','asm','ASM'])
if(not os.path.exists(BUILD_DIR)):
@@ -176,7 +194,7 @@ def main():
build_depend(CSRC)
print("<EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>")
build_object(CSRC)
build_object(ASRC)
# build_object(ASRC)
print("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>")
build_target(CSRC+ASRC)
# os.system(f"{HEX} {BUILD_DIR}/{TARGET} {BUILD_DIR}/{TARGET}.hex")

162
soft/debug.c Normal file
View File

@@ -0,0 +1,162 @@
#include "stdio.h"
#include "stdarg.h"
#include "debug.h"
#include "string.h"
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include "errno.h"
#define CONSOLEBUF_SIZE 1024
#ifdef LINUX
union semun{
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
void _sem_take(int semid)//得到钥匙
{
struct sembuf sop;
sop.sem_num = 0;//控制第一个信号量
sop.sem_op = -1;//钥匙数量减一6
sop.sem_flg = SEM_UNDO;
semop(semid,&sop,1);
}
void _sem_relase(int semid)//放回钥匙
{
struct sembuf sop;
sop.sem_num = 0;
sop.sem_op = 1;
sop.sem_flg = SEM_UNDO;
semop(semid,&sop,1);
}
int _sem_init(){
key_t key;
int mutex;
key = ftok(".",5345);
printf("sem init, key=%llu\n",key);
mutex = semget(key,1,IPC_CREAT);//创建信号量
printf("sem init, mutex=%d\n",mutex);
if(mutex<=0){
printf("%d\n",errno);
}
union semun set;
set.val = 1;//钥匙数量为0
semctl(mutex,0,SETVAL,set);
return mutex;
}
#endif
#ifdef RT_THREAD
#include "rtthread.h"
#endif
typedef struct{
int inited;
#ifdef RT_THREAD
struct rt_mutex mutex;
#endif
#ifdef LINUX
int mutex;
#endif
dbg_dev *dev;
}self_def;
static self_def g_data;
static int dev_init(){
return 0;
}
static int dev_write(const uint8_t *data,size_t len){
size_t rb;
rb=fwrite(data,sizeof(uint8_t),len,stdout);
return (int)rb;
}
static dbg_dev g_dev_default={
.init=dev_init,
.write=dev_write,
};
int debug_init(dbg_dev *dev)
{
self_def *self=&g_data;
if(dev==NULL){
dev=&g_dev_default;
}
if(self->inited==0)
{
#ifdef RT_THREAD
rt_mutex_init(&self->mutex,"debug_mutex",RT_IPC_FLAG_FIFO);
#endif
#ifdef LINUX
self->mutex=_sem_init();
#endif
self->dev=dev;
self->dev->init();
self->dev->write((const uint8_t *)"\r\n",2);
self->inited=1;
DBG_LOG("debug inited.\r\n");
}
return 0;
}
void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...)
{
self_def *self=&g_data;
if(self->inited==0) return;
va_list args;
size_t length;
static char log_buf[CONSOLEBUF_SIZE];
static const char *level_str[]={"[info] ","[log] ","[warn] ","[err] "};
static int level_str_len[]={7,6,7,6};
if(level<DBG_LEVEL_INFO||level>DBG_LEVEL_ERR) return;
#ifdef RT_THREAD
rt_mutex_take(&self->mutex,RT_WAITING_FOREVER);
#endif
#ifdef LINUX
_sem_take(self->mutex);
#endif
memcpy(log_buf,level_str[level],level_str_len[level]);
length=level_str_len[level];
length+=sprintf(log_buf + length,"%s|%s|%d| ",file,fun,line);
va_start(args, fmt);
length += vsnprintf(log_buf + length, CONSOLEBUF_SIZE - length - 3, fmt, args);
va_end(args);
if (length > CONSOLEBUF_SIZE - 3)
length = CONSOLEBUF_SIZE - 3;
if(log_buf[length-1]!='\n'){
memcpy(&log_buf[length],"\n",1);
length+=1;
}
log_buf[length]=0;
self->dev->write((const uint8_t *)log_buf,length);
#ifdef RT_THREAD
rt_mutex_release(&self->mutex);
#endif
#ifdef LINUX
_sem_relase(self->mutex);
#endif
}

68
soft/debug.h Normal file
View File

@@ -0,0 +1,68 @@
#ifndef debug_h__
#define debug_h__
#include "stdint.h"
#include "stdio.h"
/*r{ 修改日志打印等级 }c*/
#define DBG_LOG_LEVEL DBG_LEVEL_INFO
/*r{ 定义打印数据等级 }c*/
#define DBG_LEVEL_INFO 0
#define DBG_LEVEL_LOG 1
#define DBG_LEVEL_WARN 2
#define DBG_LEVEL_ERR 3
#if (DBG_LOG_LEVEL<=DBG_LEVEL_INFO)
#define DBG_INFO( ml_msg_, ...) \
DBG_LOG_(DBG_LEVEL_INFO, (ml_msg_), ##__VA_ARGS__)
#else
#define DBG_INFO( ml_msg_, ...)
#endif
#if (DBG_LOG_LEVEL<=DBG_LEVEL_LOG)
#define DBG_LOG( ml_msg_, ...) \
DBG_LOG_(DBG_LEVEL_LOG, (ml_msg_), ##__VA_ARGS__)
#else
#define DBG_LOG( ml_msg_, ...)
#endif
#if (DBG_LOG_LEVEL<=DBG_LEVEL_WARN)
#define DBG_WARN( ml_msg_, ...) \
DBG_LOG_(DBG_LEVEL_WARN, (ml_msg_), ##__VA_ARGS__)
#else
#define DBG_WARN( ml_msg_, ...)
#endif
#if (DBG_LOG_LEVEL<=DBG_LEVEL_ERR)
#define DBG_ERR( ml_msg_, ...) \
DBG_LOG_(DBG_LEVEL_ERR, (ml_msg_), ##__VA_ARGS__)
#else
#define DBG_ERR( ml_msg_, ...)
#endif
#define DBG_LOG_(type_,msg_,...)\
debug_log(__FILE__,__func__,__LINE__,type_,(msg_),##__VA_ARGS__)
typedef struct{
int (*init)();
int (*write)(const uint8_t *data,size_t len);
}dbg_dev;
int debug_init(dbg_dev *dev);
void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...);
#endif

View File

@@ -8,12 +8,15 @@
#include "stdarg.h"
#include "exception.h"
#include "mystdlib.h"
#include "debug.h"
#include "mythread.h"
exception_def *exception(){
static exception_def frame={0};
return &frame;
exception_def *frame;
frame=&myth_self()->except;
return frame;
}
@@ -54,31 +57,30 @@ void func_two();
int test_add(int a, int b)
{
printf("setjmp test.\n");
DBG_INFO("setjmp test.\n");
try_{
printf("first enter setjmp.\n");
DBG_INFO("first enter setjmp.\n");
try_{
printf("try in try.\n");
DBG_INFO("try in try.\n");
func_two();
// throw_("throw two err.");
}catch_{
printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
DBG_WARN("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_());
DBG_WARN("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
try_{
printf("try in catch.\n");
DBG_INFO("try in catch.\n");
func_two();
// throw_("throw two err.");
}catch_{
printf("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
DBG_WARN("file=%s,line=%d,err=%s.\n",file_(),line_(),err_());
}
}
printf("setjmp end.\n");
DBG_INFO("setjmp end.\n");
return 0;
}
@@ -87,7 +89,7 @@ int test_add(int a, int b)
void func_two(){
printf("in func:%s\n",__func__);
DBG_INFO("in func:%s\n",__func__);
void *p=mem_malloc(512);
throw_("throw in func_two. in func:%s",__func__);
mem_free(p);

View File

@@ -3,6 +3,7 @@
#include "string.h"
#include "exception.h"
#include "stdio.h"
#include "debug.h"
static void __mem_append_m(map_def **m,void *p);
@@ -17,7 +18,7 @@ void __mem_clear(map_def **m){
for(size_t i=0;i<size;i++){
if(map[i]){
free((void *)map[i]);
printf("clear eme_p=%08lx\n",map[i]);
DBG_INFO("clear eme_p=%08lx\n",map[i]);
}
}
free(*m);
@@ -38,7 +39,7 @@ void __mem_mov(map_def **d,map_def **s){
}
free(*s);
(*s)=0;
printf("mem mov end.\n");
DBG_INFO("mem mov end.\n");
}
@@ -51,7 +52,7 @@ void mem_free(void *p){
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);
DBG_INFO("free eme_p=%08lx\n",(size_t)p);
(*m)->mam_used--;
break;
}
@@ -77,7 +78,7 @@ static void __mem_append_m(map_def **m,void *p){
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);
DBG_INFO("append eme_p=%08lx\n",(size_t)p);
(*m)->mam_used++;
break;
}

View File

@@ -5,17 +5,9 @@
#include "mythread.h"
#include "exception.h"
#include "stdio.h"
#include "debug.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;
@@ -32,17 +24,18 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
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);
DBG_INFO("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);
DBG_WARN("func:%08lx failed.\n",(size_t)th->func);
DBG_WARN("file=%s,line=%d,err=%s\n",exception()->file,exception()->line,exception()->log);
}
printf("func:%08lx end.\n",(size_t)th->func);
DBG_INFO("func:%08lx end.\n",(size_t)th->func);
th->end=1;
return 0;
}
@@ -85,3 +78,20 @@ int myth_join(){
return 0;
}
myth_def *myth_self(){
self_def *s=&g_self;
myth_def *myth=s->head;
size_t id=(size_t)pthread_self();
while(myth){
if(myth->id==id){
return myth;
}
myth=myth->next;
}
printf("can not find myth.\n");
return NULL;
}

View File

@@ -3,10 +3,27 @@
#include "pthread.h"
#include "exception.h"
typedef struct _myth_def{
struct _myth_def *next;
struct _myth_def *last;
pthread_t th;
exception_def except;
size_t id;
size_t end;
int (*func)(void *);
void *arg;
}myth_def;
int myth_create(int (*func)(void *t),void *t);
int myth_join();
myth_def *myth_self();
#endif