Other Tools
This document is unfinished - there a quite a bunch of other tools to be documented ...
Transcript - The Smalltalk Messages Window
In smalltalk, the Transcript plays the role of a console,
where useful information is sent to. For example, the compiler
outputs progress information onto the transcript when compiling methods
from a file or from the browser.
From your programs, you can send output to the Transcript via the messages:
show:,
cr and
showCR:.
Here are a few concrete examples (click to execute):
Transcript showCR:'Hello World'.
Transcript clear.
Transcript show:'The time is '.
Transcript show:(Time now).
Transcript cr
or:
Transcript show:'The time is '; show:(Time now); cr
or:
Transcript
showCR:('The time is %1, today is %2'
bindWith: (Time now)
with: (Date today) )
In very old Smalltalk versions, the Transcript and Launcher (described below)
were two separate applications.
Today, these two applications have been merged into a new Launcher.
NewLauncher - Combined Launcher and Transcript Tool
The Launcher allows startup of commonly used tools and utilities,
and contains the transcript window for messages to the user.
This application offers pulldown menus and buttons to open
useful applications, monitors and to perform most common operations.
In addition, the language, viewStyle and compiler settings can be set
via more convenient dialogs
(in previous versions, these had to be set by evaluating Smalltalk
expressions in a workspace or by editing the startup scripts).
The launcher is typically started from your "private.rc"
startup file.
Starting with ST/X rev 3.3, the Launcher was completely rewritten,
using the new UI-builder framework.
The items found in the pullDown-menu
and the toolBar panel can now be changed using the convenient menu-editor;
i.e. it is very easy to create a user/project specific
subclass with different functions offered.
Also, the launchers functionality was moved to an abstract generic launcher superclass,
which does not provide any GUI, but is purely functional.
This architecture allows for future- and custom launchers to be build easily.
Workspace - A Tool for Expression Evaluation
Workspaces allow smalltalk expression to be entered and evaluated.
You can also use them as scratchpads or notepads for ordinary text.
Beside the general text editing features, Workspaces allow for Smalltalk code to
be evaluated (interpreted); to do this,
select some text which represents a valid smalltalk expression,
and use one of the following pop-menu functions for evaluation
(actually, if nothing is selected, the current cursor line is taken):
- doIt - To evaluate the expression
- printIt - To evaluate the expression and paste the result
- inspectIt - To evaluate the expression and open an inspectorView on the result
- browse - To evaluate the expression and open a browser on the results classes
There are also keyboard shortcuts for the above function - typically
"ALT-d" ,
"ALT-p" ,
"ALT-i" and
"ALT-Shift-B".
Depending on your keyboard settings file ("keyboard.rc"), the key assignments might be
different on your particular system.
If in doubt, consult the Launchers System-Settings-Keyboard dialog.
An ongoing expression evaluation can be interrupted and a debugger is opened
by pressing the Interrupt key, "CTRL-c" ("Break" or "Untbr" under Windows).
By pressing the Abort key, "CTRL-y",
an ongoing expression evaluation can be aborted (without going into a debugger).
Aborting means: 'raising an AbortSignal', which is cought in all views' eventLoop.
Starting with release 4.1 of ST/X, workspaces support multiple pages (aka "buffers" or "tabs")
and a pull down menu, with additional functions:
- TimeIt
show the execution time it takes to evaluate the selected expression
- SpyOnIt
show an execution trace (messageTally-spy) of the selected expressions evaluation
- Browse Implementors
open a browser on the selected message selectors implementors
- Browse Senders
open a browser on the selected message selectors senders
- Browse References
open a browser on methods which refer to the selected global variable name
In addition, WorkspaceVariables and DoItVariables have been added:
- WorkspaceVariables
These are much like global variables,
but only visible and known in the context of "doIt" evaluations
(i.e. NOT in a methods code).
Being shared among all workspaces, these are very useful to pass an object reference
from one workspace or inspector to another,
or to keep objects around for later use without a need to introduce new global variable names.
Of course, they also save you from the danger of overwriting a global name by accident.
- DoItVariables
These are like local variables,
and only visible and known in the context of one single "doIt" evaluation.
They do not add new functionality, but avoid the need to declare locals in a doIt evaluation.
The workspaces menu provides an item "Auto Define Variables" which can be checked
to force all unknown variables to be automatically declared as workspace or doIt variables.
If this option is turned off, undefined variables trigger an error message, as usual.
A special variant of the workspace is the so called "Evaluation Workspace".
This adds a separate view to show an evaluations result, and a list of currently defined
workspace variables, and the last few results in a history list.
The evaluation workspace can be opened from a regular workspace's pull down menu.
The set of sharedPools which are visible inside a doIt evaluation can be controlled by the
"Add SharedPool" and "Remove SharedPool" menu functions from
the "Workspace" section in the main menu.
Initially, no sharedPools are visible in a doIt evaluation.
You can add a private personalized page to the system workspace,
by creating a file named "MyWorkspace.wsp" in the ST/X startup directory.
There, you may keep commonly used expressions/doIts to start tools or applications.
If such a file exists, the WorkspaceApplication automatically adds another page to its tab-list
and presents the contents of that file there.
You can remember a piece of code as a so called "Code Sniplet"
These sniplets are shared among multiple workspaces and also retained in a class variable
(they are not lost, when a workspace window is closed).
However, they are only persistent inside the image, which means that there is not external file
persistency. If you forget to save a snapshot image, or you start st/x anew, these sniplets are lost.
The functions for sniplet handling are found in the "Edit" section in the main menu.
Click here for a
tutorial on workspaces, which is found
in the "Tutorial for Beginners".
Text edit functions are described in
the "Editing Text Section"
of the "Getting started Document".
Inspector - Looking into an Object
Introduction
Inspectors allow looking into an object. They usually consist of
2 subviews, one showing the names (and possibly indices) of the
objects instance variables, the other showing the value of the selected
instance variable.
There are some specialized inspectors (for example: image inspectors), which
add more subviews and/or show the object additionally in a more user friendly
form.
Opening an inspector
Inspectors can be started:
- by executing:
anObject inspect
or:
anObject basicInspect
to any object.
(see below for the difference between inspect
and basicInspect).
- by executing:
Inspector openOn:anObject
- by using the inspectIt-menu function in any codeview.
All codeviews allow inspecting the result of an expression evaluation,
by the inspectIt menu-entry
(there is also a keyboard abbreviation, such as CMD-i available).
- by double-clicking on a name entry in an inspector
Beside the obvious behavior, there are some special situations to consider:
- inspecting large collections
If the inspected object contains a large number of indexed instance variables,
only some of these are shown in the instance variable list initially (to save
some time during startup of the inspector).
In this case, the lists popup menu will contain an entry 'show more' to
increase (double) the number of instance variables shown.
- inspecting dictionaries
The variable list shown when dictionaries are inspected will show the
dictionaries keys instead of the raw (i.e. real) instance variables.
If this is not what you are interested in, use basicInspect:,
which will open an inspector without this behavior.
- updating after a change
To avoid overhead, inspectors do not update their list automatically.
To force an update (for example, after a collection has changed its
size) click on the self entry in the list.
This will both update the list
AND show the objects new printed representation in the value view.
Without updating, you may run into an index error (and therefore: a debugger),
if you select an entry in a collection which is no longer valid.
For example, try:
#(1 2 3) asOrderedCollection inspect
then, in the inspector, evaluate (doIt):
self grow:2
and finally click on the entry labeled '3' in the namelist.
Since the index 3 is no longer a legal one, you will run into a
debugger due to an index error.
To fix this, `continue' or `abort'
in the debugger, and force an update in the inspector by clicking on the self
entry.
- inspecting instances
Double clicking on a name/index in the instance variable list will open an
inspector on this instance variables value.
Examples (click to execute):
#('one' #two 3.0 4) inspect
#('one' #two 3.0 4) asOrderedCollection inspect
#('one' #two 3.0 4) asOrderedCollection basicInspect
( #('one' #two 3.0 4) asOrderedCollection removeFirst; yourself ) inspect
( #('one' #two 3.0 4) asOrderedCollection removeFirst; yourself ) basicInspect
(Image fromFile:'../../goodies/bitmaps/xpmBitmaps/smileys/smiley_angry.xpm') inspect
(Image fromFile:'../../goodies/bitmaps/xpmBitmaps/smileys/smiley_angry.xpm') basicInspect
(Color yellow) inspect
(Color yellow) basicInspect
(Array new:400) inspect
Inspect vs. basicInspect
Sending basicInspect to an object will always open a general inspector,
which shows instance variables as they are physically present in the inspected object.
In contrast, inspect is redefined in some classes to open an inspector showing
the logical contents.
In some collections, the physical implementation uses an extra collection to hold the contents.
Try inspecting an (nonempty) instance of Dictionary to see the difference:
|d|
d := Dictionary new.
d at:#foo put:1.
d at:#bar put:2.
d inspect.
d basicInspect.
or the differences in the inspectors of the above examples.
Process Monitor - Show & manipulate Smalltalk Processes
This tool displays a list of active Smalltalk processes (i.e. threads) and their current state.
Its popupMenu allows common operations to be applied to a process or a group of processes.
The process monitor is a very useful tool to find (and terminate or debug) leftover
background processes - especially during program development & debugging.
The fields are:
- Id - the processes ID; this number is assigned by the runtime system when
the process is created. Each process has a unique ID.
- Group - the process group ID; this is empty for process group leaders and
the ID of the group leader (the creator) for other processes.
The process group allows for easy termination of some process with all of
its subprocesses.
- Name - the processes name; this is provided for your convenience and has
no semantic meaning.
If no explicit name was ever given to the process, its the name and ID
of its creator with " sub" appended.
- State - the processes execution state. See definitions below.
- Prio - the processes execution priority.
The priority is an integer in the range 1..31. If two or more
processes are runnable, the system selects the highest priority process
for execution.
If the process has a dynamic priority range, the range is shown behind
its current priority (which may change).
- Where - the method in which the process is currently executing or
in which it was suspended (went sleeping).
The states shown are:
- run - the process is runnable (but CPU is not executing it)
- active - the CPU executes this process right now
- wait - the process is waiting on some semaphore
- ioWait - the process is waiting on a IO-semaphore
- wrapWait - the process is waiting in a blocking API call (win32 only)
- eventWait - the process is waiting on an eventQueue-semaphore
- timeWait - the process is waiting on a timer-semaphore
- suspended - the process is suspended, but not waiting on a semaphore
- stopped - manually stopped; like suspended, but will not respond to interrupts
- halted - stopped by CTRL-C (win32 only)
- light - the process has not yet started (it has no stack allocated yet)
- dead - the process has died (these are normally not shown)
The process which ran at the time of the update is marked with
an (*) character. If none is marked, the scheduler was active (or waiting
for an event).
Processes which ran during the last timeSlicing period (1/10th second) are marked
with a (+) character.
The list is updated every few seconds, so be prepared for some delayed
visibility of new processes.
A popup-menu (and tool-buttons in the new version)
allows for useful operations to be performed on a selected process:
- Inspect - opens an inspector on the selected process.
- Debug - opens a debugger on the selected process.
- Resume - resume execution of a suspended process
- Suspend - suspend execution of the process
notice, that the process may be resumed by the system due to a timer
or I/O event.
- Stop - stop execution of the process
timer or I/O events will not resume a stopped process
- Abort - send an AbortSignal to the process
all processes are supposed to return to a save place (typically the
main event handling loop) when an abortSignal arrives. This can be used to
force a process "out of" a long term (or endless) computation.
- Terminate - terminate the process
sends a TerminateSignal to the process; the process has a chance to
perform any cleanup (unwind) actions and is then removed from the system.
- Terminate group - terminate the process and all of its group members
use this to terminate a process which has created background processes.
(for example, a workspace in which subprocesses were forked)
- Hard Terminate - terminate the process without cleanup
immediately terminates the process, without giving it a chance
to perform any cleanup (unwind) actions.
Only use this, if a terminating process blocks in its unwind actions
(due to a bug or deadlock).
As there are no unwind actions performed, the process has no chance for any
proper cleanup and leftover resources, open streams or locked semaphores
are likely to be encountered afterwards. Be aware of this, and only use this
if a regular abort or terminate operation fails.
- Raise prio - raise the processes priority by one
- Lower priority - lower its priority by one
By holding down the "CTRL" key while pressing the middle button,
another popupMenu is opened, which allows toggling the display details
flag.
With details on, more info is shown (which you might not be interested in).
The additional information (among others) is:
- UsedStack - the size of the stack being in use by the process
- TotalStack - the size of the stack as allocated for the process
This is adjusted dynamically by the runtime system.
Other items are only of interest for ST/X runtime system debugging.
Probably the most useful item found is the debug function,
which opens an inspector-like debugger on the selected process.
This may be useful if some process is waiting on
a semaphore and you want to see exactly where the wait is and how it reached
it. With the debuggers monitor option, you can even watch & see what
that process is doing !
Note:
Since at the time of the view update,
the active process is always
the process monitor itself, the distinction between run and active
states is useless here: you will always see that process as being active
in the monitors display.
This tool displays a list of Smalltalk semaphores, their internal count
and the list of processes on its waiting list.
This tool is useful to debug deadlock or endless-wait situations in
multithread applications.
The columns shown are:
- Id - an internal id (actually, the semaphores hashKey)
- Name - the semaphores userFriendly name (if it has one)
- Count - the semaphores count (i.e. the number of waits that go through
without blocking)
- Owner - the processId of the process which was dropping the count to
zero the last time (i.e. which got the semaphore). This id is not cleared
when the process releases the semaphore - it stays set, even if the semaphore
is actually free. I.e. it giced the ID of the current or the last owner.
- Waiting processes - the number and names of process(es) waiting for the semaphore
to be signalled.
Memory Monitor - Displays overall Memory Usage
This utility displays the amount of object memory used by the system,
and displays various other statistic values.
Its popUpMenu offers functions to manually perform
either blocking- or nonBlocking background garbage collects.
Some of those functions are provided as debugging & measuring tools,
and not required by the typical user.
The numbers shown are (top to bottom):
- max - the maximum overall amount in bytes (since start of the monitor),
- tot - the current total amount of used memory (new + old + free)
- all - the current used amount of memory (new + old)
- new - the amount of newSpace used
- frl - the amount of memory in free lists (fragmented free space)
- fre - the unused portion of oldSpace (compact free space)
- old - the amount of oldSpace used
- min - the minimum overall amount (since start of the monitor)
the other numbers are less of interest to normal users, but give
some info to VM developers:
- t - the current dynamic tenureAge
- I - the internal state of the incremental garbage collector (2 = idle)
- weak - the number of weak objects
- rem - the number of objects in the remembered list (old->new crossrefs)
- lrem - the number of contexts in the lifo list (obj->stack crossrefs)
- minSc - scavengers worst case survivor percentage
- number of scavenges since system started
- % - the fill-grade of newSpace after the last scavenge
the graphic displays a history of the used amount. Newspace size
is shown in orange (light grey in b&w displays),
freelistspace in green (dark grey)
and oldspace in white.
The history is updated twice a second.
Use the key-commands 'f' (for faster) and 's' (for slower) to change
the update interval.
Pressing 'r' (for reset) rescales the display.
The typical picture shown is some saw-tooth figure;
memory use is usually growing until a new-space collection reduces the amount.
The memoryMonitor also provides a popup menu for common garbage collect
operations:
- collect garbage - perform a mark&sweep oldSpace collect.
the system will be blocked while doing this.
- collect garbage & symbols - like above, but reclaim unused symbols as well.
- collect garbage & compress - perform a compressing oldSpace collect.
the system will be blocked while doing this.
- background collect - perform a non blocking mark&sweep collect.
the system will continue to react, since this collect is performed
incrementally in the background.
This is executed at low priority; if other user processes (at normal priority)
are currently running, this garbage collect may not make any progress.
- reset statistic values - clears minSc & max amount
The others submenu allows less frequently needed operations
to be invoked:
- scavenge - perform a newSpace collect
- tenure - clean the newSpace; surviving objects
are immediately tenured into the oldSpace
- hi prio incremental collect - perform a non blocking mark&sweep collect.
the system will continue to react, since this collect is performed
incrementally in the background.
In contrast to the above ("background collect"),
the incremental garbage collect is performed at high prioriy and guaranteed
to make some progress.
- cleanup memory - sends all classes a
#lowSpaceCleanup
message, to have them free any cached or buffered data.
If your classes keep any recoverable objects in classVariables (caching),
these should implement this message and release these objects there.
- flush method history - flush method history
The method history (if enabled in the launchers "Source & Debugger"
settings dialog) keeps previous versions of changed methods.
Over time, this may take up a lot of memory and should be flushed
periodically by selecting this menu item.
- unload autoloaded classes - unloads all classes which were autoloaded
and changes them to become autoloaded again.
Use this, to remove examples, demos and games which are no longer needed.
- compress sources
this writes out all incore method source string to a file called
st.src and replaces the in memory strings by references
into this file. This reduces memory requirements after you have changed
(or filedIn) lots of code.
Be very careful in keeping this file
intact, unchanged and in sync with images.
Since your methods sources are no longer directly
available as string objects after doing this,
your methods source is lost, if this file gets corrupted.
(However, you still have your changes file around for emergency)
Memory usage - Displays Statistics on Memory Usage by Class
This utility
displays the amount of memory allocated by individual classes.
The display can be sorted by different criteria - use its popupMenu to
change this.
Since scanning the memory is a time consuming operation,
there is no automatic update of the list;
use the menus update function to manually update the display.
A memoryUsageView is useful to find memory leaks.
In Smalltalk, these are not caused by not freeing memory, but instead
by keeping references to objects in globals or class variables.
(so, if you find those leaks, dont blame it on the garbage collector;
the collector cannot free the memory as long as any reachable
reference to an object exists.)
The menu includes two very useful functions, which help in finding
those references:
- owners
which opens an
inspector on all objects owning references to instances of the
selected class
(showing the names/indices of the instance variables,
which hold a reference).
- ref chains
which displays chains of references from a global to instances of the
selected class.
Thus, if you have trouble finding out why some object is not garbage collected,
open a memory usage view, select the class and use the ref chains
menu function to find out how those instances are still references.
Notice, that the owners function will not be much of a help,
if the object in question is kept from being freed by a long
chain of references (for example, if its in a long linked list which is
anchored in a global variable).
Also notice, that the ref chains function may be very time consuming.
This tool lists the classes/methods/functions as contained in the loaded
dlls (shared libraries).
This is useful to find out version information in case of an error.
The tools menu also allows for a dll to be unloaded.
Its popUpMenu also provides a convenient way to get a modules version information into the clipBoard.
Event Monitor - Displays Events sent to a View
This tool is useful when keyboard mappings are changed or tested.
It outputs the
incoming event-messages on the standard output (xterm-window / console)
or alternatively to the Transcript.
(similar to the 'xev' XWindow utility).
To try it, open an EventMonitor, place the mouse pointer into it, and press
some key(s) on the keyboard. Watch the trace output.
An EventMonitor can also be started via the Launchers "System-EventMonitor" menu item.
This tool displays a views widget hierarchy graphically (Smalltalk views only).
When started via the launcher, a crosshair cursor is shown, and
you should click on some (smalltalk-) view on the screen.
That views widget hierarchy will then be displayed;
visible components are displayed in red color, invisible (i.e.
hidden or unmapped views) are drawn black.
The popupMenu shows various details about a selected widget
and allows further inspection.
A graphical viewTree can be opened via the launchers "Tools-Views"
pullDown menu; either on a single view (which is to be selected with
the mouse), or on all views.
cvs add: TOP.html already exists, with version number 1.48
Method Finder - Find a Selector by Argument & Result
A tool ported from squeak that can be started via the Laucher "classes-special-methodFinder".
Use an example to find a method in the system. Type receiver, args, and answer
in the top panes, like 4 5 1. Then press the search button. The lower left pane will show all
messages which - when send to the receiver 4 with an argument of 5 answer the value 1.
Try it again with a receiver of 'hello', and argument of 3 and an
answer of 'llo'.
You can write expressions in the fields to create a non-literal
object such as a Dictionary (rather than using strings and numbers).
In addition, a limited browser is included: selecting an item in the lower left pane
shows the implementors in the upper right pane; selecting any of the implementors will
display the methods code in the lower right pane (which is readOnly; i.e. no accept
is possible).
The methodFinder-GUI is actually using the MethodFinder-class to do the actual work.
This one provides even more search functionality.
For example, if you evaluate ("printIt") the following in a workspace
MethodFinder methodFor: #(
(4 3) 7
(0 5) 5
(5 5) 10)
it will discover (data1 + data2) - i.e. a message selector which satisfies all of the three
constraints.
Some fancy examples of its usefulness are:
| Receiver | Arg1 | Arg2 | Result | Finds this |
'knock knock' | $k | | 'noc noc' | 'knock knock' copyWithout: $k |
'30 apr 1999' asDate | | | 'friday' | '30 apr 1999' asDate weekday |
This tools was originally written by Ted Kaehler, Scott Wallace and Dan Ingalls for Squeak.
ToDo List - Tool to Remember Things to be Fixed
This tool monitors error and warning-messages from the compiler and displays them in a list.
Whenever a change is made to a class or a method, the TODO-list checks if any of those remembered
errors is now fixed. If that is the case, the entry is removed from the list.
The use of this tool is especially helpful while programming new code,
where some of the sent messages are not yet implemented.
A double click on an entry in the list will open a systembrowser and navigate it to
the corresponding code.
Notice: you can quickly check a class (or group of classes) by selecting them in a browser
and then performing the "Recompile-All-Methods" menu item in the classLists "Debug"
submenu, while a ToDo-List tool is open.
SUnit - Unit testing framework and TestRunner GUI
This framework (-> Kent Beck, Ward Cunningham and others) allows for convenient
component testing.
This tool was ported to ST/X by Samuel Shuster and Travis Triggs - thanks to you and
all other Camp Smalltalk freaks !
For automatic testing, testcases (subclasses of TestCase) should define a bunch of methods
named 'test*', which test various aspects of your code.
For checks, the inherited messages #assert:, #should, #shouldNot etc. should be used.
See the provided ExampleSetTest for more info on how to use this.
The TestRunner GUI interface automatically searches for all testCases as present in the system,
and offers execution via a convenient pull-down list:
After selection of the test, run its test-methods by pressing the Run-Button.
All failures will be collected and provided in the lower pull-down list for debugging.
Although simple, this is a very useful tool and we highly recommend its use -
it will make your life MUCH easier.
Please read some good book(s) on eXtreme programming or
Kent Becks original "Smalltalk Testing"" paper
for more information.
Using the TestRunner
The TestRunner is started either by double-clicking on a TestCase class in the browser,
by evaluating:
TestRunner open.
or via the launchers "Tools-SUnit" menu item.
- Refresh - Button
Press this button to update the list of offered testCases (in the TestCase-PullDown list)
(Use this after new testCases have been added, or when testCases have been filedIn/autoloaded).
- TestCase Selection - PullDown list
Select a particular TestCase to run.
- Run - Button
Executes all test* methods from the selected testCase; rememberes the results and changes the
information views background color to red, if any test failed or green, if all tests succeeded.
- ReRun Defects - Button
Re-Executes only the failed testCases from the previous run.
- RunAll - Button
Executes all testCases present in the system
- Defects - PullDown List
Displays failed testCases and allows for selective reRun with a debugger opening up at
point of failure.
- Browse - Button
Opens a SystemBrowser on the selected TestCase.
- Debug - Button
ReRun the selected failed testCase with a debugger opening up at point of failure (if it fails).
The main information window displays progress information (while executing testCases) and the final
result. Its color is changed to yellow while executing, and back to
green (if all ok) or red if any testCase failed.
Notice that some of the test runners functionality has also been built into the
new systembrowser.
Terminal - A Shell Terminal
This application provides a VT100 terminal emulation as an interface to the Operating
Systems command line interface (i.e. "shell" under Unix / "command.com" under DOS based systems).
Copyright © 1995 Claus Gittinger Development & Consulting, all rights reserved
<cg@exept.de>
Doc $Revision: 1.89 $ $Date: 2008/05/29 12:01:51 $