elks-enhanced

publicRead
Owner: themasterBranch: masterCommits: 6893Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL

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);