🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.smalltalk.bug
Article #3

Getting stack backtrace from ST code

#3
From: Steve Byrne
Date: Tue, 27 Oct 1992 06:26
98 lines
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.Byrne
References: <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