Article View: gnu.smalltalk.bug
Article #3Getting stack backtrace from ST code
From: Steve Byrne
Date: Tue, 27 Oct 1992 06:26
Date: Tue, 27 Oct 1992 06:26
98 lines
4944 bytes
4944 bytes
Mark Bush writes:
> I am trying to obtain a context stack backtrace from within smalltalk code
> itself. I've added messages to enable the extraction of the relevant
> instance variables to MethodContext and BlockContext.
>
> For the following, assume that the above mentioned classes have the
> obviously named selectors for extracting the instance variables.
>
> There are circumstances that a:
>
> Processor activeProcess suspendedContext
>
> will then enable me to work my way down the stack when subsequently
> inspected through a new process. However, I get some very strange results
> depending on the context in which I evaluate the above and I suspect this is
> due to the fact that new contexts are appearing for every message send. One
> attempt using a whileTrue: type of looping mechanism got me in an infinite
> loop because, I presume, every time through the loop, the context I was
> looking at got further `away', so the next iteration meant I was pointing at
> the same context as the previous time. No doubt this is all because of the
> manner in which the pointers representing the contexts are managed in the
> interpreter.
This is a good try, but I think you are working too hard! From t.st in
the 1.1.1 distribution:
!Object methodsFor: 'testing'!
test
| x |
x _ [ :dummy | "thisContext inspect.
Smalltalk backtrace."
thisContext backit ].
" x inspect."
x value: 3
!
backit
| n context |
n _ 0.
context _ thisContext.
[ context notNil ] whileTrue: [ n _ n + 1. context _ context parentContext ].
context _ thisContext.
n to: 1 by: -1 do:
[ :i | context receiver print.
'>>' print.
context selector printNl.
context _ context parentContext ].
!!
Note the clever use of "thisContext" -- it seems that for the case you are
trying to work with, you are interested in the current context, as opposed to
some other process's context, so this should work fine. I am not sure
that you need to go about iterating back through the contexts this way; you
may be able to use one of the standard iterators to traverse the context
stack; I just don't remember.
> Now...looking at the interpreter code gives me a headache. I thought about
> changing the `SystemDictionary backtrace' primitive to return a Collection
> (of some sort) of references to the information in the contexts (at this
> stage just the strings that would normally be printed would do), however I
> am not sure how to generate Collections from within the C code.
It's not easy -- I generally just create Arrays since there is support
in mstdict.c for that.
> The reason I want this is that I have just finished implementing classes
> such as Form, BitBlt, DisplayObject, DisplayScreen, Controller, etc... and I
> now want all output that would normally go to stdout to be redirectable.
> For this, I need to reimplement in smalltalk code a number of primitives.
> So, for example, I have reimplemented `doesNotUnderstand:' as:
>
> doesNotUnderstand: message
> | aString |
> Smalltalk backtrace.
> aString := self printString, ' does not understand selector '''.
> (message isKindOf: Message)
> ifTrue: [ aString := aString, message selector printString ]
> ifFalse: [ aString := aString, message printString ].
> self notify: aString
> !
>
> where `notify:' is defined to open a Notifier window displaying the
> appropriate message in the titlebar. I want this notifier window to show
> the backtrace, rather than have it printed to the terminal. (And yes, I
> eventually want to be able to manipulate the contexts on the stack in a
> Debugger window. 8*)
Great!!!! This is wonderful news. You'll be happy to know that I am working
on some more speed improvements for 1.2: removing the OOP table, dealing with
method context allocation better (so it no longer involves any copying when
they are "realized"), and some other minor things. I don't know how much of an
undertaking this will turn out to be, and how much speed it will add, but I
think it should be noticeable. Also, I'm trying to get the conditional code
out of the interpret() routine, so that the cycle is just
fetch/dispatch/execute, but I don't know yet if I will succeed in this effort.
Steve
Technical Details
Message-ID:
<9210270626.AA07842@laplace.Eng.Sun.COM>Path:
arc1-ca.pugleaf.net!sparky!uunet!convex!darwin.sura.net!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!eng.SUn.COM!Steven.ByrneReferences:
<1992Oct21.180646.17072@thom5.ecsthom5.ecs>Show Full Headers
Complete Article Headers
Newsgroups: gnu.smalltalk.bug Path: arc1-ca.pugleaf.net!sparky!uunet!convex!darwin.sura.net!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!eng.SUn.COM!Steven.Byrne From: Steven.Byrne@eng.SUn.COM (Steve Byrne) Subject: Getting stack backtrace from ST code Message-ID: <9210270626.AA07842@laplace.Eng.Sun.COM> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet References: <1992Oct21.180646.17072@thom5.ecsthom5.ecs> Distribution: gnu Date: Tue, 27 Oct 1992 06:26:09 GMT Approved: bug-smalltalk@prep.ai.mit.edu Lines: 99