a much better tracing code

This commit is contained in:
Yanyan Jiang 2018-08-10 16:44:11 +00:00
parent 87ea80951b
commit 5c5d3ad03f
5 changed files with 73 additions and 80 deletions

View File

@ -89,7 +89,7 @@ void _intr_write(int enable);
int _pte_init(void *(*pgalloc)(size_t size), void (*pgfree)(void *));
int _protect(_Protect *p);
void _unprotect(_Protect *p);
void _switch(_Protect *p);
void _prot_switch(_Protect *p);
int _map(_Protect *p, void *va, void *pa, int prot);
_Context *_ucontext(_Protect *p, _Area ustack, _Area kstack,
void *entry, void *args);

View File

@ -60,50 +60,4 @@ void vec14();
void vecsys();
void irqall();
// Tracing
#include <klib.h> // TODO: don't do this.
#define should_trace(flags, req) ( \
(flags & TRACE_THIS) && \
(flags & req) \
)
#define trace_call(fn, args) \
do { \
uint32_t flags = trace_flags; \
if (should_trace(flags, _TRACE_CALL)) { \
printf("[trace] call " #fn " (%x) with args {%x, %x, %x, %x}\n", (void *)fn, \
args.a0, args.a1, args.a2, args.a3); \
} \
} while (0)
#define trace_ret(fn, retval) \
do { \
uint32_t flags = trace_flags; \
if (should_trace(flags, _TRACE_RET)) { \
printf("[trace] ret " #fn " (%x) -> %x\n", (void *)fn, (uintptr_t)retval); \
} \
} while (0)
#define CALL_ARGS(_0, _1, _2, _3, ...) \
(_CallArgs) { .a0 = ((uintptr_t)_0), \
.a1 = ((uintptr_t)_1), \
.a2 = ((uintptr_t)_2), \
.a3 = ((uintptr_t)_3), } \
#define trace_wrapper_noret(rettype, stub, func, arglist, n, ...) \
trace_call(stub, CALL_ARGS(__VA_ARGS__, 0, 0, 0, 0)); \
rettype ret = func arglist; \
trace_ret(stub, ret);
#define trace_wrapper(rettype, stub, func, arglist, n, ...) \
trace_wrapper_noret(rettype, stub, func, arglist, n, __VA_ARGS__); \
return ret;
#define TRACE_NORET(stub, func, decl, arglist, n, ...) \
void stub decl { trace_wrapper_noret(int, stub, func, arglist, n, __VA_ARGS__); }
#define TRACE(rettype, stub, func, decl, arglist, n, ...) \
rettype stub decl { trace_wrapper(rettype, stub, func, arglist, n, __VA_ARGS__); }
#endif

View File

@ -75,7 +75,7 @@ int unprotect(_Protect *p) {
return 0;
}
int vm_switch(_Protect *p) {
int prot_switch(_Protect *p) {
set_cr3(p->ptr);
return 0;
}
@ -129,4 +129,4 @@ static void *pgalloc() {
static void pgfree(void *ptr) {
pgfree_usr(ptr);
}
}

View File

@ -11,41 +11,80 @@ void _trace_off(uint32_t flags) {
trace_flags &= ~flags;
}
// wrappers of traced functions
// TODO: add others, add pgalloc()/pgfree() callback traces
#include <klib.h> // TODO: don't do this.
// ASYE
int asye_init(_Context *(*handler)(_Event, _Context *));
_Context *kcontext(_Area stack, void (*entry)(void *), void *arg);
int yield();
int intr_read();
int intr_write(int enable);
_Context *irq_callback(_Event ev, _Context *ctx);
// PTE
int pte_init(void * (*pgalloc_f)(size_t), void (*pgfree_f)(void *));
int map(_Protect *p, void *va, void *pa, int prot);
_Context *ucontext(_Protect *p, _Area ustack, _Area kstack, void *entry, void *args);
int vm_switch(_Protect *p);
int protect(_Protect *p);
int unprotect(_Protect *p);
// MPE
#define should_trace(flags, req) ( \
(flags & TRACE_THIS) && \
(flags & req) \
)
// ==================== wrapper implementations ====================
#define trace_call(fn, args) \
do { \
uint32_t flags = trace_flags; \
if (should_trace(flags, _TRACE_CALL)) { \
printf("[trace] call " #fn " (%x) with args {%x, %x, %x, %x}\n", (void *)fn, \
args.a0, args.a1, args.a2, args.a3); \
} \
} while (0)
#define trace_ret(fn, retval) \
do { \
uint32_t flags = trace_flags; \
if (should_trace(flags, _TRACE_RET)) { \
printf("[trace] ret " #fn " (%x) -> %x\n", (void *)fn, (uintptr_t)retval); \
} \
} while (0)
#define CALL_ARGS(_0, _1, _2, _3, ...) \
(_CallArgs) { .a0 = ((uintptr_t)_0), \
.a1 = ((uintptr_t)_1), \
.a2 = ((uintptr_t)_2), \
.a3 = ((uintptr_t)_3), } \
#define trace_wrapper_noret(rettype, stub, func, arglist, n, ...) \
trace_call(stub, CALL_ARGS(__VA_ARGS__, 0, 0, 0, 0)); \
rettype ret = func arglist; \
trace_ret(stub, ret);
#define trace_wrapper(rettype, stub, func, arglist, n, ...) \
trace_wrapper_noret(rettype, stub, func, arglist, n, __VA_ARGS__); \
return ret;
#define TRACE_NORET(rettype, stub, func, decl, arglist, n, ...) \
void stub decl { trace_wrapper_noret(int, stub, func, arglist, n, __VA_ARGS__); }
#define TRACE(rettype, stub, func, decl, arglist, n, ...) \
rettype stub decl { trace_wrapper(rettype, stub, func, arglist, n, __VA_ARGS__); }
#define DECL(tr, rettype, func, decl, args, ...) \
rettype func decl ;
#define DEF(tr, rettype, func, decl, args, ...) \
tr(rettype, _##func, func, decl, args, __VA_ARGS__)
#define ASYE_FUNCS(_) \
_(TRACE, int, asye_init, (_Context *(*handler)(_Event, _Context *)), (handler), 1, handler) \
_(TRACE, _Context *, kcontext, (_Area stack, void (*entry)(void *), void *arg), (stack, entry, arg), 2, entry, arg) \
_(TRACE, int, intr_read, (), (), 1, 0) \
_(TRACE, _Context *, irq_callback, (_Event ev, _Context *ctx), (ev, ctx), 4, ev.event, ev.cause, ev.ref, ctx); \
_(TRACE_NORET, int, yield, (), (), 1, 0) \
_(TRACE_NORET, int, intr_write, (int enable), (enable), 1, enable)
#define PTE_FUNCS(_) \
_(TRACE, int, pte_init, (void * (*pgalloc_f)(size_t), void (*pgfree_f)(void *)), (pgalloc_f, pgfree_f), 2, pgalloc_f, pgfree_f) \
_(TRACE, int, map, (_Protect *p, void *va, void *pa, int prot), (p, va, pa, prot), 4, p, va, pa, prot) \
_(TRACE, _Context *, ucontext, (_Protect *p, _Area ustack, _Area kstack, void *entry, void *args), (p, ustack, kstack, entry, args), 3, p, entry, args) \
_(TRACE_NORET, int, prot_switch, (_Protect *p), (p), 1, p) \
_(TRACE, int, protect, (_Protect *p), (p), 1, p) \
_(TRACE_NORET, int, unprotect, (_Protect *p), (p), 1, p)
ASYE_FUNCS(DECL)
PTE_FUNCS(DECL)
#define TRACE_THIS _TRACE_ASYE
TRACE(int, _asye_init, asye_init, (_Context *(*handler)(_Event, _Context *)), (handler), 1, handler);
TRACE(_Context *, _kcontext, kcontext, (_Area stack, void (*entry)(void *), void *arg), (stack, entry, arg), 2, entry, arg);
TRACE_NORET(_yield, yield, (), (), 1, 0);
TRACE(int, _intr_read, intr_read, (), (), 1, 0);
TRACE_NORET(_intr_write, intr_write, (int enable), (enable), 1, enable)
TRACE(_Context *, _irq_callback, irq_callback, (_Event ev, _Context *ctx), (ev, ctx), 4, ev.event, ev.cause, ev.ref, ctx);
ASYE_FUNCS(DEF)
#undef TRACE_THIS
#define TRACE_THIS _TRACE_PTE
TRACE(int, _pte_init, pte_init, (void * (*pgalloc_f)(size_t), void (*pgfree_f)(void *)), (pgalloc_f, pgfree_f), 2, pgalloc_f, pgfree_f) ;
TRACE(int, _map, map, (_Protect *p, void *va, void *pa, int prot), (p, va, pa, prot), 4, p, va, pa, prot);
TRACE(_Context *, _ucontext, ucontext, (_Protect *p, _Area ustack, _Area kstack, void *entry, void *args), (p, ustack, kstack, entry, args), 3, p, entry, args);
TRACE_NORET(_switch, vm_switch, (_Protect *p), (p), 1, p)
TRACE(int, _protect, protect, (_Protect *p), (p), 1, p);
TRACE_NORET(_unprotect, unprotect, (_Protect *p), (p), 1, p);
PTE_FUNCS(DEF)
#undef TRACE_THIS

View File

@ -56,7 +56,7 @@ int main() {
_ucontext(&prot, u, k, ptr, (void*)-1);
_switch(&prot);
_prot_switch(&prot);
_unprotect(&prot);
_yield();