summaryrefslogtreecommitdiff
path: root/sys/doc/acid.ms
diff options
context:
space:
mode:
authoraiju <aiju@phicode.de>2011-07-18 11:01:22 +0200
committeraiju <aiju@phicode.de>2011-07-18 11:01:22 +0200
commit8c4c1f39f4e369d7c590c9d119f1150a2215e56d (patch)
treecd430740860183fc01de1bc1ddb216ceff1f7173 /sys/doc/acid.ms
parent11bf57fb2ceb999e314cfbe27a4e123bf846d2c8 (diff)
added /sys/doc
Diffstat (limited to 'sys/doc/acid.ms')
-rw-r--r--sys/doc/acid.ms2550
1 files changed, 2550 insertions, 0 deletions
diff --git a/sys/doc/acid.ms b/sys/doc/acid.ms
new file mode 100644
index 000000000..683c543bf
--- /dev/null
+++ b/sys/doc/acid.ms
@@ -0,0 +1,2550 @@
+.HTML "Acid Manual
+.am DS
+.ft I
+..
+.ta 1i 2.3i 4.5i (optional to set tabs)
+.TL
+Acid Manual
+.AU
+Phil Winterbottom
+philw@plan9.bell-labs.com
+.SH
+Introduction
+.PP
+Acid is a general purpose, source level symbolic debugger.
+The debugger is built around a simple command language.
+The command language, distinct from the language of the program being debugged,
+provides a flexible user interface that allows the debugger
+interface to be customized for a specific application or architecture.
+Moreover, it provides an opportunity to write test and
+verification code independently of a program's source code.
+Acid is able to debug multiple
+processes provided they share a common set of symbols, such as the processes in
+a threaded program.
+.PP
+Like other language-based solutions, Acid presents a poor user interface but
+provides a powerful debugging tool.
+Application of Acid to hard problems is best approached by writing functions off-line
+(perhaps loading them with the
+.CW include
+function or using the support provided by
+.I acme (1)),
+rather than by trying to type intricate Acid operations
+at the interactive prompt.
+.PP
+Acid allows the execution of a program to be controlled by operating on its
+state while it is stopped and by monitoring and controlling its execution
+when it is running. Each program action that causes a change
+of execution state is reflected by the execution
+of an Acid function, which may be user defined.
+A library of default functions provides the functionality of a normal debugger.
+.PP
+A Plan 9 process is controlled by writing messages to a control file in the
+.I proc (3)
+file system. Each control message has a corresponding Acid function, which
+sends the message to the process. These functions take a process id
+.I pid ) (
+as an
+argument. The memory and text file of the program may be manipulated using
+the indirection operators. The symbol table, including source cross reference,
+is available to an Acid program. The combination allows complex operations
+to be performed both in terms of control flow and data manipulation.
+.SH
+Input format and \f(CWwhatis\fP
+.PP
+Comments start with
+.CW //
+and continue to the end of the line.
+Input is a series of statements and expressions separated by semicolons.
+At the top level of the interpreter, the builtin function
+.CW print
+is called automatically to display the result of all expressions except function calls.
+A unary
+.CW +
+may be used as a shorthand to force the result of a function call to be printed.
+.PP
+Also at the top level, newlines are treated as semicolons
+by the parser, so semicolons are unnecessary when evaluating expressions.
+.PP
+When Acid starts, it loads the default program modules,
+enters interactive mode, and prints a prompt. In this state Acid accepts
+either function definitions or statements to be evaluated.
+In this interactive mode
+statements are evaluated immediately, while function definitions are
+stored for later invocation.
+.PP
+The
+.CW whatis
+operator can be used to report the state of identifiers known to the interpreter.
+With no argument,
+.CW whatis
+reports the name of all defined Acid functions; when supplied with an identifier
+as an argument it reports any variable, function, or type definition
+associated with the identifier.
+Because of the way the interpreter handles semicolons,
+the result of a
+.CW whatis
+statement can be returned directly to Acid without adding semicolons.
+A syntax error or interrupt returns Acid to the normal evaluation
+mode; any partially evaluated definitions are lost.
+.SH
+Using the Library Functions
+.PP
+After loading the program binary, Acid loads the portable and architecture-specific
+library functions that form the standard debugging environment.
+These files are Acid source code and are human-readable.
+The following example uses the standard debugging library to show how
+language and program interact:
+.P1
+% acid /bin/ls
+/bin/ls:mips plan 9 executable
+
+/sys/lib/acid/port
+/sys/lib/acid/mips
+acid: new()
+75721: system call _main ADD $-0x14,R29
+75721: breakpoint main+0x4 MOVW R31,0x0(R29)
+acid: bpset(ls)
+acid: cont()
+75721: breakpoint ls ADD $-0x16c8,R29
+acid: stk()
+At pc:0x0000141c:ls /sys/src/cmd/ls.c:87
+ls(s=0x0000004d,multi=0x00000000) /sys/src/cmd/ls.c:87
+ called from main+0xf4 /sys/src/cmd/ls.c:79
+main(argc=0x00000000,argv=0x7ffffff0) /sys/src/cmd/ls.c:48
+ called from _main+0x20 /sys/src/libc/mips/main9.s:10
+acid: PC
+0xc0000f60
+acid: *PC
+0x0000141c
+acid: ls
+0x0000141c
+.P2
+The function
+.CW new()
+creates a new process and stops it at the first instruction.
+This change in state is reported by a call to the
+Acid function
+.CW stopped ,
+which is called by the interpreter whenever the debugged program stops.
+.CW Stopped
+prints the status line giving the pid, the reason the program stopped
+and the address and instruction at the current PC.
+The function
+.CW bpset
+makes an entry in the breakpoint table and plants a breakpoint in memory.
+The
+.CW cont
+function continues the process, allowing it to run until some condition
+causes it to stop. In this case the program hits the breakpoint placed on
+the function
+.CW ls
+in the C program. Once again the
+.CW stopped
+routine is called to print the status of the program. The function
+.CW stk
+prints a C stack trace of the current process. It is implemented using
+a builtin Acid function that returns the stack trace as a list; the code
+that formats the information is all written in Acid.
+The Acid variable
+.CW PC
+holds the address of the
+cell where the current value of the processor register
+.CW PC
+is stored. By indirecting through
+the value of
+.CW PC
+the address where the program is stopped can be found.
+All of the processor registers are available by the same mechanism.
+.SH
+Types
+.PP
+An Acid variable has one of four types:
+.I integer ,
+.I float ,
+.I list ,
+or
+.I string .
+The type of a variable is inferred from the type of the right-hand
+side of the assignment expression which last set its value.
+Referencing a variable that has not yet
+been assigned draws a "used but not set" error. Many of the operators may
+be applied to more than
+one type; for these operators the action of the operator is determined by
+the types of its operands. The action of each operator is defined in the
+.I Expressions
+section of this manual.
+.SH
+Variables
+.PP
+Acid has three kinds of variables: variables defined by the symbol table
+of the debugged program, variables that are defined and maintained
+by the interpreter as the debugged program changes state, and variables
+defined and used by Acid programs.
+.PP
+Some examples of variables maintained by the interpreter are the register
+pointers listed by name in the Acid list variable
+.CW registers ,
+and the symbol table listed by name and contents in the Acid variable
+.CW symbols .
+.PP
+The variable
+.CW pid
+is updated by the interpreter to select the most recently created process
+or the process selected by the
+.CW setproc
+builtin function.
+.SH 1
+Formats
+.PP
+In addition to a type, variables have formats. The format is a code
+letter that determines the printing style and the effect of some of the
+operators on that variable. The format codes are derived from the format
+letters used by
+.I db (1).
+By default, symbol table variables and numeric constants
+are assigned the format code
+.CW X ,
+which specifies 32-bit hexadecimal.
+Printing a variable with this code yields the output
+.CW 0x00123456 .
+The format code of a variable may be changed from the default by using the
+builtin function
+.CW fmt .
+This function takes two arguments, an expression and a format code. After
+the expression is evaluated the new format code is attached to the result
+and forms the return value from
+.CW fmt .
+The backslash operator is a short form of
+.CW fmt .
+The format supplied by the backslash operator must be the format character
+rather than an expression.
+If the result is assigned to a variable the new format code is maintained
+in the variable. For example:
+.P1
+acid: x=10
+acid: print(x)
+0x0000000a
+acid: x = fmt(x, 'D')
+acid: print(x, fmt(x, 'X'))
+10 0x0000000a
+acid: x
+10
+acid: x\eo
+12
+.P2
+The supported format characters are:
+.RS
+.IP \f(CWo\fP
+Print two-byte integer in octal.
+.IP \f(CWO\fP
+Print four-byte integer in octal.
+.IP \f(CWq\fP
+Print two-byte integer in signed octal.
+.IP \f(CWQ\fP
+Print four-byte integer in signed octal.
+.IP \f(CWB\fP
+Print four-byte integer in binary.
+.IP \f(CWd\fP
+Print two-byte integer in signed decimal.
+.IP \f(CWD\fP
+Print four-byte integer in signed decimal.
+.IP \f(CWV\fP
+Print eight-byte integer in signed decimal.
+.IP \f(CWZ\fP
+Print eight-byte integer in unsigned decimal.
+.IP \f(CWx\fP
+Print two-byte integer in hexadecimal.
+.IP \f(CWX\fP
+Print four-byte integer in hexadecimal.
+.IP \f(CWY\fP
+Print eight-byte integer in hexadecimal.
+.IP \f(CWu\fP
+Print two-byte integer in unsigned decimal.
+.IP \f(CWU\fP
+Print four-byte integer in unsigned decimal.
+.IP \f(CWf\fP
+Print single-precision floating point number.
+.IP \f(CWF\fP
+Print double-precision floating point number.
+.IP \f(CWg\fP
+Print a single precision floating point number in string format.
+.IP \f(CWG\fP
+Print a double precision floating point number in string format.
+.IP \f(CWb\fP
+Print byte in hexadecimal.
+.IP \f(CWc\fP
+Print byte as an ASCII character.
+.IP \f(CWC\fP
+Like
+.CW c ,
+with
+printable ASCII characters represented normally and
+others printed in the form \f(CW\ex\fInn\fR.
+.IP \f(CWs\fP
+Interpret the addressed bytes as UTF characters
+and print successive characters until a zero byte is reached.
+.IP \f(CWr\fP
+Print a two-byte integer as a rune.
+.IP \f(CWR\fP
+Print successive two-byte integers as runes
+until a zero rune is reached.
+.IP \f(CWi\fP
+Print as machine instructions.
+.IP \f(CWI\fP
+As
+.CW i
+above, but print the machine instructions in
+an alternate form if possible:
+.CW sunsparc
+and
+.CW mipsco
+reproduce the manufacturers' syntax.
+.IP \f(CWa\fP
+Print the value in symbolic form.
+.RE
+.SH
+Complex types
+.PP
+Acid permits the definition of the layout of memory.
+The usual method is to use the
+.CW -a
+flag of the compilers to produce Acid-language descriptions of data structures (see
+.I 2c (1))
+although such definitions can be typed interactively.
+The keywords
+.CW complex ,
+.CW adt ,
+.CW aggr ,
+and
+.CW union
+are all equivalent; the compiler uses the synonyms to document the declarations.
+A complex type is described as a set of members, each containing a format letter,
+an offset in the structure, and a name. For example, the C structure
+.P1
+struct List {
+ int type;
+ struct List *next;
+};
+.P2
+is described by the Acid statement
+.P1
+complex List {
+ 'D' 0 type;
+ 'X' 4 next;
+};
+.P2
+.SH
+Scope
+.PP
+Variables are global unless they are either parameters to functions
+or are declared as
+.CW local
+in a function body. Parameters and local variables are available only in
+the body of the function in which they are instantiated.
+Variables are dynamically bound: if a function declares a local variable
+with the same name as a global variable, the global variable will be hidden
+whenever the function is executing.
+For example, if a function
+.CW f
+has a local called
+.CW main ,
+any function called below
+.CW f
+will see the local version of
+.CW main ,
+not the external symbol.
+.SH 1
+Addressing
+.PP
+Since the symbol table specifies addresses,
+to access the value of program variables
+an extra level of indirection
+is required relative to the source code.
+For consistency, the registers are maintained as pointers as well; Acid variables with the names
+of processor registers point to cells holding the saved registers.
+.PP
+The location in a file or memory image associated with
+an address is calculated from a map
+associated with the file.
+Each map contains one or more quadruples (\c
+.I t ,
+.I b ,
+.I e ,
+.I f \|),
+defining a segment named
+.I t
+(usually
+.CW text ,
+.CW data ,
+.CW regs ,
+or
+.CW fpregs )
+mapping addresses in the range
+.I b
+through
+.I e
+to the part of the file
+beginning at
+offset
+.I f .
+The memory model of a Plan 9 process assumes
+that segments are disjoint. There
+can be more than one segment of a given type (e.g., a process
+may have more than one text segment) but segments
+may not overlap.
+An address
+.I a
+is translated
+to a file address
+by finding a segment
+for which
+.I b
++
+.I a
+<
+.I e ;
+the location in the file
+is then
+.I address
++
+.I f
+\-
+.I b .
+.PP
+Usually,
+the text and initialized data of a program
+are mapped by segments called
+.CW text
+and
+.CW data .
+Since a program file does not contain bss, stack, or register data,
+these data are
+not mapped by the data segment.
+The text segment is mapped similarly in the memory image of
+a normal (i.e., non-kernel) process.
+However, the segment called
+.CW *data
+maps memory from the beginning to the end of the program's data space.
+This region contains the program's static data, the bss, the
+heap and the stack. A segment
+called
+.CW *regs
+maps the registers;
+.CW *fpregs
+maps the floating point registers.
+.PP
+Sometimes it is useful to define a map with a single segment
+mapping the region from 0 to 0xFFFFFFFF; such a map
+allows the entire file to be examined
+without address translation. The builtin function
+.CW map
+examines and modifies Acid's map for a process.
+.SH 1
+Name Conflicts
+.PP
+Name conflicts between keywords in the Acid language, symbols in the program,
+and previously defined functions are resolved when the interpreter starts up.
+Each name is made unique by prefixing enough
+.CW $
+characters to the front of the name to make it unique. Acid reports
+a list of each name change at startup. The report looks like this:
+.P1
+/bin/sam: mips plan 9 executable
+/lib/acid/port
+/lib/acid/mips
+Symbol renames:
+ append=$append T/0xa4e40
+acid:
+.P2
+The symbol
+.CW append
+is both a keyword and a text symbol in the program. The message reports
+that the text symbol is now named
+.CW $append .
+.SH
+Expressions
+.PP
+Operators have the same
+binding and precedence as in C.
+For operators of equal precedence, expressions are evaluated from left to right.
+.SH 1
+Boolean expressions
+.PP
+If an expression is evaluated for a boolean condition the test
+performed depends on the type of the result. If the result is of
+.I integer
+or
+.I floating
+type the result is true if the value is non-zero. If the expression is a
+.I list
+the result is true if there are any members in the list.
+If the expression is a
+.I string
+the result is true if there are any characters in the string.
+.DS
+ primary-expression:
+ identifier
+ identifier \f(CW:\fP identifier
+ constant
+ \f(CW(\fP expression \f(CW)\fP
+ \f(CW{\fP elist \f(CW}\fP
+
+ elist:
+ expression
+ elist , expression
+.DE
+An identifier may be any legal Acid variable. The colon operator returns the
+address of parameters or local variables in the current stack of a program.
+For example:
+.P1
+*main:argc
+.P2
+prints the number of arguments passed into main. Local variables and parameters
+can only be referenced after the frame has been established. It may be necessary to
+step a program over the first few instructions of a breakpointed function to properly set
+the frame.
+.PP
+Constants follow the same lexical rules as C.
+A list of expressions delimited by braces forms a list constructor.
+A new list is produced by evaluating each expression when the constructor is executed.
+The empty list is formed from
+.CW {} .
+.P1
+acid: x = 10
+acid: l = { 1, x, 2\eD }
+acid: x = 20
+acid: l
+{0x00000001 , 0x0000000a , 2 }
+.P2
+.SH 1
+Lists
+.PP
+Several operators manipulate lists.
+.DS
+ list-expression:
+ primary-expression
+ \f(CWhead\fP primary-expression
+ \f(CWtail\fP primary-expression
+ \f(CWappend\fP expression \f(CW,\fP primary-expression
+ \f(CWdelete\fP expression \f(CW,\fP primary-expression
+.DE
+The
+.I primary-expression
+for
+.CW head
+and
+.CW tail
+must yield a value of type
+.I list .
+If there are no elements in the list the value of
+.CW head
+or
+.CW tail
+will be the empty list. Otherwise
+.CW head
+evaluates to the first element of the list and
+.CW tail
+evaluates to the rest.
+.P1
+acid: head {}
+{}
+acid: head {1, 2, 3, 4}
+0x00000001
+acid: tail {1, 2, 3, 4}
+{0x00000002 , 0x00000003 , 0x00000004 }
+.P2
+The first operand of
+.CW append
+and
+.CW delete
+must be an expression that yields a
+.I list .
+.CW Append
+places the result of evaluating
+.I primary-expression
+at the end of the list.
+The
+.I primary-expression
+supplied to
+.CW delete
+must evaluate to an integer;
+.CW delete
+removes the
+.I n 'th
+item from the list, where
+.I n
+is integral value of
+.I primary-expression.
+List indices are zero-based.
+.P1
+ acid: append {1, 2}, 3
+ {0x00000001 , 0x00000002 , 0x00000003 }
+ acid: delete {1, 2, 3}, 1
+ {0x00000001 , 0x00000003 }
+.P2
+.PP
+Assigning a list to a variable copies a reference to the list; if a list variable
+is copied it still points at the same list. To copy a list, the elements must
+be copied piecewise using
+.CW head
+and
+.CW append .
+.SH 1
+Operators
+.PP
+.DS
+ postfix-expression:
+ list-expression
+ postfix-expression \f(CW[\fP expression \f(CW]\fP
+ postfix-expression \f(CW(\fP argument-list \f(CW)\fP
+ postfix-expression \f(CW.\fP tag
+ postfix-expression \f(CW->\fP tag
+ postfix-expression \f(CW++\fP
+ postfix-expression \f(CW--\fP
+
+ argument-list:
+ expression
+ argument-list , expression
+.DE
+The
+.CW [
+.I expression
+.CW ]
+operator performs indexing.
+The indexing expression must result in an expression of
+.I integer
+type, say
+.I n .
+The operation depends on the type of
+.I postfix-expression .
+If the
+.I postfix-expression
+yields an
+.I integer
+it is assumed to be the base address of an array in the memory image.
+The index offsets into this array; the size of the array members is
+determined by the format associated with the
+.I postfix-expression .
+If the
+.I postfix-expression
+yields a
+.I string
+the index operator fetches the
+.I n 'th
+character
+of the string. If the index points beyond the end
+of the string, a zero is returned.
+If the
+.I postfix-expression
+yields a
+.I list
+then the indexing operation returns the
+.I n 'th
+item of the list.
+If the list contains less than
+.I n
+items the empty list
+.CW {}
+is returned.
+.PP
+The
+.CW ++
+and
+.CW --
+operators increment and decrement integer variables.
+The amount of increment or decrement depends on the format code. These postfix
+operators return the value of the variable before the increment or decrement
+has taken place.
+.DS
+ unary-expression:
+ postfix-expression
+ \f(CW++\fP unary-expression
+ \f(CW--\fP unary-expression
+
+ unary-operator: one of
+ \f(CW*\fP \f(CW@\fP \f(CW+\fP \f(CW-\fP ~ \f(CW!\fP
+.DE
+The operators
+.CW *
+and
+.CW @
+are the indirection operators.
+.CW @
+references a value from the text file of the program being debugged.
+The size of the value depends on the format code. The
+.CW *
+operator fetches a value from the memory image of a process. If either
+operator appears on the left-hand side of an assignment statement, either the file
+or memory will be written. The file can only be modified when Acid is invoked
+with the
+.CW -w
+option.
+The prefix
+.CW ++
+and
+.CW --
+operators perform the same operation as their postfix counterparts but
+return the value after the increment or decrement has been performed. Since the
+.CW ++
+and
+.CW *
+operators fetch and increment the correct amount for the specified format,
+the following function prints correct machine instructions on a machine with
+variable length instructions, such as the 68020 or 386:
+.P1
+ defn asm(addr)
+ {
+ addr = fmt(addr, 'i');
+ loop 1, 10 do
+ print(*addr++, "\en");
+ }
+.P2
+The operators
+.CW ~
+and
+.CW !
+perform bitwise and logical negation respectively. Their operands must be of
+.I integer
+type.
+.DS
+ cast-expression:
+ unary-expression
+ unary-expression \f(CW\e\fP format-char
+ \f(CW(\fP complex-name \f(CW)\fP unary-expression
+.DE
+A unary expression may be preceded by a cast. The cast has the effect of
+associating the value of
+.I unary-expression
+with a complex type structure.
+The result may then be dereferenced using the
+.CW .
+and
+.CW ->
+operators.
+.PP
+An Acid variable may be associated with a complex type
+to enable accessing the type's members:
+.P1
+acid: complex List {
+ 'D' 0 type;
+ 'X' 4 next;
+};
+acid: complex List lhead
+acid: lhead.type
+10
+acid: lhead = ((List)lhead).next
+acid: lhead.type
+-46
+.P2
+Note that the
+.CW next
+field cannot be given a complex type automatically.
+.PP
+When entered at the top level of the interpreter,
+an expression of complex type
+is treated specially.
+If the type is called
+.CW T
+and an Acid function also called
+.CW T
+exists,
+then that function will be called with the expression as its argument.
+The compiler options
+.CW -a
+and
+.CW -aa
+will generate Acid source code defining such complex types and functions; see
+.I 2c (1).
+.PP
+A
+.I unary-expression
+may be qualified with a format specifier using the
+.CW \e
+operator. This has the same effect as passing the expression to the
+.CW fmt
+builtin function.
+.DS
+ multiplicative-expression:
+ cast-expression
+ multiplicative-expression \f(CW*\fP multiplicative-expression
+ multiplicative-expression \f(CW/\fP multiplicative-expression
+ multiplicative-expression \f(CW%\fP multiplicative-expression
+.DE
+These operate on
+.I integer
+and
+.I float
+types and perform the expected operations:
+.CW *
+multiplication,
+.CW /
+division,
+.CW %
+modulus.
+.DS
+ additive-expression:
+ multiplicative-expression
+ additive-expression \f(CW+\fP multiplicative-expression
+ additive-expression \f(CW-\fP multiplicative-expression
+.DE
+These operators perform as expected for
+.I integer
+and
+.I float
+operands.
+Unlike in C,
+.CW +
+and
+.CW -
+do not scale the addition based on the format of the expression.
+This means that
+.CW i=i+1
+will always add 1 but
+.CW i++
+will add the size corresponding to the format stored with
+.CW i .
+If both operands are of either
+.I string
+or
+.I list
+type then addition is defined as concatenation.
+Adding a string and an integer is treated as concatenation
+with the Unicode character corresponding to the integer.
+Subtraction is undefined for strings and lists.
+.DS
+ shift-expression:
+ additive-expression
+ shift-expression \f(CW<<\fP additive-expression
+ shift-expression \f(CW>>\fP additive-expression
+.DE
+The
+.CW >>
+and
+.CW <<
+operators perform bitwise right and left shifts respectively. Both
+require operands of
+.I integer
+type.
+.DS
+ relational-expression:
+ relational-expression \f(CW<\fP shift-expression
+ relational-expression \f(CW>\fP shift-expression
+ relational-expression \f(CW<=\fP shift-expression
+ relational-expression \f(CW>=\fP shift-expression
+
+ equality-expression:
+ relational-expression
+ relational-expression \f(CW==\fP equality-expression
+ relational-expression \f(CW!=\fP equality-expression
+.DE
+The comparison operators are
+.CW <
+(less than),
+.CW >
+(greater than),
+.CW <=
+(less than or equal to),
+.CW >=
+(greater than or equal to),
+.CW ==
+(equal to) and
+.CW !=
+(not equal to). The result of a comparison is 0
+if the condition is false, otherwise 1. The relational operators can only be
+applied to operands of
+.I integer
+and
+.I float
+type. The equality operators apply to all types. Comparing mixed types is legal.
+Mixed integer and float compare on the integral value. Other mixtures are always unequal.
+Two lists are equal if they
+have the same number of members and a pairwise comparison of the members results
+in equality.
+.DS
+ AND-expression:
+ equality-expression
+ AND-expression \f(CW&\fP equality-expression
+
+ XOR-expression:
+ AND-expression
+ XOR-expression \f(CW^\fP AND-expression
+
+ OR-expression:
+ XOR-expression
+ OR-expression \f(CW|\fP XOR-expression
+.DE
+These operators perform bitwise logical operations and apply only to the
+.I integer
+type.
+The operators are
+.CW &
+(logical and),
+.CW ^
+(exclusive or) and
+.CW |
+(inclusive or).
+.DS
+ logical-AND-expression:
+ OR-expression
+ logical-AND-expression \f(CW&&\fP OR-expression
+
+ logical-OR-expression:
+ logical-AND-expression
+ logical-OR-expression \f(CW||\fP logical-AND-expression
+.DE
+The
+.CW &&
+operator returns 1 if both of its operands evaluate to boolean true, otherwise 0.
+The
+.CW ||
+operator returns 1 if either of its operands evaluates to boolean true,
+otherwise 0.
+.SH
+Statements
+.PP
+.DS
+ \f(CWif\fP expression \f(CWthen\fP statement \f(CWelse\fP statement
+ \f(CWif\fP expression \f(CWthen\fP statement
+.DE
+The
+.I expression
+is evaluated as a boolean. If its value is true the statement after
+the
+.CW then
+is executed, otherwise the statement after the
+.CW else
+is executed. The
+.CW else
+portion may be omitted.
+.DS
+ \f(CWwhile\fP expression \f(CWdo\fP statement
+.DE
+In a while loop, the
+.I statement
+is executed while the boolean
+.I expression
+evaluates
+true.
+.DS
+ \f(CWloop\fP startexpr, endexpr \f(CWdo\fP statement
+.DE
+The two expressions
+.I startexpr
+and
+.I endexpr
+are evaluated prior to loop entry.
+.I Statement
+is evaluated while the value of
+.I startexpr
+is less than or equal to
+.I endexpr .
+Both expressions must yield
+.I integer
+values. The value of
+.I startexpr
+is
+incremented by one for each loop iteration.
+Note that there is no explicit loop variable; the
+.I expressions
+are just values.
+.DS
+ \f(CWreturn\fP expression
+.DE
+.CW return
+terminates execution of the current function and returns to its caller.
+The value of the function is given by expression. Since
+.CW return
+requires an argument, nil-valued functions should return the empty list
+.CW {} .
+.DS
+ \f(CWlocal\fP variable
+.DE
+The
+.CW local
+statement creates a local instance of
+.I variable ,
+which exists for the duration
+of the instance of the function in which it is declared. Binding is dynamic: the local variable,
+rather than the previous value of
+.I variable ,
+is visible to called functions.
+After a return from the current function the previous value of
+.I variable
+is
+restored.
+.PP
+If Acid is interrupted, the values of all local variables are lost,
+as if the function returned.
+.DS
+ \f(CWdefn\fP function-name \f(CW(\fP parameter-list \f(CW)\fP body
+
+ parameter-list:
+ variable
+ parameter-list , variable
+
+ body:
+ \f(CW{\fP statement \f(CW}\fP
+.DE
+Functions are introduced by the
+.CW defn
+statement. The definition of parameter names suppresses any variables
+of the same name until the function returns. The body of a function is a list
+of statements enclosed by braces.
+.SH
+Code variables
+.PP
+Acid permits the delayed evaluation of a parameter to a function. The parameter
+may then be evaluated at any time with the
+.CW eval
+operator. Such parameters are called
+.I "code variables
+and are defined by prefixing their name with an asterisk in their declaration.
+.PP
+For example, this function wraps up an expression for later evaluation:
+.P1
+acid: defn code(*e) { return e; }
+acid: x = code(v+atoi("100")\eD)
+acid: print(x)
+(v+atoi("100"))\eD;
+acid: eval x
+<stdin>:5: (error) v used but not set
+acid: v=5
+acid: eval x
+105
+.P2
+.SH
+Source Code Management
+.PP
+Acid provides the means to examine source code. Source code is
+represented by lists of strings. Builtin functions provide mapping
+from address to lines and vice-versa. The default debugging environment
+has the means to load and display source files.
+.SH
+Builtin Functions
+.PP
+The Acid interpreter has a number of builtin functions, which cannot be redefined.
+These functions perform machine- or operating system-specific functions such as
+symbol table and process management.
+The following section presents a description of each builtin function.
+The notation
+.CW {}
+is used to denote the empty list, which is the default value of a function that
+does not execute a
+.CW return
+statement.
+The type and number of parameters for each function are specified in the
+description; where a parameter can be of any type it is specified as type
+.I item .
+.de Ip
+.KS
+.in 0
+.LP
+.ie h \&\f2\\$1\fP\ \ \f(CW\\$2(\f2\\$3\f(CW)\f1\ \ \ \ \ \ \ \ \\$4
+.el .tl '\f2\\$1\fP\ \ \f(CW\\$2(\f2\\$3\f(CW)\f1''\\$4'
+.IP
+..
+.de Ex
+.KE
+.KS
+.IP
+.ft CW
+.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n
+.nf
+.in +4n
+.br
+..
+.de Ee
+.fi
+.ft 1
+.br
+.KE
+..
+.\"
+.\"
+.\"
+.Ip integer access string "Check if a file can be read
+.CW Access
+returns the integer 1 if the file name in
+.I string
+can be read by the builtin functions
+.CW file ,
+.CW readfile ,
+or
+.CW include ,
+otherwise 0. A typical use of this function is to follow
+a search path looking for a source file; it is used by
+.CW findsrc .
+.Ex
+if access("main.c") then
+ return file("main.c");
+.Ee
+.\"
+.\"
+.\"
+.Ip float atof string "Convert a string to float
+.CW atof
+converts the string supplied as its argument into a floating point
+number. The function accepts strings in the same format as the C
+function of the same name. The value returned has the format code
+.CW f .
+.CW atof
+returns the value 0.0 if it is unable to perform the conversion.
+.Ex
+acid: +atof("10.4e6")
+1.04e+07
+.Ee
+.\"
+.\"
+.\"
+.Ip integer atoi string "Convert a string to an integer
+.CW atoi
+converts the argument
+.i string
+to an integer value.
+The function accepts strings in the same format as the C function of the
+same name. The value returned has the format code
+.CW D .
+.CW atoi
+returns the integer 0 if it is unable to perform a conversion.
+.Ex
+acid: +atoi("-1255")
+-1255
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP error string "Generate an interpreter error
+.CW error
+generates an error message and returns the interpreter to interactive
+mode. If an Acid program is running, it is aborted.
+Processes being debugged are not affected. The values of all local variables are lost.
+.CW error
+is commonly used to stop the debugger when some interesting condition arises
+in the debugged program.
+.Ex
+while 1 do {
+ step();
+ if *main != @main then
+ error("memory corrupted");
+}
+.Ee
+.\"
+.\"
+.\"
+.Ip list file string "Read the contents of a file into a list
+.CW file
+reads the contents of the file specified by
+.I string
+into a list.
+Each element in the list is a string corresponding to a line in the file.
+.CW file
+breaks lines at the newline character, but the newline
+characters are not returned as part each string.
+.CW file
+returns the empty list if it encounters an error opening or reading the data.
+.Ex
+acid: print(file("main.c")[0])
+#include <u.h>
+.Ee
+.\"
+.\"
+.\"
+.Ip integer filepc string "Convert source address to text address
+.CW filepc
+interprets its
+.I string
+argument as a source file address in the form of a file name and line offset.
+.CW filepc
+uses the symbol table to map the source address into a text address
+in the debugged program. The
+.I integer
+return value has the format
+.CW X .
+.CW filepc
+returns an address of -1 if the source address is invalid.
+The source file address uses the same format as
+.I acme (1).
+This function is commonly used to set breakpoints from the source text.
+.Ex
+acid: bpset(filepc("main:10"))
+acid: bptab()
+ 0x00001020 usage ADD $-0xc,R29
+.Ee
+.\"
+.\"
+.\"
+.Ip item fmt item,fmt "Set print, \f(CW@\fP and \f(CW*\fP formats
+.CW fmt
+evaluates the expression
+.I item
+and sets the format of the result to
+.I fmt .
+The format of a value determines how it will be printed and
+what kind of object will be fetched by the
+.CW *
+and
+.CW @
+operators. The
+.CW \e
+operator is a short-hand form of the
+.CW fmt
+builtin function. The
+.CW fmt
+function leaves the format of the
+.I item
+unchanged.
+.Ex
+acid: main=fmt(main, 'i') // as instructions
+acid: print(main\eX, "\et", *main)
+0x00001020 ADD $-64,R29
+.Ee
+.\"
+.\"
+.\"
+.Ip fmt fmtof item "Get format
+.CW fmtof
+evaluates the expression
+.I item
+and returns the format of the result.
+.Ex
+acid: +fmtof(33)
+W
+acid: +fmtof("string")
+s
+.Ee
+.\"
+.\"
+.\"
+.Ip integer fmtsize item "Get format size
+.CW fmtsize
+evaluates the expression
+.I item
+and returns the size in bytes of a single element of result's format.
+.Ex
+acid: +fmtsize('c')
+8
+acid: +fmtsize('c'\ec)
+1
+acid: +fmtsize(0\eX)
+4
+acid: +fmtsize('c'\e3)
+10
+.Ee
+.\"
+.\"
+.\"
+.Ip list fnbound integer "Find start and end address of a function
+.CW fnbound
+interprets its
+.I integer
+argument as an address in the text of the debugged program.
+.CW fnbound
+returns a list containing two integers corresponding to
+the start and end addresses of the function containing the supplied address.
+If the
+.I integer
+address is not in the text segment of the program then the empty list is returned.
+.CW fnbound
+is used by
+.CW next
+to detect stepping into new functions.
+.Ex
+acid: print(fnbound(main))
+{0x00001050, 0x000014b8}
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP follow integer "Compute follow set
+The follow set is defined as the set of program counter values that could result
+from executing an instruction.
+.CW follow
+interprets its
+.I integer
+argument as a text address, decodes the instruction at
+that address and, with the current register set, builds a list of possible
+next program counter values. If the instruction at the specified address
+cannot be decoded
+.CW follow
+raises an error.
+.CW follow
+is used to plant breakpoints on
+all potential paths of execution. The following code fragment
+plants breakpoints on top of all potential following instructions.
+.Ex
+lst = follow(*PC);
+while lst do
+{
+ *head lst = bpinst;
+ lst = tail lst;
+}
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP include string "Take input from a new file
+.CW include
+opens the file specified by
+.I string
+and uses its contents as command input to the interpreter.
+The interpreter restores input to its previous source when it encounters
+either an end of file or an error.
+.CW include
+can be used to incrementally load symbol table information without
+leaving the interpreter.
+.Ex
+acid: include("/sys/src/cmd/acme/syms")
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP interpret string "Take input from a string
+.CW interpret
+evaluates the
+.I string
+expression and uses its result as command input for the interpreter.
+The interpreter restores input to its previous source when it encounters
+either the end of string or an error. The
+.CW interpret
+function allows Acid programs to write Acid code for later evaluation.
+.Ex
+acid: interpret("main+10;")
+0x0000102a
+.Ee
+.\"
+.\"
+.\"
+.Ip string itoa integer[,string] "Convert integer to string
+.CW itoa
+takes an integer argument and converts it into an ASCII string
+in the
+.CW D
+format.
+an alternate format string
+may be provided in the
+.CW %
+style of
+.I print (2).
+This function is commonly used to build
+.CW rc
+command lines.
+.Ex
+acid: rc("cat /proc/"+itoa(pid)+"/segment")
+Stack 7fc00000 80000000 1
+Data 00001000 00009000 1
+Data 00009000 0000a000 1
+Bss 0000a000 0000c000 1
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP kill integer "Kill a process
+.CW kill
+writes a kill control message into the control file of the process
+specified by the
+.I integer
+pid.
+If the process was previously installed by
+.CW setproc
+it will be removed from the list of active processes.
+If the
+.I integer
+has the same value as
+.CW pid ,
+then
+.CW pid
+will be set to 0.
+To continue debugging, a new process must be selected using
+.CW setproc .
+For example, to kill all the active processes:
+.Ex
+while proclist do {
+ kill(head proclist);
+ proclist = tail proclist;
+}
+.Ee
+.\"
+.\"
+.\"
+.Ip list map list "Set or retrieve process memory map
+.CW map
+either retrieves all the mappings associated with a process or sets a single
+map entry to a new value.
+If the
+.I list
+argument is omitted then
+.CW map
+returns a list of lists. Each sublist has four values and describes a
+single region of contiguous addresses in the
+memory or file image of the debugged program. The first entry is the name of the
+mapping. If the name begins with
+.CW *
+it denotes a map into the memory of an active process.
+The second and third values specify the base and end
+address of the region and the fourth number specifies the offset in the file
+corresponding to the first location of the region.
+A map entry may be set by supplying a list in the same format as the sublist
+described above. The name of the mapping must match a region already defined
+by the current map.
+Maps are set automatically for Plan 9 processes and some kernels; they may
+need to be set by hand for other kernels and programs that run on bare hardware.
+.Ex
+acid: map({"text", _start, end, 0x30})
+.Ee
+.\"
+.\"
+.\"
+.Ip integer match item,list "Search list for matching value
+.CW match
+compares each item in
+.I list
+using the equality operator
+.CW ==
+with
+.I item .
+The
+.I item
+can be of any type. If the match succeeds the result is the integer index
+of the matching value, otherwise -1.
+.Ex
+acid: list={8,9,10,11}
+acid: print(list[match(10, list)]\eD)
+10
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP newproc string "Create a new process
+.CW newproc
+starts a new process with an argument vector constructed from
+.I string .
+The argument vector excludes the name of the program to execute and
+each argument in
+.I string
+must be space separated. A new process can accept no more
+than 512 arguments. The internal variable
+.CW pid
+is set to the pid of the newly created process. The new pid
+is also appended to the list of active processes stored in the variable
+.CW proclist .
+The new process is created then halted at the first instruction, causing
+the debugger to call
+.CW stopped .
+The library functions
+.CW new
+and
+.CW win
+should be used to start processes when using the standard debugging
+environment.
+.Ex
+acid: newproc("-l .")
+56720: system call _main ADD $-0x14,R29
+.Ee
+.\"
+.\"
+.\"
+.Ip string pcfile integer "Convert text address to source file name
+.CW pcfile
+interprets its
+.I integer
+argument as a text address in the debugged program. The address and symbol table
+are used to generate a string containing the name of the source file
+corresponding to the text address. If the address does not lie within the
+program the string
+.CW ?file?
+is returned.
+.Ex
+acid: print("Now at ", pcfile(*PC), ":", pcline(*PC))
+Now at ls.c:46
+.Ee
+.\"
+.\"
+.\"
+.Ip integer pcline integer "Convert text address to source line number
+.CW pcline
+interprets its
+.I integer
+argument as a text address in the debugged program. The address and symbol table
+are used to generate an integer containing the line number in the source file
+corresponding to the text address. If the address does not lie within the
+program the integer 0 is returned.
+.Ex
+acid: +file("main.c")[pcline(main)]
+main(int argc, char *argv[])
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP print item,item,... "Print expressions
+.CW print
+evaluates each
+.I item
+supplied in its argument list and prints it to standard output. Each
+argument will be printed according to its associated format character.
+When the interpreter is executing, output is buffered and flushed every
+5000 statements or when the interpreter returns to interactive mode.
+.CW print
+accepts a maximum of 512 arguments.
+.Ex
+acid: print(10, "decimal ", 10\eD, "octal ", 10\eo)
+0x0000000a decimal 10 octal 000000000012
+acid: print({1, 2, 3})
+{0x00000001 , 0x00000002 , 0x00000003 }
+acid: print(main, main\ea, "\et", @main\ei)
+0x00001020 main ADD $-64,R29
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP printto string,item,item,... "Print expressions to file
+.CW printto
+offers a limited form of output redirection. The first
+.I string
+argument is used as the path name of a new file to create.
+Each
+.I item
+is then evaluated and printed to the newly created file. When all items
+have been printed the file is closed.
+.CW printto
+accepts a maximum of 512 arguments.
+.Ex
+acid: printto("/env/foo", "hello")
+acid: rc("echo -n $foo")
+hello
+.Ee
+.\"
+.\"
+.\"
+.Ip string rc string "Execute a shell command
+.CW rc
+evaluates
+.I string
+to form a shell command. A new command interpreter is started
+to execute the command. The Acid interpreter blocks until the command
+completes. The return value is the empty string
+if the command succeeds, otherwise the exit status of the failed command.
+.Ex
+acid: rc("B "+itoa(-pcline(addr))+" "+pcfile(addr));
+.Ee
+.\"
+.\"
+.\"
+.Ip string readfile string "Read file contents into a string
+.CW readfile
+takes the contents of the file specified by
+.I string
+and returns its contents as a new string.
+If
+.CW readfile
+encounters a zero byte in the file, it terminates.
+If
+.CW readfile
+encounters an error opening or reading the file then the empty list
+is returned.
+.CW readfile
+can be used to read the contents of device files whose lines are not
+terminated with newline characters.
+.Ex
+acid: ""+readfile("/dev/label")
+helix
+.Ee
+.\"
+.\"
+.\"
+.Ip string reason integer "Print cause of program stoppage
+.CW reason
+uses machine-dependent information to generate a string explaining
+why a process has stopped. The
+.I integer
+argument is the value of an architecture dependent status register,
+for example
+.CW CAUSE
+on the MIPS.
+.Ex
+acid: print(reason(*CAUSE))
+system call
+.Ee
+.\"
+.\"
+.\"
+.Ip integer regexp pattern,string "Regular expression match
+.CW regexp
+matches the
+.I pattern
+string supplied as its first argument with the
+.I string
+supplied as its second.
+If the pattern matches the result is the value 1, otherwise 0.
+.Ex
+acid: print(regexp(".*bar", "foobar"))
+1
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP setproc integer "Set debugger focus
+.CW setproc
+selects the default process used for memory and control operations. It effectively
+shifts the focus of control between processes. The
+.I integer
+argument specifies the pid of the process to look at.
+The variable
+.CW pid
+is set to the pid of the selected process. If the process is being
+selected for the first time its pid is added to the list of active
+processes
+.CW proclist .
+.Ex
+acid: setproc(68382)
+acid: procs()
+>68382: Stopped at main+0x4 setproc(68382)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP start integer "Restart execution
+.CW start
+writes a
+.CW start
+message to the control file of the process specified by the pid
+supplied as its
+.I integer
+argument.
+.CW start
+draws an error if the process is not in the
+.CW Stopped
+state.
+.Ex
+acid: start(68382)
+acid: procs()
+>68382: Running at main+0x4 setproc(68382)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP startstop integer "Restart execution, block until stopped
+.CW startstop
+performs the same actions as a call to
+.CW start
+followed by a call to
+.CW stop .
+The
+.I integer
+argument specifies the pid of the process to control. The process
+must be in the
+.CW Stopped
+state.
+Execution is restarted, the debugger then waits for the process to
+return to the
+.CW Stopped
+state. A process will stop if a startstop message has been written to its control
+file and any of the following conditions becomes true: the process executes or returns from
+a system call, the process generates a trap or the process receives a note.
+.CW startstop
+is used to implement single stepping.
+.Ex
+acid: startstop(pid)
+75374: breakpoint ls ADD $-0x16c8,R29
+.Ee
+.\"
+.\"
+.\"
+.Ip string status integer "Return process state
+.CW status
+uses the pid supplied by its
+.I integer
+argument to generate a string describing the state of the process.
+The string corresponds to the state returned by the
+sixth column of the
+.I ps (1)
+command.
+A process must be in the
+.CW Stopped
+state to modify its memory or registers.
+.Ex
+acid: ""+status(pid)
+Stopped
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP stop integer "Wait for a process to stop
+.CW stop
+writes a
+.CW stop
+message to the control file of the process specified by the
+pid supplied as its
+.I integer
+argument.
+The interpreter blocks until the debugged process enters the
+.CW Stopped
+state.
+A process will stop if a stop message has been written to its control
+file and any of the following conditions becomes true: the process executes or returns from
+a system call, the process generates a trap, the process is scheduled or the
+process receives a note.
+.CW stop
+is used to wait for a process to halt before planting a breakpoint since Plan 9
+only allows a process's memory to be written while it is in the
+.CW Stopped
+state.
+.Ex
+defn bpset(addr) {
+ if (status(pid)!="Stopped") then {
+ print("Waiting...\en");
+ stop(pid);
+ }
+ ...
+}
+.Ee
+.\"
+.\"
+.\"
+.Ip list strace pc,sp,linkreg "Stack trace
+.CW strace
+generates a list of lists corresponding to procedures called by the debugged
+program. Each sublist describes a single stack frame in the active process.
+The first element is an
+.I integer
+of format
+.CW X
+specifying the address of the called function. The second element is the value
+of the program counter when the function was called. The third and fourth elements
+contain lists of parameter and automatic variables respectively.
+Each element of these lists
+contains a string with the name of the variable and an
+.I integer
+value of format
+.CW X
+containing the current value of the variable.
+The arguments to
+.CW strace
+are the current value of the program counter, the current value of the
+stack pointer, and the address of the link register. All three parameters
+must be integers.
+The setting of
+.I linkreg
+is architecture dependent. On the MIPS linkreg is set to the address of saved
+.CW R31 ,
+on the SPARC to the address of saved
+.CW R15 .
+For the other architectures
+.I linkreg
+is not used, but must point to valid memory.
+.Ex
+acid: print(strace(*PC, *SP, linkreg))
+{{0x0000141c, 0xc0000f74,
+{{"s", 0x0000004d}, {"multi", 0x00000000}},
+{{"db", 0x00000000}, {"fd", 0x000010a4},
+{"n", 0x00000001}, {"i", 0x00009824}}}}
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP waitstop integer "Wait for a process to stop
+.CW waitstop
+writes a waitstop message to the control file of the process specified by the
+pid supplied as its
+.I integer
+argument.
+The interpreter will remain blocked until the debugged process enters the
+.CW Stopped
+state.
+A process will stop if a waitstop message has been written to its control
+file and any of the following conditions becomes true: the process generates a trap
+or receives a note. Unlike
+.CW stop ,
+the
+.CW waitstop
+function is passive; it does not itself cause the program to stop.
+.Ex
+acid: waitstop(pid)
+75374: breakpoint ls ADD $-0x16c8,R29
+.Ee
+.\"
+.\"
+.\"
+.SH
+Library Functions
+.PP
+A standard debugging environment is provided by modules automatically
+loaded when
+Acid is started.
+These modules are located in the directory
+.CW /sys/lib/acid .
+These functions may be overridden, personalized, or added to by code defined in
+.CW $home/lib/acid .
+The implementation of these functions can be examined using the
+.CW whatis
+operator and then modified during debugging sessions.
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP Bsrc integer "Load editor with source
+.CW Bsrc
+interprets the
+.I integer
+argument as a text address. The text address is used to produce a pathname
+and line number suitable for the
+.CW B
+command
+to send to the text editor
+.I sam (1)
+or
+.I acme (1).
+.CW Bsrc
+builds an
+.I rc (1)
+command to invoke
+.CW B ,
+which either selects an existing source file or loads a new source file into the editor.
+The line of source corresponding to the text address is then selected.
+In the following example
+.CW stopped
+is redefined so that the editor
+follows and displays the source line currently being executed.
+.Ex
+defn stopped(pid) {
+ pstop(pid);
+ Bsrc(*PC);
+}
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP Fpr "" "Display double precision floating registers
+For machines equipped with floating point,
+.CW Fpr
+displays the contents of the floating point registers as double precision
+values.
+.Ex
+acid: Fpr()
+F0 0. F2 0.
+F4 0. F6 0.
+F8 0. F10 0.
+\&...
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP Ureg integer "Display contents of Ureg structure
+.CW Ureg
+interprets the integer passed as its first argument as the address of a
+kernel
+.CW Ureg
+structure. Each element of the structure is retrieved and printed.
+The size and contents of the
+.CW Ureg
+structure are architecture dependent.
+This function can be used to decode the first argument passed to a
+.I notify (2)
+function after a process has received a note.
+.Ex
+acid: Ureg(*notehandler:ur)
+ status 0x3000f000
+ pc 0x1020
+ sp 0x7ffffe00
+ cause 0x00004002
+\&...
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP acidinit "" "Interpreter startup
+.CW acidinit
+is called by the interpreter after all
+modules have been loaded at initialization time.
+It is used to set up machine specific variables and the default source path.
+.CW acidinit
+should not be called by user code.
+.KE
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP addsrcdir string "Add element to source search path
+.CW addsrcdir
+interprets its string argument as a new directory
+.CW findsrc
+should search when looking for source code files.
+.CW addsrcdir
+draws an error if the directory is already in the source search path. The search
+path may be examined by looking at the variable
+.CW srcpath .
+.Ex
+acid: rc("9fs fornax")
+acid: addsrcpath("/n/fornax/sys/src/cmd")
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP asm integer "Disassemble machine instructions
+.CW asm
+interprets its integer argument as a text address from which to disassemble
+machine instructions.
+.CW asm
+prints the instruction address in symbolic and hexadecimal form, then prints
+the instructions with addressing modes. Up to twenty instructions will
+be disassembled.
+.CW asm
+stops disassembling when it reaches the end of the current function.
+Instructions are read from the file image using the
+.CW @
+operator.
+.Ex
+acid: asm(main)
+main 0x00001020 ADD $-0x64,R29
+main+0x4 0x00001024 MOVW R31,0x0(R29)
+main+0x8 0x00001028 MOVW R1,argc+4(FP)
+main+0xc 0x0000102c MOVW $bin(SB),R1
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP bpdel integer "Delete breakpoint
+.CW bpdel
+removes a previously set breakpoint from memory.
+The
+.I integer
+supplied as its argument must be the address of a previously set breakpoint.
+The breakpoint address is deleted from the active breakpoint list
+.CW bplist ,
+then the original instruction is copied from the file image to the memory
+image so that the breakpoint is removed.
+.Ex
+acid: bpdel(main+4)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP bpset integer "Set a breakpoint
+.CW bpset
+places a breakpoint instruction at the address specified
+by its
+.I integer
+argument, which must be in the text segment.
+.CW bpset
+draws an error if a breakpoint has already been set at the specified address.
+A list of current breakpoints is maintained in the variable
+.CW bplist .
+Unlike in
+.I db (1),
+breakpoints are left in memory even when a process is stopped, and
+the process must exist, perhaps by being
+created by either
+.CW new
+or
+.CW win ,
+in order to place a breakpoint.
+.CW Db "" (
+accepts breakpoint commands before the process is started.)
+On the
+MIPS and SPARC architectures,
+breakpoints at function entry points should be set 4 bytes into the function
+because the
+instruction scheduler may fill
+.CW JAL
+branch delay slots with the first instruction of the function.
+.Ex
+acid: bpset(main+4)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP bptab "" "List active breakpoints
+.CW bptab
+prints a list of currently installed breakpoints. The list contains the
+breakpoint address in symbolic and hexadecimal form as well as the instruction
+the breakpoint replaced. Breakpoints are not maintained across process creation
+using
+.CW new
+and
+.CW win .
+They are maintained across a fork, but care must be taken to keep control of
+the child process.
+.Ex
+acid: bpset(ls+4)
+acid: bptab()
+ 0x00001420 ls+0x4 MOVW R31,0x0(R29)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP casm "" "Continue disassembly
+.CW casm
+continues to disassemble instructions from where the last
+.CW asm
+or
+.CW casm
+command stopped. Like
+.CW asm ,
+this command stops disassembling at function boundaries.
+.Ex
+acid: casm()
+main+0x10 0x00001030 MOVW $0x1,R3
+main+0x14 0x00001034 MOVW R3,0x8(R29)
+main+0x18 0x00001038 MOVW $0x1,R5
+main+0x1c 0x0000103c JAL Binit(SB)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP cont "" "Continue program execution
+.CW cont
+restarts execution of the currently active process.
+If the process is stopped on a breakpoint, the breakpoint is first removed,
+the program is single stepped, the breakpoint is replaced and the program
+is then set executing. This may cause
+.CW stopped()
+to be called twice.
+.CW cont
+causes the interpreter to block until the process enters the
+.CW Stopped
+state.
+.Ex
+acid: cont()
+95197: breakpoint ls+0x4 MOVW R31,0x0(R29)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP dump integer,integer,string "Formatted memory dump
+.CW dump
+interprets its first argument as an address, its second argument as a
+count and its third as a format string.
+.CW dump
+fetches an object from memory at the current address and prints it according
+to the format. The address is incremented by the number of bytes specified by
+the format and the process is repeated count times. The format string is any
+combination of format characters, each preceded by an optional count.
+For each object,
+.CW dump
+prints the address in hexadecimal, a colon, the object and then a newline.
+.CW dump
+uses
+.CW mem
+to fetch each object.
+.Ex
+acid: dump(main+35, 4, "X2bi")
+0x00001043: 0x0c8fa700 108 143 lwc2 r0,0x528f(R4)
+0x0000104d: 0xa9006811 0 0 swc3 r0,0x0(R24)
+0x00001057: 0x2724e800 4 37 ADD $-0x51,R23,R31
+0x00001061: 0xa200688d 6 0 NOOP
+0x0000106b: 0x2710c000 7 0 BREAK
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP findsrc string "Use source path to load source file
+.CW findsrc
+interprets its
+.I string
+argument as a source file. Each directory in the source path is searched
+in turn for the file. If the file is found, the source text is loaded using
+.CW file
+and stored in the list of active source files called
+.CW srctext .
+The name of the file is added to the source file name list
+.CW srcfiles .
+Users are unlikely to call
+.CW findsrc
+from the command line, but may use it from scripts to preload source files
+for a debugging session. This function is used by
+.CW src
+and
+.CW line
+to locate and load source code. The default search path for the MIPS
+is
+.CW ./ ,
+.CW /sys/src/libc/port ,
+.CW /sys/src/libc/9sys ,
+.CW /sys/src/libc/mips .
+.Ex
+acid: findsrc(pcfile(main));
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP fpr "" "Display single precision floating registers
+For machines equipped with floating point,
+.CW fpr
+displays the contents of the floating point registers as single precision
+values. When the interpreter stores or manipulates floating point values
+it converts into double precision values.
+.Ex
+acid: fpr()
+F0 0. F1 0.
+F2 0. F3 0.
+F4 0. F5 0.
+\&...
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP func "" "Step while in function
+.CW func
+single steps the active process until it leaves the current function
+by either calling another function or returning to its caller.
+.CW func
+will execute a single instruction after leaving the current function.
+.Ex
+acid: func()
+95197: breakpoint ls+0x8 MOVW R1,R8
+95197: breakpoint ls+0xc MOVW R8,R1
+95197: breakpoint ls+0x10 MOVW R8,s+4(FP)
+95197: breakpoint ls+0x14 MOVW $0x2f,R5
+95197: breakpoint ls+0x18 JAL utfrrune(SB)
+95197: breakpoint utfrrune ADD $-0x18,R29
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP gpr "" "Display general purpose registers
+.CW gpr
+prints the values of the general purpose processor registers.
+.Ex
+acid: gpr()
+R1 0x00009562 R2 0x000010a4 R3 0x00005d08
+R4 0x0000000a R5 0x0000002f R6 0x00000008
+\&...
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP labstk integer "Print stack trace from label
+.CW labstk
+performs a stack trace from a Plan 9
+.I label.
+The kernel,
+C compilers store continuations in a common format. Since the
+compilers all use caller save conventions a continuation may be saved by
+storing a
+.CW PC
+and
+.CW SP
+pair. This data structure is called a label and is used by the
+the C function
+.CW longjmp
+and the kernel to schedule threads and processes.
+.CW labstk
+interprets its
+.I integer
+argument as the address of a label and produces a stack trace for
+the thread of execution. The value of the function
+.CW ALEF_tid
+is a suitable argument for
+.CW labstk .
+.Ex
+acid: labstk(*mousetid)
+At pc:0x00021a70:Rendez_Sleep+0x178 rendez.l:44
+Rendez_Sleep(r=0xcd7d8,bool=0xcd7e0,t=0x0) rendez.l:5
+ called from ALEF_rcvmem+0x198 recvmem.l:45
+ALEF_rcvmem(c=0x000cd764,l=0x00000010) recvmem.l:6
+\&...
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP lstk "" "Stack trace with local variables
+.CW lstk
+produces a long format stack trace.
+The stack trace includes each function in the stack,
+where it was called from, and the value of the parameters and automatic
+variables for each function.
+.CW lstk
+displays the value rather than the address of each variable and all
+variables are assumed to be an integer in format
+.CW X .
+To print a variable in its correct format use the
+.CW :
+operator to find the address and apply the appropriate format before indirection
+with the
+.CW *
+operator. It may be necessary to single step a couple of instructions into
+a function to get a correct stack trace because the frame pointer adjustment
+instruction may get scheduled down into the body of the function.
+.Ex
+acid: lstk()
+At pc:0x00001024:main+0x4 ls.c:48
+main(argc=0x00000001,argv=0x7fffefec) ls.c:48
+ called from _main+0x20 main9.s:10
+ _argc=0x00000000
+ _args=0x00000000
+ fd=0x00000000
+ buf=0x00000000
+ i=0x00000000
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP mem integer,string "Print memory object
+.CW mem
+interprets its first
+.I integer
+argument as the address of an object to be printed according to the
+format supplied in its second
+.I string
+argument.
+The format string can be any combination of format characters, each preceded
+by an optional count.
+.Ex
+acid: mem(bdata+0x326, "2c2Xb")
+P = 0xa94bc464 0x3e5ae44d 19
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP new "" "Create new process
+.CW new
+starts a new copy of the debugged program. The new program is started
+with the program arguments set by the variable
+.CW progargs .
+The new program is stopped in the second instruction of
+.CW main .
+The breakpoint list is reinitialized.
+.CW new
+may be used several times to instantiate several copies of a program
+simultaneously. The user can rotate between the copies using
+.CW setproc .
+.Ex
+acid: progargs="-l"
+acid: new()
+60: external interrupt _main ADD $-0x14,R29
+60: breakpoint main+0x4 MOVW R31,0x0(R29)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP next "" "Step through language statement
+.CW next
+steps through a single language level statement without tracing down
+through each statement in a called function. For each statement,
+.CW next
+prints the machine instructions executed as part of the statement. After
+the statement has executed, source lines around the current program
+counter are displayed.
+.Ex
+acid: next()
+60: breakpoint Binit+0x4 MOVW R31,0x0(R29)
+60: breakpoint Binit+0x8 MOVW f+8(FP),R4
+binit.c:93
+ 88
+ 89 int
+ 90 Binit(Biobuf *bp, int f, int mode)
+ 91 {
+>92 return Binits(bp, f, mode, bp->b, BSIZE);
+ 93 }
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP notestk integer "Stack trace after receiving a note
+.CW notestk
+interprets its
+.I integer
+argument as the address of a
+.CW Ureg
+structure passed by the kernel to a
+.I notify (2)
+function during note processing.
+.CW notestk
+uses the
+.CW PC ,
+.CW SP ,
+and link register from the
+.CW Ureg
+to print a stack trace corresponding to the point in the program where the note
+was received.
+To get a valid stack trace on the MIPS and SPARC architectures from a notify
+routine, the program must stop in a new function called from the notify routine
+so that the link register is valid and the notify routine's parameters are
+addressable.
+.Ex
+acid: notestk(*notify:ur)
+Note pc:0x00001024:main+0x4 ls.c:48
+main(argc=0x00000001,argv=0x7fffefec) ls.c:48
+ called from _main+0x20 main9.s:10
+ _argc=0x00000000
+ _args=0x00000000
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP pfl integer "Print source file and line
+.CW pfl
+interprets its argument as a text address and uses it to print
+the source file and line number corresponding to the address. The output
+has the same format as file addresses in
+.I acme (1).
+.Ex
+acid: pfl(main)
+ls.c:48
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP procs "" "Print active process list
+.CW procs
+prints a list of active process attached to the debugger. Each process
+produces a single line of output giving the pid, process state, the address
+the process is currently executing, and the
+.CW setproc
+command required to make that process current.
+The current process is marked in the first column with a
+.CW >
+character. The debugger maintains a list of processes in the variable
+.CW proclist .
+.Ex
+acid: procs()
+>62: Stopped at main+0x4 setproc(62)
+ 60: Stopped at Binit+0x8 setproc(60)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP pstop integer "Print reason process stopped
+.CW pstop
+prints the status of the process specified by the
+.I integer
+pid supplied as its argument.
+.CW pstop
+is usually called from
+.CW stopped
+every time a process enters the
+.CW Stopped
+state.
+.Ex
+acid: pstop(62)
+0x0000003e: breakpoint main+0x4 MOVW R31,0x0(R29)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP regs "" "Print registers
+.CW regs
+prints the contents of both the general and special purpose registers.
+.CW regs
+calls
+.CW spr
+then
+.CW gpr
+to display the contents of the registers.
+.KE
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP source "" "Summarize source data base
+.CW source
+prints the directory search path followed by a list of currently loaded
+source files. The source management functions
+.CW src
+and
+.CW findsrc
+use the search path to locate and load source files. Source files are
+loaded incrementally into a source data base during debugging. A list
+of loaded files is stored in the variable
+.CW srcfiles
+and the contents of each source file in the variable
+.CW srctext .
+.Ex
+acid: source()
+/n/bootes/sys/src/libbio/
+./
+/sys/src/libc/port/
+/sys/src/libc/9sys/
+/sys/src/libc/mips/
+ binit.c
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP spr "" "Print special purpose registers
+.CW spr
+prints the contents of the processor control and memory management
+registers. Where possible, the contents of the registers are decoded
+to provide extra information; for example the
+.CW CAUSE
+register on the MIPS is
+printed both in hexadecimal and using the
+.CW reason
+function.
+.Ex
+acid: spr()
+PC 0x00001024 main+0x4 ls.c:48
+SP 0x7fffef68 LINK 0x00006264 _main+0x28 main9.s:12
+STATUS 0x0000ff33 CAUSE 0x00000024 breakpoint
+TLBVIR 0x000000d3 BADVADR 0x00001020
+HI 0x00000004 LO 0x00001ff7
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP src integer "Print lines of source
+.CW src
+interprets its
+.I integer
+argument as a text address and uses this address to print 5 lines
+of source before and after the address. The current line is marked with a
+.CW >
+character.
+.CW src
+uses the source search path maintained by
+.CW source
+and
+.CW addsrcdir
+to locate the required source files.
+.Ex
+acid: src(*PC)
+ls.c:47
+ 42 Biobuf bin;
+ 43
+ 44 #define HUNK 50
+ 45
+ 46 void
+>47 main(int argc, char *argv[])
+ 48 {
+ 49 int i, fd;
+ 50 char buf[64];
+ 51
+ 52 Binit(&bin, 1, OWRITE);
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP step "" "Single step process
+.CW step
+causes the debugged process to execute a single machine level instruction.
+If the program is stopped on a breakpoint set by
+.CW bpset
+it is first removed, the single step executed, and the breakpoint replaced.
+.CW step
+uses
+.CW follow
+to predict the address of the program counter after the current instruction
+has been executed. A breakpoint is placed at each of these predicted addresses
+and the process is started. When the process stops the breakpoints are removed.
+.Ex
+acid: step()
+62: breakpoint main+0x8 MOVW R1,argc+4(FP)
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP stk "" "Stack trace
+.CW stk
+produces a short format stack trace. The stack trace includes each function
+in the stack, where it was called from, and the value of the parameters.
+The short format omits the values of automatic variables.
+Parameters are assumed to be integer values in the format
+.CW X ;
+to print a parameter in the correct format use the
+.CW :
+to obtain its address, apply the correct format, and use the
+.CW *
+indirection operator to find its value.
+It may be necessary to single step a couple of instructions into
+a function to get a correct stack trace because the frame pointer adjustment
+instruction may get scheduled down into the body of the function.
+.Ex
+acid: stk()
+At pc:0x00001028:main+0x8 ls.c:48
+main(argc=0x00000002,argv=0x7fffefe4) ls.c:48
+ called from _main+0x20 main9.s:10
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP stmnt "" "Execute a single statement
+.CW stmnt
+executes a single language level statement.
+.CW stmnt
+displays each machine level instruction as it is executed. When the executed
+statement is completed the source for the next statement is displayed.
+Unlike
+.CW next ,
+the
+.CW stmnt
+function will trace down through function calls.
+.Ex
+acid: stmnt()
+62: breakpoint main+0x18 MOVW R5,0xc(R29)
+62: breakpoint main+0x1c JAL Binit(SB)
+62: breakpoint Binit ADD $-0x18,R29
+binit.c:91
+ 89 int
+ 90 Binit(Biobuf *bp, int f, int mode)
+>91 {
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP stopped integer "Report status of stopped process
+.CW stopped
+is called automatically by the interpreter
+every time a process enters the
+.CW Stopped
+state, such as when it hits a breakpoint.
+The pid is passed as the
+.I integer
+argument. The default implementation just calls
+.CW pstop ,
+but the function may be changed to provide more information or perform fine control
+of execution. Note that
+.CW stopped
+should return; for example, calling
+.CW step
+in
+.CW stopped
+will recur until the interpreter runs out of stack space.
+.Ex
+acid: defn stopped(pid) {
+ if *lflag != 0 then error("lflag modified");
+ }
+acid: progargs = "-l"
+acid: new();
+acid: while 1 do step();
+<stdin>:7: (error) lflag modified
+acid: stk()
+At pc:0x00001220:main+0x200 ls.c:54
+main(argc=0x00000001,argv=0x7fffffe8) ls.c:48
+ called from _main+0x20 main9.s:10
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP symbols string "Search symbol table
+.CW symbols
+uses the regular expression supplied by
+.I string
+to search the symbol table for symbols whose name matches the
+regular expression.
+.Ex
+acid: symbols("main")
+main T 0x00001020
+_main T 0x0000623c
+.Ee
+.\"
+.\"
+.\"
+.Ip \f(CW{}\fP win "" "Start new process in a window
+.CW win
+performs exactly the same function as
+.CW new
+but uses the window system to create a new window for the debugged process.
+The variable
+.CW progargs
+supplies arguments to the new process.
+The environment variable
+.CW $8½srv
+must be set to allow the interpreter to locate the mount channel for the
+window system.
+The window is created in the top left corner of the screen and is
+400x600 pixels in size. The
+.CW win
+function may be modified to alter the geometry.
+The window system will not be able to deliver notes in the new window
+since the pid of the created process is not passed when the server is
+mounted to create a new window.
+.Ex
+acid: win()
+.Ee