shithub: sl

Download patch

ref: 06f3f23530c137bac805f97166bbfab32a392644
parent: e75314f9ae9f23f1bf38317673ba1c5dea52f1c0
author: spew <spew@cbza.org>
date: Tue Mar 25 14:14:45 EDT 2025

lsd: various small improvements

--- a/src/plan9/lsd.sl
+++ b/src/plan9/lsd.sl
@@ -37,7 +37,6 @@
   sym retpc sp locals)
 
 (def coref NIL)
-(def textf NIL)
 (def regsf NIL)
 (def fpregsf NIL)
 (def proc-stdin NIL)
@@ -94,15 +93,20 @@
   (unless coref (error "not attached to proc"))
   (io-pread coref addr rest))
 
-(def (readtext addr . rest)
-  (unless textf (error "not attached to proc"))
-  (io-pread textf addr rest))
-
 (def (writecore addr . rest)
   (unless coref (error "not attached to proc"))
   (io-pwrite coref addr rest))
 
 (def (readreg reg)
+  "Read the value of a register.
+
+   Examples:
+
+       (readreg AX) ; read the return register on amd64
+       (readreg PC) ; read the current instruction address."
+  :doc-group lsd
+  :doc-see reg
+  :doc-see registers
   (unless regsf (error "not attached to proc"))
   (let {[f (case (reg-type reg)
              ((:gpreg) regsf)
@@ -110,15 +114,23 @@
     (io-pread f (reg-addr reg) (list (reg-size reg)))))
 
 (def (symbol-read symbol . rest)
-  "Reads the value from the core file at the symbol's address."
+  "Read the value from the core file at the symbol's address."
   :doc-group lsd
   :doc-see sym-local
+  :doc-see sym-global
+  :doc-see sym-addr
   (unless coref (error "not attached to proc"))
   (apply readcore (cons (symbol-addr symbol) rest)))
 
-(def (hex n) (str "0x" (num->str n 16)))
+(def (hex n)
+  "Display an integer in hex format."
+  :doc-group lsd
+  (str "0x" (num->str n 16)))
 
-(def (oct n) (str "0" (num->str n 8)))
+(def (oct n)
+  "Display an integer in octal format."
+  :doc-group lsd
+  (str "0" (num->str n 8)))
 
 (def (bpsave a) (readcore a 'byte (length bpinst)))
 
@@ -188,7 +200,6 @@
   (when regsf (io-close regsf))
   (when fpregsf (io-close fpregsf))
   (when coref (io-close coref))
-  (when textf (io-close textf))
   (void))
 
 (def (attach)
@@ -196,10 +207,12 @@
   (set! regsf (procfile 'regs :read :write))
   (set! fpregsf (procfile 'fpregs :read :write))
   (set! coref (procfile 'mem :read :write))
-  (set! textf (procfile 'text :read))
+  (set! pids (cons pid pids))
   (void))
 
 (def (status)
+  "Return the running status of the process."
+  :doc-group lsd
   (let {[sf (procfile 'status)]}
     (prog1 (caddr (read-all sf))
            (io-close sf))))
@@ -216,13 +229,16 @@
 
 (def ctrace (get tracers (os-getenv "objtype")))
 
-(def (_stk)
-  "Return the call stack in the form of a list of stack frames."
+(def (_stk (:level 0) (:n NIL))
+  "Return the call stack in the form of a list of stack frames.
+   Optionally specify what level of the stack to return, starting at
+   the innermost level and how many levels to display."
   :doc-group lsd
   :doc-see frame
-  (reverse! (ctrace)))
+  (let {[s (list-tail (reverse! (ctrace)) level)]}
+    (if n (list-head s n) s)))
 
-(def (stk (:locals NIL))
+(def (stk (:level 0) (:n NIL) (:locals NIL))
   "Print the stack trace optionally showing local auto values.
 
    Bugs:
@@ -258,7 +274,7 @@
                                     "\n"))
                       autos))
           (go (frame-retpc f) (cdr fs))))))
-  (let* {[tos (go (curPC) (_stk))]
+  (let* {[tos (go (curPC) (_stk :level level :n n))]
          [topsym (lsd-findsym tos)]}
     (princ (symbol-name topsym)
            "+"
@@ -267,12 +283,12 @@
            (src tos)
            "\n")))
 
-(def (lstk)
+(def (lstk (:level 0) (:n NIL))
   "Print the stack trace showing local auto values."
   :doc-group lsd
   :doc-see _stk
   :doc-see stk
-  (stk :locals T))
+  (stk :locals T :level level :n n))
 
 (def (curPC) (and (>= pid 0) (readreg PC)))
 
@@ -341,7 +357,7 @@
         (curPC)
         (func))))
 
-(def (asmlist (n 5) (addr (curPC)))
+(def (asmlist (n 5) (addr (readreg PC)))
   "Return a list of the next `n` disassembled instructions starting at
    `addr`.  Just like `(asm)` but returns a list instead of printing.
 
@@ -357,7 +373,7 @@
           (when on-bp (writecore addr bpinst))
           (cons (cons addr instr) (asmlist (1- n) (+ addr isize)))))))
 
-(def (asm (n 5) (addr (curPC)))
+(def (asm (n 5) (addr (readreg PC)))
   "Print the next `n` disassembled instructions at `addr`.
 
    Examples:
@@ -432,9 +448,10 @@
   (or (find (global-text globals) s)
       (find (global-data globals) s)))
 
-(def (sym-local s)
+(def (sym-local s (:level 0))
   «Return a local symbol from the attached proc's current stack frame
-   or `NIL`.  Input is a `sym`.
+   or `NIL`.  Input is a `sym`.  Optionally specify what level of the
+   stack frame to search.
 
    Examples:
 
@@ -441,16 +458,18 @@
        (sym-local 'i)    → #(symbol "i" #\a 140737488350940)
        (symbol-read (sym-local 'argc) 's32) → #s32(2)»
   :doc-group lsd
+  :doc-see _stk
   (let {[ss (str s)]}
     (find ss
-          (frame-locals (car (_stk)))
+          (frame-locals (car (_stk :level level)))
           :key symbol-name)))
 
-(def (sym-addr s)
+(def (sym-addr s (:local NIL))
   "Return the address of a symbol from the attached proc's symbol table
-   or NIL.  Input is a sym."
+   or NIL.  Input is a sym.  Optionally specify whether to search the
+   local stack frame for the symbol."
   :doc-group lsd
-  (symbol-addr (sym-global s)))
+  (symbol-addr ((if local sym-local sym-global) s)))
 
 (add-exit-hook
   (λ (s)
@@ -478,10 +497,12 @@
     (attach)
     (map bpset (follow (sym-addr 'main)))
     (startstop)
-    (set! pids (cons pid pids))
     pid))
 
 (def (lsd a)
+  "Entry point to lsd.  Load the symbol table, the registers and
+   attach to a process if one is running."
+  :doc-group lsd
   (let* {[v (lsd-load a)]
          [f (λ (symbol tbl) (put! tbl (sym (symbol-name symbol)) symbol))]
          [text (foldl f (table) (aref v 3))]
@@ -492,6 +513,16 @@
     (set! globals (make-global :text text :data data)))
   (and (>= pid 0) (attach)))
 
+(def (usage)
+  (princ "usage: " (car *argv*) " [pid | textfile]\n")
+  (exit))
+
+(unless (cdr *argv*) (usage))
+
 (let* {[proc (cadr *argv*)]
        [pid (str->num proc)]}
   (if pid (lsd pid) (lsd proc)))
+
+(set! top-level-exception-handler
+      (λ (e) (with-output-to *stderr*
+                             (print-exception e))))