Commit diff
Commit 92bbb2cd602376b5d38b73b5bb04eead64b5438
commit 92bbb2cd602376b5d38b73b5bb04eead64b5438c
Author: Greg Haerr <greg@censoft.com>
Date: Wed Feb 11 16:46:32 2026 -0700
[libc] Enhance debug function tracing
---
elks/arch/i86/kernel/strace.c | 4 ++--
elkscmd/rootfs_template/bootopts | 1 +
libc/debug/instrument.c | 35 ++++++++++++++++++++++++++++-------
libc/debug/stacktrace.c | 16 ++++++++--------
4 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/elks/arch/i86/kernel/strace.c b/elks/arch/i86/kernel/strace.c
index ca49ad03..a9a699a4 100644
--- a/elks/arch/i86/kernel/strace.c
+++ b/elks/arch/i86/kernel/strace.c
@@ -25,7 +25,7 @@ void check_ustack(void)
if (sp < brk) {
printk("(%P)STACK OVERFLOW by %u\n", brk - sp);
- printk("curbreak %u, SP %u\n", current->t_endbrk, current->t_regs.sp);
+ printk("CURBREAK %x, SP %x\n", brk, sp);
do_exit(SIGSEGV);
}
if (sp < stacklow) {
@@ -33,7 +33,7 @@ void check_ustack(void)
printk("(%P)STACK USING %u UNUSED HEAP\n", stacklow - sp);
}
if (sp > current->t_begstack) {
- printk("(%P)STACK UNDERFLOW\n");
+ printk("(%P)STACK UNDERFLOW: SP %x BEGSTACK %x\n", sp, current->t_begstack);
do_exit(SIGSEGV);
}
}
diff --git a/elkscmd/rootfs_template/bootopts b/elkscmd/rootfs_template/bootopts
index 92b7e857..e0a70270 100644
--- a/elkscmd/rootfs_template/bootopts
+++ b/elkscmd/rootfs_template/bootopts
@@ -34,3 +34,4 @@ xms=on
#istack
#console=ttyS0,19200 3
#MOUSE_PORT=/dev/ttyS1
+#DEBUG_PORT=none
diff --git a/libc/debug/instrument.c b/libc/debug/instrument.c
index 64ca83ad..ac018f60 100644
--- a/libc/debug/instrument.c
+++ b/libc/debug/instrument.c
@@ -14,10 +14,19 @@
#include "debug/instrument.h"
#include "debug/syms.h"
+#define getsp() __extension__ ({ \
+ unsigned int _v; \
+ asm volatile ("mov %%sp,%%ax" \
+ :"=a" (_v) \
+ : /* no input */ \
+ ); \
+ _v; })
+
static size_t ftrace;
static size_t start_sp;
static size_t max_stack;
static int count;
+static int *save_calling_fn[64];
/* runs before main and rewrites argc/argv on stack if --ftrace found */
#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
@@ -25,16 +34,21 @@ static noinstrument CONSTRUCTOR(ftrace_checkargs, _INIT_PRI_FTRACE);
static noinstrument void ftrace_checkargs(void)
{
char **avp = __argv + 1;
+ char *p;
int fd;
- ftrace = (size_t)getenv("FTRACE");
- if ((*avp && !strcmp(*avp, "--ftrace"))) {
+ if (*avp && !strncmp("--ftrace", *avp, 8)) {
+ p = *avp + 8;
while (*avp) {
*avp = *(avp + 1);
avp++;
}
__argc--;
- ftrace = 1;
+ } else
+ p = getenv("FTRACE");
+ if (p) {
+ if (*p) ftrace = *p - '0';
+ else ftrace = 1;
}
if (ftrace) {
fd = open(_PATH_CONSOLE, O_WRONLY);
@@ -90,16 +104,23 @@ void noinstrument __cyg_profile_func_enter_simple(void)
fprintf(stderr, "(%d)", getpid());
for (i=0; i<count; i++)
fputc('|', stderr);
- fprintf(stderr, ">%s, from %s %d/%u %lk", sym_text_symbol(calling_fn, 0),
- callsite, stack_used, max_stack, get_ptime());
+ fprintf(stderr, ">%s, from %s %d/%u SP %x %lk", sym_text_symbol(calling_fn, 0),
+ callsite, stack_used, max_stack, getsp(), get_ptime());
fputc('\n', stderr);
+ save_calling_fn[count] = calling_fn;
+ if (ftrace & 2) _print_stack(0);
++count;
}
void noinstrument __cyg_profile_func_exit_simple(void)
{
- if (ftrace)
- --count;
+ if (ftrace) {
+ int *calling_fn = save_calling_fn[--count];
+ fprintf(stderr, "(%d)", getpid());
+ for (int i=0; i<count; i++)
+ fputc('|', stderr);
+ fprintf(stderr, "<%s EXIT SP %x\n", sym_text_symbol(calling_fn, 0), getsp());
+ }
}
#if UNUSED
diff --git a/libc/debug/stacktrace.c b/libc/debug/stacktrace.c
index 4a57f91a..fa1d16f2 100644
--- a/libc/debug/stacktrace.c
+++ b/libc/debug/stacktrace.c
@@ -32,19 +32,19 @@ static void noinstrument _print_stack_line(int level, int **addr, int *fn,
{
int j = 0;
- printf("%4d: %04x =>", level, (int)addr);
+ fprintf(stderr, "%4d: %04x =>", level, (int)addr);
do {
if ((j == 0 && !(flag & BP_PUSHED))
|| (j == 1 && !(flag & DI_PUSHED))
|| (j == 2 && !(flag & SI_PUSHED)))
- printf(" ");
- else printf(" %04x", (int)*addr++);
+ fprintf(stderr, " ");
+ else fprintf(stderr, " %04x", (int)*addr++);
} while (++j < STACKCOLS);
- printf(" (%04x)", (int)fn);
- printf(" %s", sym_text_symbol(fn, (size_t)fn - (size_t)fnstart));
+ fprintf(stderr, " (%04x)", (int)fn);
+ fprintf(stderr, " %s", sym_text_symbol(fn, (size_t)fn - (size_t)fnstart));
if (!(flag & BP_PUSHED))
- printf("*");
- printf("\n");
+ fprintf(stderr, "*");
+ fprintf(stderr, "\n");
}
/* display call stack, arg1 ignored but displayed for testing */
@@ -56,7 +56,7 @@ void noinstrument _print_stack(int arg1)
int i = 0;
sym_read_exe_symbols(__program_filename);
- printf("Level Addr BP DI SI Ret Arg Arg2 Arg3 Arg4\n"
+ fprintf(stderr, "Level Addr BP DI SI Ret Arg Arg2 Arg3 Arg4\n"
"~~~~~ ~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
do {
int *fnstart = _get_fn_start_address(fn);