[Openmcl-devel] Trying to build a single stepper

73budden . budden73 at gmail.com
Thu Jan 18 09:31:16 PST 2018

It looks like I found a proper place to patch. *x862-constant-alist*
is a variable where I can associate any data with a function to be
generated, and x86-immediate-label is a proper primitive to use for
that. I don't quite understand what it does, but as a side effect, a
constant is created so I have a place where to store indices of
function refrences amongst all function "constants".

2018-01-18 19:47 GMT+03:00, 73budden . <budden73 at gmail.com>:
> Hi!
> Thanks, Bill, I was thinking about coverage tool, and it was my
> previous plan. Coverage inserts movs, so if I watch the destination of
> this mov, this is a breakpoint. I made a prototype and was able to
> break and see variables. Next step would be to coalesce all code-notes
> and thus I would obtain a "step on/off" flag.
> But it is less convenient because one has to recompile a function to
> make it steppable. Recompilation is context dependent in CL, hence
> recompiled function can yield e.g. different macroexpansion. So if
> there is a way to instrument/uninstrument a function w/o
> recompilation, it is preferrable. Also this watch based approach hurts
> performance more than my current idea.
> Actually what I do now is not perfect. Calls to CONS, LIST and some
> other things are inlined, so they won't be steppable. But I guess
> anyway it would be good as a starting point and I have rather limited
> time period for that work.
> Maybe coverage tool would be useful for setting breakpoint with a
> mouse, because I would need to find a place in a code which
> corresponds to current place in a source file. Code coverage tool
> contains this data.
> Ron, thanks, I know about advice, but it is global. Making a wrapper
> only hurts a performance where it is used, and does not touch other
> uses of PRINT. Not only wrapper function is faster, it is more
> reliable too. Advising print and other system things is always
> dangerous. But maybe I'll find useful code snippets to borrow from the
> advice, thanks.
> Meanwhile you can take a look at the similar proof-of-concept I made
> for Lispworks some time ago. Lispworks rebuild a function to be
> stepped in an interpreter, so it is not quite reliable approach. I did
> something, but it is extremely hard to change anything in a closed
> source program.
> https://bitbucket.org/budden/budden-tools/src/default/experiments/hack-debugger/native-code-stepper.lisp?at=default&fileviewer=file-view-default
> 2018-01-18 19:29 GMT+03:00, Bill St. Clair <wws at clozure.com>:
>> The thought has occurred to me that the coverage tool that Gail Zacharias
>> wrote a number of years back could be extended to a single stepper. It
>> would be a fair amount of work, and would require pretty deep
>> understanding
>> of CCL internals, but it would enable single-stepping of compiled code.
>> On Thu, Jan 18, 2018 at 11:17 AM, Ron Garret <ron at flownet.com> wrote:
>>> Rather than write your own wrapper you should consider using the advice
>>> facility built in to CCL:
>>> https://ccl.clozure.com/manual/chapter4.3.html#Advising
>>> On Jan 18, 2018, at 7:41 AM, 73budden . <budden73 at gmail.com> wrote:
>>> > Hi!
>>> >
>>> > I'm trying to build a single stepper for compiled functions in CCL
>>> > (vanilla "Visual Basic" like "debugger").
>>> >
>>> > My current idea is to find all function references (subset of
>>> > ccl::lfunloop scope) and
>>> > replace all of them with function wrappers. E.g. I have a function
>>> > which I want to make steppable:
>>> >
>>> > (defun f () (print 'list))
>>> >
>>> > It references PRINT as a symbol.
>>> > (lfunloop for v in #'f do (print v)) returns:
>>> >
>>> > LIST
>>> > PRINT
>>> > F
>>> >
>>> > Then I do:
>>> > CCL>(compile (defun my-wrapped-print (&rest args) (break "About to
>>> > call print with ~S" args) (apply #'print args)))
>>> >
>>> > And
>>> > CCL>(%set-nth-immediate #'f 1 'MY-WRAPPED-PRINT)
>>> >
>>> > Then, when I run (f), debugger is invoked while trying to call
>>> > "print". In current example #'f is too trivial and it isn't shown on
>>> > the backtrace, but if we make more complex f and put it into the
>>> > source file, I can see its source with SWANK debugger.
>>> >
>>> > So the question is: how do I say 'print (which is used as a function)
>>> > from 'list (which is used as mere data). If I treat any symbol
>>> > reference as a function, this would be obviously wrong.
>>> >
>>> > As far as I can get it, I have to track how symbols are referenced. I
>>> > found already that #<acode immediate (PRINT)> is created in the
>>> > nx1-call-form, so I think I can extend acode to include the type of
>>> > reference. Also I found how info is extracted. So I can add a
>>> > bit-vector to a functions data which stores "1" if nth-immediate is a
>>> > function and 0 otherwise. But still I'm unable to find where this
>>> > immediate is recorded into the generated code, so I don't know how to
>>> > extend the set. Can anyone please give a hint?
>>> >
>>> > Also, if my approach is definitely wrong somehow, please let me know.
>>> > _______________________________________________
>>> > Openmcl-devel mailing list
>>> > Openmcl-devel at clozure.com
>>> > https://lists.clozure.com/mailman/listinfo/openmcl-devel
>>> _______________________________________________
>>> Openmcl-devel mailing list
>>> Openmcl-devel at clozure.com
>>> https://lists.clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list