ref: 5090b2fec4c35cfc5b41fcb32e8efc33a078567f
parent: 9c0e261a35c05718aa9c890f7164c441c868ceb4
author: spew <spew@cbza.org>
date: Tue Mar 18 20:34:18 EDT 2025
lsd: add filepc, extend bpset/bpdel with file:line
--- a/src/plan9/lsd.c
+++ b/src/plan9/lsd.c
@@ -393,6 +393,30 @@
return str_from_cstr(buf);
}
+BUILTIN("lsd-file2pc", lsd_file2pc)
+{
+ static char buf[1024];
+ uvlong addr;
+ int len, line;
+
+ argcount(nargs, 2);
+ if(sl_unlikely(!sl_isstr(args[0])))
+ type_error("str", args[0]);
+ if(sl_unlikely(!isfixnum(args[1])))
+ type_error("num", args[1]);
+
+ len = cv_len(ptr(args[0]));
+ if(len+1 > sizeof(buf))
+ lerrorf(sl_errio, "path too long");
+ memmove(buf, cvalue_data(args[0]), len);
+ buf[len] = '\0';
+ line = numval(args[1]);
+ addr = file2pc(buf, line);
+ if(addr == ~0)
+ lerrorf(sl_errio, "could not find address of %s:%d", buf, line);
+ return size_wrap(addr);
+}
+
BUILTIN("lsd-ctrace", lsd_ctrace)
{
sl_v *a;
--- a/src/plan9/lsd.lsp
+++ b/src/plan9/lsd.lsp
@@ -28,6 +28,7 @@
(princ "process " pid " exited\n")
(set! pids (cdr pids))
(set! pid (if pids (car pids) -1))
+ (set! bptbl (table))
(detach))
(def (readnote)
@@ -86,11 +87,11 @@
(unless (eq? (status) 'Stopped)
(begin (princ "Waiting... " status "\n")
(stop)))
- (cond ((sym? loc) (unless (has? (global-text globals) loc)
- (error "symbol " loc " not found"))
- (symbol-addr (get (global-text globals) loc)))
+ (cond ((sym? loc) (symbol-addr (get (global-text globals) loc)))
((num? loc) (u64 loc))
- (else (error "symbol or number"))))))
+ ((symbol? loc) (symbol-addr loc))
+ ((str? loc) (filepc loc))
+ (else (error "sym|num|symbol|file:line"))))))
(set! bpset (λ (loc)
(let ((addr (bp_init loc)))
(when (has? bptbl addr)
@@ -107,26 +108,34 @@
(doc-for (bpset loc)
"Set a breakpoint.
- The location can either be a symbol, in which case
- the address will be retrieved from the global text symbols
- of the process, or an integer which is the address at which
- to place the break.
+ The location can be one of the following:
+ 1. A sym, in which case the address will be retrieved from
+ the global text symbols of the process,
+ 2. A num which is the address at which to place the break.
+ 3. An LSD symbol in which the case the symbol's address is used.
+ 4. A string of the form \"file:line\" which specifies a line in a
+ file of source code.
Examples:
`(bpset 'strcpy)` ; breakpoint on strcpy function.
- `(bpset (readreg PC))` ; breakpoint on current instruction.")
+ `(bpset (readreg PC))` ; breakpoint on current instruction.
+ `(bpset \"/sys/src/cmd/cat.c:26\")` ; breakpoint on line 26.")
(doc-for (bpdel loc)
"Delete a breakpoint.
- The location can either be a symbol, in which case
- the address will be retrieved from the global text symbols
- of the process, or an integer which is the address at which
- to remove the break.
+ The location can be one of the following:
+ 1. A sym, in which case the address will be retrieved from
+ the global text symbols of the process,
+ 2. A num which is the address at which to place the break.
+ 3. An LSD symbol in which the case the symbol's address is used.
+ 4. A string of the form \"file:line\" which specifies a line in a
+ file of source code.
Examples:
`(bpdel 'strcpy)` ; remove breakpoint on strcpy function.
- `(bpdel (readreg PC))` ; remove breakpoint on current instruction.")
+ `(bpdel (readreg PC))` ; remove breakpoint on current instruction.
+ `(bpdel \"/sys/src/cmd/cat.c:26\")` ; remove breakpoint on line 26.")
(def (detach)
(when regsf (io-close regsf))
@@ -234,11 +243,7 @@
(def (src (addr (readreg PC)))
"Returns a string of the filename and line number corresponding
- to the instruction address.
-
- Examples:
- `(src)`
- `(src (asm 10))` ; read 10 instructions forward first."
+ to the instruction address."
(lsd-fileline addr))
(def (Bsrc (addr (readreg PC)))
@@ -257,6 +262,14 @@
"\n" s))
(io-close plumbf)))
+(def (filepc f (line NIL))
+ (if line
+ (lsd-file2pc f line)
+ (let ((s (str-split f ":")))
+ (when (/= (length s) 2) (error "invalid file"))
+ (let ((line (str->num (cadr s))))
+ (unless line (error "bad line number"))
+ (lsd-file2pc (car s) line)))))
(def (at-exit s)
(when proc-stdin (io-close proc-stdin))
@@ -263,6 +276,13 @@
(detach)
(lsd-cleanup)
(for-each (λ (p) (princ "echo kill > /proc/" p "/ctl\n")) pids))
+
+(def (sym-find s)
+ (let* ((find (λ (tbl k) (and (has? tbl k) (get tbl k)))))
+ (or (find (global-text globals) s)
+ (find (global-data globals) s))))
+
+(def (sym-addr s) (symbol-addr (find-sym s)))
(add-exit-hook at-exit)