Native code stepper for lispworks?
Hi list!
When digging into lispworks compiled functions, I found that there is
vector attached to every function, which maps code offsets into source
"offsets". This vector seem to be used by debugger when finding a
source of a frame.
I wonder is there a way to implement native code stepper this way?
Lispworks instrumentation based stepper is fine, but it has some
disadvanteges. Consider the following example:
#.(defpackage :test3
(:use :cl))
(in-package :test3)
(defun steppable (x)
(+ x 1))
(defun nonsteppable (x)
(+ (steppable x) (steppable x)))
if I put breakpoint in "steppable" and then call "nonsteppable", I'm
unable to continue stepping out of steppable function. When I write
just (break) somewhere, I unable continue stepping. And so on. Next, I
guess stepper uses an interpreter. If code contains compiler-macros,
its behaviour can differ in stepped code and in truly compiled one.
Combined, these disadvantages make stepper very inconvinient compared
e.g. to Delphi (and, likely, C#, Visual Basic etc...) source level
debuggers. Yes, I'm aware of trace, incremental development, logging,
restarting frames, but there is still some essential inconvinience.
I have made some experimens. I was able to alter compiled machine code
and put int 3 instruction into it (32bit Windows):
(in-package :cl-user)
(defun extract-address-from-function (function)
"Stupid: extract function address from printed representation"
(assert (functionp function))
(let* ((text (format nil "~A" function))
(length (length text))
(offset (- length 9))
(hex-address (subseq text offset (+ offset 8)))
(*read-base* 16)
(address (read-from-string hex-address)))
address))
(defun poke (addr byte)
(setf (fli:dereference (fli:make-pointer :address addr :type :byte)) byte))
(cl-user::poke (+ (cl-user::extract-address-from-function
#'TEST3::nonsteppable) 28) #xCC)
This seem to be the first step to implement true native code
breakpoints. On a stack I found win32::exception-reentry-function, and
was able to return something from it, but stack was smashed. I guess
one need to create corrent int 3 handler, but I do not know how to do
this.
If I was able just to continue execution from int 3, this would be the
core of native code breakpoints and stepper implmenetation.
_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html