Myriam Abramson <mabra...@osf1.gmu.edu> writes: > Could somebody show me how to do a (trace-all) function or macro? > The code below does not work I guess because trace is a macro and > quotes its argument.
> Could somebody show me how to do a (trace-all) function or macro? > The code below does not work I guess because trace is a macro and > quotes its argument.
Myriam Abramson <mabra...@osf1.gmu.edu> writes: > Could somebody show me how to do a (trace-all) function or macro? > The code below does not work I guess because trace is a macro and > quotes its argument.
Maybe a better way would be to say that it doesn't evaluate its argument.
Or you could find out what function call trace expands to in your implementation, and funcall that, but that will not result in portable code.
That said, trace is already specified to take more than one function name:
(defun trace-all (fns) (eval `(trace ,@fns)))
So the only point in your trace-all function seems to be the ability to invoke it on arguments that are computed at run-time. Is that correct?
Regs, Pierre.
-- Pierre R. Mai <p...@acm.org> http://www.pmsf.de/pmai/ The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents. -- Nathaniel Borenstein
> > Could somebody show me how to do a (trace-all) function or macro? > > The code below does not work I guess because trace is a macro and > > quotes its argument. > [snip] > I think I would however expect a function named trace-all to trace > _all_ functions, something like
* "Coby Beck" <cb...@mercury.bc.ca> | I think I once did a (trace unread-char) without thinking and...well it | was a problem...
It would have been so much nicer if the Common Lisp system had not kept tracing functions called by the top-level loop itself, but had confined its tracing to the functions called by direct user request. The user is unlikely to want to debug the top-level loop, anyway.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
> * "Coby Beck" <cb...@mercury.bc.ca> > | I think I once did a (trace unread-char) without thinking and...well it > | was a problem...
> It would have been so much nicer if the Common Lisp system had not kept > tracing functions called by the top-level loop itself, but had confined > its tracing to the functions called by direct user request. The user is > unlikely to want to debug the top-level loop, anyway.
As it happens, trying to get this to work right was one of the very first things I tried to do when I was hired in the early days of Symbolics.
We never did manage to get 'trace' to work completely safely.
In article <3216666946227...@naggum.net>, Erik Naggum <e...@naggum.net> wrote:
>* "Coby Beck" <cb...@mercury.bc.ca> >| I think I once did a (trace unread-char) without thinking and...well it >| was a problem...
> It would have been so much nicer if the Common Lisp system had not kept > tracing functions called by the top-level loop itself, but had confined > its tracing to the functions called by direct user request. The user is > unlikely to want to debug the top-level loop, anyway.
Since it's unspecified what functions the top-level loop (or most built-in functions) calls, I think it would be conforming for an implementation to disable tracing while inside any of these things. I.e. since the implementation could call SYSTEM::READ-CHAR and SYSTEM::UNREAD-CHAR instead of COMMON-LISP:READ-CHAR and COMMON-LISP:UNREAD-CHAR inside the READ function, there's no reason for the user to expect that tracing these functions would result in any output from the top-level loop. Even if the implementation doesn't actually use separate functions for this, it could act as if it does since the user can't tell the difference.
I think I once crashed a Lisp Machine by tracing the wrong function. :)
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
"Coby Beck" <cb...@mercury.bc.ca> writes: > Which looks like a remarkably bad idea! : )
Unless it accepts a package argument - CMUCL provides something along those lines for profiling. (trace-all :package "COMMON-LISP") would still be a remarkable bad idea.
"Scott McKay" <s...@mediaone.net> writes: > "Erik Naggum" <e...@naggum.net> wrote in message > news:3216666946227155@naggum.net... > > * "Coby Beck" <cb...@mercury.bc.ca> > > | I think I once did a (trace unread-char) without thinking and...well it > > | was a problem...
> > It would have been so much nicer if the Common Lisp system had not kept > > tracing functions called by the top-level loop itself, but had confined > > its tracing to the functions called by direct user request. The user is > > unlikely to want to debug the top-level loop, anyway.
> As it happens, trying to get this to work right was one of the > very first things I tried to do when I was hired in the early days > of Symbolics.
> We never did manage to get 'trace' to work completely safely.
In ruminating over this common malady for Lisp programmers, and especially for Lisp implementors, I just thought of a great analogy (yeah, I know, it'll probably look really stupid tomorrow :-) :
Doing self-debugging, especially tracing, on any introspective system is like tweezing thorns or slivers out of one's own skin.
If you have a thorn or sliver in one of your hands, it is easy to get it out with a pair of tweezers in the other hand.
If the sliver is in your shoulder, it is a little harder, and you may need a mirror.
If the sliver is on your neck, you may need two mirrors and a lot of practice.
Debugging any function that works on *standard-input* is like trying to get a sliver out from on top of your eyelid (think about it).
Other languages like C or C++ are philosophically opposed to tweezing their own slivers; they have someone else (e.g. gdb or dbx) do the job. How do gdb and dbx do the job? They ask each other, or have a clone of themselves do it.
[The real answer to tracing unread-char is to only close one eyelid at a time - redirect *trace-output* to some other stream that is not *terminal-io*]
-- Duane Rettig Franz Inc. http://www.franz.com/ (www) 1995 University Ave Suite 275 Berkeley, CA 94704 Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
In article <4vgfjj17f....@beta.franz.com>, Duane Rettig <du...@franz.com> wrote:
>Other languages like C or C++ are philosophically opposed to >tweezing their own slivers; they have someone else (e.g. gdb or dbx) >do the job. How do gdb and dbx do the job? They ask each other, >or have a clone of themselves do it.
It's not so much the language as the OS and development environment. I used to use Multics, which was a PL/I machine, and PL/I is much more like C than it is like Lisp. However, the operating environment was similar to Lisp Machines, in that a login session is a single-process address space, and command invocation was implemented by dynamic linking and calling them as subroutines, rather than creating an independent process for each command. The debugger was introspective, much like it is in Lisp implementations; this meant that if you corrupted some critical parts of process memory (like the ones that the dynamic linker itself depends on) you might not be able to run the debugger.
For Lisp Machines, the solution when you need to have "someone else do the job", the answer is to use the FEP's DDT-style debugger. I once managed to use it to resurrect a machine after accidentally changing the value of NIL or T (SETQ had checks to make sure you didn't modify them, but SET didn't -- Symbolics fixed it in the following release by moving their value cells to read-only pages).
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <bar...@genuity.net> writes: > In article <4vgfjj17f....@beta.franz.com>, > Duane Rettig <du...@franz.com> wrote: > >Other languages like C or C++ are philosophically opposed to > >tweezing their own slivers; they have someone else (e.g. gdb or dbx) > >do the job. How do gdb and dbx do the job? They ask each other, > >or have a clone of themselves do it.
> It's not so much the language as the OS and development environment. I > used to use Multics, which was a PL/I machine, and PL/I is much more like C > than it is like Lisp. However, the operating environment was similar to > Lisp Machines, in that a login session is a single-process address space, > and command invocation was implemented by dynamic linking and calling them > as subroutines, rather than creating an independent process for each > command. The debugger was introspective, much like it is in Lisp > implementations; this meant that if you corrupted some critical parts of > process memory (like the ones that the dynamic linker itself depends on) > you might not be able to run the debugger.
Hmm. I can see your point, but I still contend that my point is a language issue, not an OS/environment one. That PL/I system you worked on had to have implemented an _extension_ of PL/I - it's been a _long_ time since I worked on PL/I, and you can correct me if I'm wrong, but I don't remember any such self-inspecting capabilities when I worked on PL/I on the IBM 360).
Compare/contrast that with Common Lisp, which indeed does define all of the language elements needed to do such self-inspection (e.g. trace, step, inspect, and it even gives examples for and interactions with the read-eval-print loop). In a sense, the CL spec defines enough of the environment _as_ _a_ _language_ to mandate such self-debuggability without extension.
-- Duane Rettig Franz Inc. http://www.franz.com/ (www) 1995 University Ave Suite 275 Berkeley, CA 94704 Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
>> In article <4vgfjj17f....@beta.franz.com>, >> Duane Rettig <du...@franz.com> wrote: >> >Other languages like C or C++ are philosophically opposed to >> >tweezing their own slivers; they have someone else (e.g. gdb or dbx) >> >do the job. How do gdb and dbx do the job? They ask each other, >> >or have a clone of themselves do it.
>> It's not so much the language as the OS and development environment. I >> used to use Multics, which was a PL/I machine, and PL/I is much more like C >> than it is like Lisp. However, the operating environment was similar to >> Lisp Machines, in that a login session is a single-process address space, >> and command invocation was implemented by dynamic linking and calling them >> as subroutines, rather than creating an independent process for each >> command. The debugger was introspective, much like it is in Lisp >> implementations; this meant that if you corrupted some critical parts of >> process memory (like the ones that the dynamic linker itself depends on) >> you might not be able to run the debugger.
>Hmm. I can see your point, but I still contend that my point is a >language issue, not an OS/environment one. That PL/I system you worked >on had to have implemented an _extension_ of PL/I - it's been a _long_ >time since I worked on PL/I, and you can correct me if I'm wrong, but I >don't remember any such self-inspecting capabilities when I worked on >PL/I on the IBM 360).
I'm not sure what you mean by this. There was a command "debug" to get into the debugger, analogous to Unix "dbx". The implementation of this just uses PL/I pointer variables to access the parts of memory that are being used by the program being debugged.
>Compare/contrast that with Common Lisp, which indeed does define all >of the language elements needed to do such self-inspection (e.g. trace, >step, inspect, and it even gives examples for and interactions with >the read-eval-print loop). In a sense, the CL spec defines enough of >the environment _as_ _a_ _language_ to mandate such self-debuggability >without extension.
It defines the high-level interfaces, but doesn't define the primitives needed to implement any of these things. I haven't thought it all through, but I think a possible implementation technique would be for them to spawn another process that uses the same mechanisms as gdb/dbx to watch what's happening in the process being monitored (e.g. the Unix ptrace system call). If it were done this way, you wouldn't have any problem if you traced a low-level, internal function.
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <bar...@genuity.net> writes: > In article <44rn2kfd3....@beta.franz.com>, > Duane Rettig <du...@franz.com> wrote: > >Barry Margolin <bar...@genuity.net> writes:
> >> In article <4vgfjj17f....@beta.franz.com>, > >> Duane Rettig <du...@franz.com> wrote: > >> >Other languages like C or C++ are philosophically opposed to > >> >tweezing their own slivers; they have someone else (e.g. gdb or dbx) > >> >do the job. How do gdb and dbx do the job? They ask each other, > >> >or have a clone of themselves do it.
> >> It's not so much the language as the OS and development environment. I > >> used to use Multics, which was a PL/I machine, and PL/I is much more like C > >> than it is like Lisp. However, the operating environment was similar to > >> Lisp Machines, in that a login session is a single-process address space, > >> and command invocation was implemented by dynamic linking and calling them > >> as subroutines, rather than creating an independent process for each > >> command. The debugger was introspective, much like it is in Lisp > >> implementations; this meant that if you corrupted some critical parts of > >> process memory (like the ones that the dynamic linker itself depends on) > >> you might not be able to run the debugger.
> >Hmm. I can see your point, but I still contend that my point is a > >language issue, not an OS/environment one. That PL/I system you worked > >on had to have implemented an _extension_ of PL/I - it's been a _long_ > >time since I worked on PL/I, and you can correct me if I'm wrong, but I > >don't remember any such self-inspecting capabilities when I worked on > >PL/I on the IBM 360).
> I'm not sure what you mean by this. There was a command "debug" to get > into the debugger, analogous to Unix "dbx". The implementation of this > just uses PL/I pointer variables to access the parts of memory that are > being used by the program being debugged.
dbx (and, I presume, "debug"), are not commands defined by their implementational languages, but perhaps implemented in them. CL's trace macro, however, is part of the language, where, though not highly specified, is in fact specified as a part of the langauge. A conforming PL/I implementation would get by without offering a "debug" program, and a conforming C implementation would get by without providing a "dbx" program, but a CL implementation that has no "trace" macro defined (in any way) is simply not conforming. That is what I mean by my statement that it is in fact a language issue, and not necessarily an os/evironment issue. It's because CL actually ties down some environment issues as a part of its language definition.
I don't want to get any more pedantic - it's really a fine point, in my opinion, and not worth wasting too much time on.
> >Compare/contrast that with Common Lisp, which indeed does define all > >of the language elements needed to do such self-inspection (e.g. trace, > >step, inspect, and it even gives examples for and interactions with > >the read-eval-print loop). In a sense, the CL spec defines enough of > >the environment _as_ _a_ _language_ to mandate such self-debuggability > >without extension.
> It defines the high-level interfaces, but doesn't define the primitives > needed to implement any of these things. I haven't thought it all through, > but I think a possible implementation technique would be for them to spawn > another process that uses the same mechanisms as gdb/dbx to watch what's > happening in the process being monitored (e.g. the Unix ptrace system > call). If it were done this way, you wouldn't have any problem if you > traced a low-level, internal function.
Yes, this is certainly a possible way to implement these features. However, since you are then calling on an operating system to handle some of the implementation, it becomes harder to make the interface portable. It's hard enough dealing with all those different hardware architectures as it is...
-- Duane Rettig Franz Inc. http://www.franz.com/ (www) 1995 University Ave Suite 275 Berkeley, CA 94704 Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
In article <4zo4uit4z....@beta.franz.com>, Duane Rettig <du...@franz.com> wrote:
>That is what I mean by my statement that it is in fact a language >issue, and not necessarily an os/evironment issue. It's because CL >actually ties down some environment issues as a part of its language >definition.
Yes, it's a silly thing to debate, but I'm having fun...
There's a C compiler for Symbolics Lisp Machines. You can trace C functions because this functionality is provided by the operating environment, even though the C language doesn't specify anything like this being available.
Suppose the C language required a debug_me() function. On a Lisp Machine this would presumably invoke the introspective debugger provided by the operating environment. On a Unix system I would expect it to fork a new process and run dbx there.
Common Lisp requires an ED function to invoke an editor. While some CL implementations have an embedded editor, I think quite a few simply implement this as an interface to an external editor; the only introspection involved might be writing the source code of the function to a temporary file.
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.