xref: /inferno-os/doc/dev.ms (revision 46439007cf417cbd9ac8049bb4122c890097a0fa)
1*46439007SCharles.Forsyth.TL
2*46439007SCharles.ForsythProgram Development under Inferno
3*46439007SCharles.Forsyth.AU
4*46439007SCharles.ForsythRoger Peppé
5*46439007SCharles.Forsythrog@vitanuova.com
6*46439007SCharles.Forsyth.SH
7*46439007SCharles.ForsythIntroduction
8*46439007SCharles.Forsyth.PP
9*46439007SCharles.ForsythInferno provides a set of programs that, used in
10*46439007SCharles.Forsythcombination, provide a powerful development environment
11*46439007SCharles.Forsythin which to write Limbo programs.
12*46439007SCharles.Forsyth.I Limbo (1)
13*46439007SCharles.Forsythis the compiler for the Limbo language; there
14*46439007SCharles.Forsythare versions that run inside and outside the Inferno
15*46439007SCharles.Forsythenvironment.
16*46439007SCharles.Forsyth.I Acme (1)
17*46439007SCharles.Forsythis an integrated window system and editor, and the
18*46439007SCharles.Forsythpreferred source-code editing tool within Inferno.
19*46439007SCharles.ForsythThe Limbo debugger,
20*46439007SCharles.Forsyth.I wm-debug (1),
21*46439007SCharles.Forsythallows interactive inspection of running Limbo programs.
22*46439007SCharles.Forsyth.I Stack (1)
23*46439007SCharles.Forsythallows a quick inspection of the execution stack of a
24*46439007SCharles.Forsythcurrently running process.
25*46439007SCharles.Forsyth.SH
26*46439007SCharles.ForsythGetting started
27*46439007SCharles.Forsyth.PP
28*46439007SCharles.ForsythThis document assumes that you have already managed
29*46439007SCharles.Forsythto install Inferno and have managed to obtain an Inferno
30*46439007SCharles.Forsythwindow, running the Inferno window manager,
31*46439007SCharles.Forsyth.I wm (1).
32*46439007SCharles.ForsythThe document
33*46439007SCharles.Forsyth\&``Installing Inferno'' in this volume has details on this.
34*46439007SCharles.ForsythIf running within emu, it is worth giving Inferno
35*46439007SCharles.Forsythas large a window as possible, as it cannot be resized later.
36*46439007SCharles.ForsythThis paper assumes that you are using a three-button mouse, as it is
37*46439007SCharles.Forsythnot feasible to use Acme without a three-button mouse.
38*46439007SCharles.Forsyth(if you have a two button mouse with a ``mouse wheel'',
39*46439007SCharles.Forsyththe wheel can be used as the middle button).
40*46439007SCharles.ForsythThe first thing to do is to get Acme going. By clicking
41*46439007SCharles.Forsython the Vita Nuova logo at the bottom left of the window,
42*46439007SCharles.Forsythyou can display a menu naming some preconfigured commands.
43*46439007SCharles.ForsythIf this has an ``Acme'' entry, then just clicking on that entry
44*46439007SCharles.Forsythwill start acme. If not, then click on the ``Shell'' entry,
45*46439007SCharles.Forsythand type
46*46439007SCharles.Forsyth.P1
47*46439007SCharles.Forsythacme
48*46439007SCharles.Forsyth.P2
49*46439007SCharles.Forsythto start it up. The Acme window should then appear,
50*46439007SCharles.Forsythfilling most of the screen (the window manager toolbar
51*46439007SCharles.Forsythshould still be visible).
52*46439007SCharles.Forsyth.SH
53*46439007SCharles.ForsythAcme basics
54*46439007SCharles.Forsyth.PP
55*46439007SCharles.ForsythFor a general overview and the rationale behind Acme, see ``Acme:
56*46439007SCharles.ForsythA User Interface for Programmers'', elsewhere in this volume,
57*46439007SCharles.Forsythand for detailed documentation, see
58*46439007SCharles.Forsyth.I acme (1).
59*46439007SCharles.ForsythThe basics are as follows:
60*46439007SCharles.Forsyth.PP
61*46439007SCharles.ForsythAcme windows are text-only and organised into columns.
62*46439007SCharles.ForsythA distinctive feature of Acme is that there are no graphical
63*46439007SCharles.Forsythtitle bars to windows; instead, each window (and additionally
64*46439007SCharles.Forsytheach column, and the whole Acme window itself) has
65*46439007SCharles.Forsytha textual
66*46439007SCharles.Forsyth.I tag ,
67*46439007SCharles.Forsythwhich can be edited at will, and is initially primed to contain
68*46439007SCharles.Forsytha few appropriate commands.
69*46439007SCharles.Forsyth.PP
70*46439007SCharles.ForsythAn Acme command is just represented by text; any textual
71*46439007SCharles.Forsythcommand word may be executed simply by clicking with the middle
72*46439007SCharles.Forsythmouse button on the word. (See ``Acme mouse commands'', below).
73*46439007SCharles.ForsythIf Acme recognizes the word that has been clicked on
74*46439007SCharles.Forsythas one of its internal commands (e.g. Put, Undo), then it will take the appropriate
75*46439007SCharles.Forsythaction; otherwise it will run the text as a shell command.
76*46439007SCharles.Forsyth(See
77*46439007SCharles.Forsyth.I sh (1)).
78*46439007SCharles.Forsyth.SH
79*46439007SCharles.ForsythAcme mouse commands
80*46439007SCharles.Forsyth.PP
81*46439007SCharles.ForsythMouse usage within Acme is somewhat more versatile
82*46439007SCharles.Forsyththan in most other window systems. Each of the three
83*46439007SCharles.Forsythmouse buttons has its own action, and there are also
84*46439007SCharles.Forsythactions bound to
85*46439007SCharles.Forsyth.I chords
86*46439007SCharles.Forsythof mouse buttons (i.e. mouse buttons depressed simultaneously).
87*46439007SCharles.ForsythMouse buttons are numbered from left (1) to right (3).
88*46439007SCharles.ForsythButton 1 follows similar conventions to other window systems -
89*46439007SCharles.Forsythit selects text; a double click will select a line if at the beginning or end
90*46439007SCharles.Forsythof a line, or match brackets if on a bracket character, or select
91*46439007SCharles.Forsytha word otherwise.
92*46439007SCharles.ForsythButton 2, as mentioned above, executes an
93*46439007SCharles.ForsythAcme command; a single click with button 2 will execute
94*46439007SCharles.Forsyththe single word under the click, otherwise the swept text
95*46439007SCharles.Forsythwill be executed.
96*46439007SCharles.ForsythButton 3 is a general ``look'' operator; if the text under the
97*46439007SCharles.Forsythclick represents a filename, then Acme will open a new
98*46439007SCharles.Forsythwindow for the file and read it in, otherwise it will search
99*46439007SCharles.Forsythwithin the current window for the next occurrence of the
100*46439007SCharles.Forsythtext.
101*46439007SCharles.ForsythClicking button 2 or button 3 on some text already selected
102*46439007SCharles.Forsythby button 1 causes the click to refer exactly to the text
103*46439007SCharles.Forsythselected, rather than gathering likely-looking characters
104*46439007SCharles.Forsythfrom around the click as is the default.
105*46439007SCharles.Forsyth.PP
106*46439007SCharles.ForsythThere are two mouse chord sequences which are
107*46439007SCharles.Forsythcommonly used in Acme (and you will find that some
108*46439007SCharles.Forsythother programs in the system also recognise these sequences,
109*46439007SCharles.Forsythe.g.
110*46439007SCharles.Forsyth.I wm-sh (1)).
111*46439007SCharles.ForsythThey are both available once some text
112*46439007SCharles.Forsythhas been selected by dragging the mouse with button 1,
113*46439007SCharles.Forsythbut before the button has been released. At this point,
114*46439007SCharles.Forsythtouching button 2 will delete the selected text and save
115*46439007SCharles.Forsythit in Acme's
116*46439007SCharles.Forsyth.I snarf
117*46439007SCharles.Forsythbuffer; clicking button 3 replaces the selected text with the contents
118*46439007SCharles.Forsythof the snarf buffer. Before button 1 has been released,
119*46439007SCharles.Forsyththese two buttons reverse each other's actions, so, for
120*46439007SCharles.Forsythexample, selecting some text with button 1, keeping button 1
121*46439007SCharles.Forsythheld down, then clicking button 2 and button 3 in succession,
122*46439007SCharles.Forsythwill save the selected text in the snarf buffer while leaving the
123*46439007SCharles.Forsythoriginal intact.
124*46439007SCharles.ForsythThe following table summarises the mouse commands in
125*46439007SCharles.ForsythAcme:
126*46439007SCharles.Forsyth.KS
127*46439007SCharles.Forsyth.TS
128*46439007SCharles.Forsythcenter box;
129*46439007SCharles.Forsythl l .
130*46439007SCharles.ForsythB1	Select text.
131*46439007SCharles.ForsythB2	Execute text.
132*46439007SCharles.ForsythB3	Open file or search for text.
133*46439007SCharles.ForsythB1-B2	Cut text.
134*46439007SCharles.ForsythB1-B3	Paste text.
135*46439007SCharles.ForsythB2-B3	Cancel the pending B2 action.
136*46439007SCharles.ForsythB3-B2	Cancel the pending B3 action.
137*46439007SCharles.Forsyth.TE
138*46439007SCharles.Forsyth.ce
139*46439007SCharles.Forsyth.I "Acme mouse command summary"
140*46439007SCharles.Forsyth.KE
141*46439007SCharles.Forsyth
142*46439007SCharles.Forsyth.SH
143*46439007SCharles.ForsythScrolling and resizing Acme windows
144*46439007SCharles.Forsyth.PP
145*46439007SCharles.ForsythThe scroll bars in Acme are somewhat different from
146*46439007SCharles.Forsythconventional scroll bars (including the scroll bars found
147*46439007SCharles.Forsythin other parts of Inferno). Clicking, or dragging, with
148*46439007SCharles.Forsythbutton-2 on the scrollbar acts the most like the conventional
149*46439007SCharles.Forsythbehaviour, namely that the further down the scroll bar
150*46439007SCharles.Forsythyou click, the further down the file you are shown.
151*46439007SCharles.Forsyth.PP
152*46439007SCharles.ForsythTrue to form, however, Acme doesn't omit to make
153*46439007SCharles.Forsyththe other buttons useful: button-1 and button-3
154*46439007SCharles.Forsythmove backwards and forwards through the file respectively.
155*46439007SCharles.ForsythThe nearer the top of the scrollbar the mouse, the
156*46439007SCharles.Forsythslower the movement. Holding one of these buttons
157*46439007SCharles.Forsythdown on the scrollbar will cause the scrolling motion
158*46439007SCharles.Forsythto auto-repeat, so it is easy to scroll gently through the
159*46439007SCharles.Forsythentire file, for instance.
160*46439007SCharles.Forsyth.PP
161*46439007SCharles.ForsythThe small square at the top left of each Acme window is
162*46439007SCharles.Forsyththe handle for resizing the window. Dragging this square
163*46439007SCharles.Forsythfrom one place to another (within Acme) will move the
164*46439007SCharles.Forsythwindow to the new place. A single button click in this square
165*46439007SCharles.Forsythwill grow the window: button 1 grows it a little bit; button 2
166*46439007SCharles.Forsythgrows it as much as possible without obscuring the other
167*46439007SCharles.Forsythwindow titles in the column; button 3 grows it so it covers
168*46439007SCharles.Forsyththe whole column (all other windows in the column are
169*46439007SCharles.Forsythobscured).
170*46439007SCharles.Forsyth.SH
171*46439007SCharles.ForsythCreating a new file
172*46439007SCharles.Forsyth.PP
173*46439007SCharles.ForsythAll Limbo programs are composed of
174*46439007SCharles.Forsyth.I modules
175*46439007SCharles.Forsythand each module is stored in its own file. To write a Limbo
176*46439007SCharles.Forsythprogram, you need to write at least one module,
177*46439007SCharles.Forsyththe Limbo
178*46439007SCharles.Forsyth.I "source file" ,
179*46439007SCharles.Forsythwhich will then be compiled into Dis code which can
180*46439007SCharles.Forsyththen be run by the Inferno Virtual Machine (VM).
181*46439007SCharles.ForsythThe first step is to decide where to store the file.
182*46439007SCharles.ForsythWhen Acme starts up, it creates a new window containing
183*46439007SCharles.Forsytha list of all the files in the directory in which it was started
184*46439007SCharles.Forsyth(usually your home directory). As a consequence of the
185*46439007SCharles.Forsythmouse rules above, a click of button-3 on any of those
186*46439007SCharles.Forsythfilenames in that window will open a new window
187*46439007SCharles.Forsythshowing that file or, if it is a directory, a list of the
188*46439007SCharles.Forsythfiles and directories it contains.
189*46439007SCharles.Forsyth.PP
190*46439007SCharles.ForsythAn important aspect in Acme's mouse commands, is
191*46439007SCharles.Forsyththat the command is interpreted
192*46439007SCharles.Forsyth.I "relative to the window's current directory",
193*46439007SCharles.Forsythwhere the current directory is determined from
194*46439007SCharles.Forsyththe filename in the window's tag. For instance,
195*46439007SCharles.ForsythAcme commands executed in the tag or body of
196*46439007SCharles.Forsytha window on the file
197*46439007SCharles.Forsyth.CW "/usr/joebloggs/myfile.txt"
198*46439007SCharles.Forsythwould run in the directory
199*46439007SCharles.Forsyth.CW /usr/joebloggs .
200*46439007SCharles.Forsyth.PP
201*46439007SCharles.ForsythSo, to create a new file in Acme, first open the
202*46439007SCharles.Forsythdirectory in which to create the file. (If this is
203*46439007SCharles.Forsythyour home directory, then it's probably already on the screen;
204*46439007SCharles.Forsythotherwise, you can just type (anywhere) the name of
205*46439007SCharles.Forsyththe directory, and button-3 click on it. If the directory
206*46439007SCharles.Forsythdoes not exist, then no window will be created.
207*46439007SCharles.ForsythThen, within the directory's window or its tag,
208*46439007SCharles.Forsythchoose a name,
209*46439007SCharles.Forsyth.I filename ,
210*46439007SCharles.Forsythfor your file (I'll use
211*46439007SCharles.Forsyth.CW myprog
212*46439007SCharles.Forsythfrom here on,
213*46439007SCharles.Forsythfor explanatory convenience)
214*46439007SCharles.Forsyth, type the text:
215*46439007SCharles.Forsyth.P1
216*46439007SCharles.ForsythNew \fIfilename\fP.b
217*46439007SCharles.Forsyth.P2
218*46439007SCharles.Forsythselect this text (the Escape key can also be used to highlight
219*46439007SCharles.Forsythtext that you have just typed), and button-2 click on it.
220*46439007SCharles.ForsythThis should create a new empty window in which you
221*46439007SCharles.Forsythcan edit your Limbo source file. It will also create a
222*46439007SCharles.Forsythwindow giving a warning that the file does not
223*46439007SCharles.Forsythcurrently exist - you can get rid of this by clicking
224*46439007SCharles.Forsythwith button-2 on the text
225*46439007SCharles.Forsyth.CW Del
226*46439007SCharles.Forsythin the tag of that window.
227*46439007SCharles.Forsyth.SH
228*46439007SCharles.ForsythEditing the source file
229*46439007SCharles.Forsyth.PP
230*46439007SCharles.ForsythYou can now edit text in the new window.
231*46439007SCharles.ForsythType in the following program:
232*46439007SCharles.Forsyth.P1
233*46439007SCharles.Forsythimplement Myprog;
234*46439007SCharles.Forsythinclude "sys.m";
235*46439007SCharles.Forsyth	sys: Sys;
236*46439007SCharles.Forsythinclude "draw.m";
237*46439007SCharles.Forsyth
238*46439007SCharles.ForsythMyprog: module {
239*46439007SCharles.Forsyth	init: fn(nil: ref Draw->Context, argv: list of string);
240*46439007SCharles.Forsyth};
241*46439007SCharles.Forsyth
242*46439007SCharles.Forsythinit(nil: ref Draw->Context, argv: list of string)
243*46439007SCharles.Forsyth{
244*46439007SCharles.Forsyth	sys = load Sys Sys->PATH;
245*46439007SCharles.Forsyth	sys->print("Hello, world\en");
246*46439007SCharles.Forsyth}
247*46439007SCharles.Forsyth.P2
248*46439007SCharles.ForsythWhen typing it in, note that two new commands have appeared
249*46439007SCharles.Forsythin the tag of the new window:
250*46439007SCharles.Forsyth.CW Put
251*46439007SCharles.Forsythand
252*46439007SCharles.Forsyth.CW Undo .
253*46439007SCharles.Forsyth.CW Put
254*46439007SCharles.Forsythsaves the file;
255*46439007SCharles.Forsyth.CW Undo
256*46439007SCharles.Forsythundoes the last change to the file, and successive
257*46439007SCharles.Forsythexecutions of
258*46439007SCharles.Forsyth.CW Undo
259*46439007SCharles.Forsythwill move further back in time. In case you move
260*46439007SCharles.Forsythtoo far back accidentally, there is also
261*46439007SCharles.Forsyth.CW Redo ,
262*46439007SCharles.Forsythwhich redoes a change that you have just undone.
263*46439007SCharles.ForsythChanges in the body of any window in Acme can be undone
264*46439007SCharles.Forsyththis way.
265*46439007SCharles.Forsyth.PP
266*46439007SCharles.ForsythClick with button-2 on the
267*46439007SCharles.Forsyth.CW Put
268*46439007SCharles.Forsythcommand, and the file is now saved and ready to be
269*46439007SCharles.Forsythcompiled. If you have problems at this point (say
270*46439007SCharles.ForsythAcme complains about not being able to write the
271*46439007SCharles.Forsythfile), you have probably chosen an inappropriate
272*46439007SCharles.Forsythdirectory, one in which you do not have write permission,
273*46439007SCharles.Forsythin which to put the file. In this case you can change the
274*46439007SCharles.Forsythname of the file simply by editing its name in the window's
275*46439007SCharles.Forsythtag, and clicking on
276*46439007SCharles.Forsyth.CW Put
277*46439007SCharles.Forsythagain.
278*46439007SCharles.Forsyth.SH
279*46439007SCharles.ForsythCompiling the source file
280*46439007SCharles.Forsyth.PP
281*46439007SCharles.ForsythNow, you are in a position to compile the Limbo program.
282*46439007SCharles.ForsythAlthough you can execute the Limbo compiler directly
283*46439007SCharles.Forsythfrom the tag of the new file's window, it is usually more
284*46439007SCharles.Forsythconvenient to do it from a shell window. To start a shell
285*46439007SCharles.Forsythwindow, type
286*46439007SCharles.Forsyth.CW win '' ``
287*46439007SCharles.Forsythat the right of the tag of the new file's window, select
288*46439007SCharles.Forsythit, and click with button-2 on it.
289*46439007SCharles.ForsythA new window should appear showing a shell prompt (usually
290*46439007SCharles.Forsyth.CW "; " '' ``
291*46439007SCharles.Forsythor
292*46439007SCharles.Forsyth.CW "% " ''). ``
293*46439007SCharles.ForsythAt this, you can type any of the commands mentioned
294*46439007SCharles.Forsythin Section 1 of the Programmer's Manual.
295*46439007SCharles.ForsythNote that, following Acme's usual rule, the shell has
296*46439007SCharles.Forsythstarted up in the same directory as the new file;
297*46439007SCharles.Forsythtyping
298*46439007SCharles.Forsyth.P1
299*46439007SCharles.Forsythlc
300*46439007SCharles.Forsyth.P2
301*46439007SCharles.Forsythat the prompt will show all the files in the directory,
302*46439007SCharles.Forsythincluding hopefully the newly written Limbo file.
303*46439007SCharles.Forsyth.PP
304*46439007SCharles.ForsythType the following command to the shell:
305*46439007SCharles.Forsyth.P1
306*46439007SCharles.Forsythlimbo -g myprog.b
307*46439007SCharles.Forsyth.P2
308*46439007SCharles.ForsythIf you typed in the example program correctly,
309*46439007SCharles.Forsyththen you'll get a short pause, and then another shell
310*46439007SCharles.Forsythprompt. This indicates a successful compilation (no
311*46439007SCharles.Forsythnews is good news), in which case you will now have
312*46439007SCharles.Forsythtwo new files in the current directory,
313*46439007SCharles.Forsyth.CW myprog.sbl
314*46439007SCharles.Forsythand
315*46439007SCharles.Forsyth.CW myprog.dis .
316*46439007SCharles.ForsythThe
317*46439007SCharles.Forsyth.CW -g
318*46439007SCharles.Forsythoption to the
319*46439007SCharles.Forsyth.CW limbo
320*46439007SCharles.Forsythcommand directed it to produce the
321*46439007SCharles.Forsyth.CW myprog.sbl
322*46439007SCharles.Forsythfile, which contains symbolic information
323*46439007SCharles.Forsythrelating the source code to the Dis executable file.
324*46439007SCharles.ForsythThe
325*46439007SCharles.Forsyth.CW myprog.dis
326*46439007SCharles.Forsythfile contains the actual executable file.
327*46439007SCharles.ForsythAt this point, if you type
328*46439007SCharles.Forsyth.CW lc ,
329*46439007SCharles.Forsythto get a listing of the files in the current directory,
330*46439007SCharles.Forsythand then click with button-2 on the
331*46439007SCharles.Forsyth.CW myprog.dis
332*46439007SCharles.Forsythfile, and you should see the output ``Hello, world''.
333*46439007SCharles.ForsythYou could also just type
334*46439007SCharles.Forsyth.CW myprog
335*46439007SCharles.Forsythat the shell prompt.
336*46439007SCharles.Forsyth.PP
337*46439007SCharles.ForsythIf you are normal, however, the above compilation
338*46439007SCharles.Forsythprobably failed because of some mistyped characters
339*46439007SCharles.Forsythin the source code; and for larger newly created programs,
340*46439007SCharles.Forsythin my experience, this
341*46439007SCharles.Forsythis almost invariably the case.
342*46439007SCharles.ForsythIf you got no errors in the above
343*46439007SCharles.Forsythcompilation, try changing
344*46439007SCharles.Forsyth.CW sys->print
345*46439007SCharles.Forsythto
346*46439007SCharles.Forsyth.CW print ,
347*46439007SCharles.Forsythsaving the file again,
348*46439007SCharles.Forsythand continue with the next section.
349*46439007SCharles.Forsyth.SH
350*46439007SCharles.ForsythFinding compilation errors
351*46439007SCharles.Forsyth.PP
352*46439007SCharles.ForsythWhen the Limbo compiler finds errors, it prints
353*46439007SCharles.Forsyththe errors, one per line, each one looking something
354*46439007SCharles.Forsythlike the following:
355*46439007SCharles.Forsyth.P1
356*46439007SCharles.Forsythmyprog.b:13: print is not declared
357*46439007SCharles.Forsyth.P2
358*46439007SCharles.ForsythThis shows the filename where the error has occurred,
359*46439007SCharles.Forsythits line number in the file, and a description of the error.
360*46439007SCharles.ForsythAcme's button-3 mouse clicking makes it extremely easy
361*46439007SCharles.Forsythto see where in the source code the error has occurred.
362*46439007SCharles.ForsythClick with button-3 anywhere in the filename on the
363*46439007SCharles.Forsythline of the compilation error, and Acme will automatically
364*46439007SCharles.Forsythtake the cursor to the file of that name and highlight
365*46439007SCharles.Forsyththe correct line.
366*46439007SCharles.Forsyth.PP
367*46439007SCharles.ForsythIf there had been no currently appropriate open Acme
368*46439007SCharles.Forsythwindow representing the file, then a new one would
369*46439007SCharles.Forsythbe created, and the appropriate line selected.
370*46439007SCharles.Forsyth.PP
371*46439007SCharles.ForsythEdit
372*46439007SCharles.Forsyth.CW myprog.b
373*46439007SCharles.Forsythuntil you have a program that compiles successfully
374*46439007SCharles.Forsythand produces the ``Hello, world'' output.
375*46439007SCharles.ForsythFor a program as simple as this, that's all there
376*46439007SCharles.Forsythis to it - you now know the essential stages involved in
377*46439007SCharles.Forsythwriting a Limbo program; there's just the small matter
378*46439007SCharles.Forsythof absorbing the Limbo language and familiarising
379*46439007SCharles.Forsythyourself with the libraries (``The Limbo Programming Language''
380*46439007SCharles.Forsythelsewhere in this volume,
381*46439007SCharles.Forsythand
382*46439007SCharles.Forsyth.I intro (2)
383*46439007SCharles.Forsythare the two essential starting points here).
384*46439007SCharles.Forsyth.SH
385*46439007SCharles.ForsythFinding run-time errors
386*46439007SCharles.Forsyth.PP
387*46439007SCharles.ForsythFor larger programs, there is the problem of programs
388*46439007SCharles.Forsyththat die unexpectedly with a run-time error. This
389*46439007SCharles.Forsythwill happen when, for instance, a Limbo program uses a reference
390*46439007SCharles.Forsyththat has not been initialised, or refers to an out-of-bounds
391*46439007SCharles.Forsytharray element.
392*46439007SCharles.Forsyth.PP
393*46439007SCharles.ForsythWhen a Limbo program dies with a run-time exception,
394*46439007SCharles.Forsythit does not go away completely, but remains hanging
395*46439007SCharles.Forsytharound, dormant, in a
396*46439007SCharles.Forsyth.I broken
397*46439007SCharles.Forsythstate; the state that it was in when it died may
398*46439007SCharles.Forsythnow be examined at leisure. To experiment with this,
399*46439007SCharles.Forsythedit the Myprog module above to delete the line
400*46439007SCharles.Forsyththat loads the
401*46439007SCharles.Forsyth.CW Sys
402*46439007SCharles.Forsythmodule
403*46439007SCharles.Forsyth.CW "sys = load Sys" ...), (
404*46439007SCharles.Forsythand recompile the program.
405*46439007SCharles.Forsyth.PP
406*46439007SCharles.ForsythThis time when you come to run
407*46439007SCharles.Forsyth.CW myprog ,
408*46439007SCharles.Forsythit will die, printing a message like:
409*46439007SCharles.Forsyth.P1
410*46439007SCharles.Forsythsh: 319 "Myprog":module not loaded
411*46439007SCharles.Forsyth.P2
412*46439007SCharles.ForsythThe number
413*46439007SCharles.Forsyth.CW 319
414*46439007SCharles.Forsythis the
415*46439007SCharles.Forsyth.I "process id"
416*46439007SCharles.Forsyth(or just
417*46439007SCharles.Forsyth.I pid )
418*46439007SCharles.Forsythof the broken process. The command
419*46439007SCharles.Forsyth.CW ps ,
420*46439007SCharles.Forsythwhich shows all currently running processes,
421*46439007SCharles.Forsythcan be used at this point - you will see a line like this:
422*46439007SCharles.Forsyth.P1
423*46439007SCharles.Forsyth     319      245        rog     broken    64K Myprog
424*46439007SCharles.Forsyth.P2
425*46439007SCharles.ForsythThe first number is the pid of the process;
426*46439007SCharles.Forsyththe second is the
427*46439007SCharles.Forsyth.I "process group"
428*46439007SCharles.Forsythid of the process; the third field gives the
429*46439007SCharles.Forsythowner of the process; the fourth gives its state
430*46439007SCharles.Forsyth(broken, in this case); the fifth shows the current
431*46439007SCharles.Forsythsize of the process, and the last gives the name
432*46439007SCharles.Forsythof the module that the process is currently running.
433*46439007SCharles.Forsyth.PP
434*46439007SCharles.ForsythThe
435*46439007SCharles.Forsyth.CW stack
436*46439007SCharles.Forsythcommand can be used to quickly find the line
437*46439007SCharles.Forsythat which the process has broken; type:
438*46439007SCharles.Forsyth.P1
439*46439007SCharles.Forsyth	stack \fIpid\fP
440*46439007SCharles.Forsyth.P2
441*46439007SCharles.Forsythwhere
442*46439007SCharles.Forsyth.I pid
443*46439007SCharles.Forsythis the number mentioned in the ``module not loaded''
444*46439007SCharles.Forsythmessage (319 in this case).
445*46439007SCharles.ForsythIt produces something like the following output:
446*46439007SCharles.Forsyth.P1
447*46439007SCharles.Forsythinit() myprog.b:12.1, 29
448*46439007SCharles.Forsythunknown fn() Module /dis/sh.dis PC 1706
449*46439007SCharles.Forsyth.P2
450*46439007SCharles.ForsythAs usual, a quick button-3 click on the
451*46439007SCharles.Forsyth.CW myprog.b
452*46439007SCharles.Forsythpart of the first line takes you to the appropriate
453*46439007SCharles.Forsythpart of the source file. The reason that the program
454*46439007SCharles.Forsythhas died here is that, in Limbo, all external modules
455*46439007SCharles.Forsythmust be explicitly loaded before they can be used; to
456*46439007SCharles.Forsythtry to call an uninitialised module is an error
457*46439007SCharles.Forsythand causes an exception.
458*46439007SCharles.Forsyth.SH
459*46439007SCharles.ForsythMore sophisticated debugging
460*46439007SCharles.Forsyth.PP
461*46439007SCharles.Forsyth.CW Stack
462*46439007SCharles.Forsythis fine for getting a quick summary of the state
463*46439007SCharles.Forsythin which a program has died, but there are
464*46439007SCharles.Forsythtimes when such a simple post-mortem analysis
465*46439007SCharles.Forsythis inadequate. The
466*46439007SCharles.Forsyth.CW wm/deb
467*46439007SCharles.Forsyth(see
468*46439007SCharles.Forsyth.I wm-deb\fR(1))\fP
469*46439007SCharles.Forsythcommand provides an interactive windowing
470*46439007SCharles.Forsythdebugger for such occasions.
471*46439007SCharles.ForsythIt runs outside Acme,
472*46439007SCharles.Forsythin the default window system. A convenient way
473*46439007SCharles.Forsythto start debugging an existing process is
474*46439007SCharles.Forsythto raise
475*46439007SCharles.Forsyth.CW wm/task
476*46439007SCharles.Forsyth(``Task Manager'' on the
477*46439007SCharles.Forsythmain menu), select with the mouse the process
478*46439007SCharles.Forsythto debug, and click ``Debug''. This will start
479*46439007SCharles.Forsyth.CW wm/deb
480*46439007SCharles.Forsython that process. Before it can start, the debugger will ask
481*46439007SCharles.Forsythfor the names of any source files that it has not been
482*46439007SCharles.Forsythable to find (usually this includes the source for
483*46439007SCharles.Forsyththe shell, as the module being debugged is often
484*46439007SCharles.Forsythstarted by the shell, and so the top-level function will
485*46439007SCharles.Forsythbe in the shell's module).
486*46439007SCharles.Forsyth.PP
487*46439007SCharles.Forsyth.CW Wm/deb
488*46439007SCharles.Forsythcan be used to debug multiple threads, to inspect
489*46439007SCharles.Forsyththe data structures in a thread, and to interactively
490*46439007SCharles.Forsythstep through the running of a thread (single stepping).
491*46439007SCharles.ForsythSee
492*46439007SCharles.Forsyth.I wm-deb (1)
493*46439007SCharles.Forsythfor details.
494*46439007SCharles.Forsyth
495*46439007SCharles.Forsyth\" further afield?
496*46439007SCharles.Forsyth\" other development tools?
497*46439007SCharles.Forsyth\" tools to come?
498