12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921 |
- <html>
- <title>
- data
- </title>
- <body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
- <H1>Acid Manual
- </H1>
- <DL><DD><I>Phil Winterbottom<br>
- philw@plan9.bell-labs.com<br>
- </I></DL>
- <H4>Introduction
- </H4>
- <P>
- 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.
- </P>
- <P>
- 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
- <TT>include</TT>
- function or using the support provided by
- <A href="/magic/man2html/1/acme"><I>acme</I>(1)),
- </A>rather than by trying to type intricate Acid operations
- at the interactive prompt.
- </P>
- <P>
- 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.
- </P>
- <P>
- A Plan 9 process is controlled by writing messages to a control file in the
- <A href="/magic/man2html/3/proc"><I>proc</I>(3)
- </A>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</I>)
- 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.
- </P>
- <H4>Input format and <TT>whatis</TT>
- </H4>
- <P>
- Comments start with
- <TT>//</TT>
- 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
- <TT>print</TT>
- is called automatically to display the result of all expressions except function calls.
- A unary
- <TT>+</TT>
- may be used as a shorthand to force the result of a function call to be printed.
- </P>
- <P>
- Also at the top level, newlines are treated as semicolons
- by the parser, so semicolons are unnecessary when evaluating expressions.
- </P>
- <P>
- 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.
- </P>
- <P>
- The
- <TT>whatis</TT>
- operator can be used to report the state of identifiers known to the interpreter.
- With no argument,
- <TT>whatis</TT>
- 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
- <TT>whatis</TT>
- 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.
- </P>
- <H4>Using the Library Functions
- </H4>
- <P>
- 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:
- <DL><DT><DD><TT><PRE>
- % acid /bin/ls
- /bin/ls:mips plan 9 executable
- /sys/lib/acid/port
- /sys/lib/acid/mips
- acid: new()
- 75721: system call _main ADD <I>-0x14,R29
- 75721: breakpoint main+0x4 MOVW R31,0x0(R29)
- acid: bpset(ls)
- acid: cont()
- 75721: breakpoint ls ADD </I>-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
- </PRE></TT></DL>
- The function
- <TT>new()</TT>
- creates a new process and stops it at the first instruction.
- This change in state is reported by a call to the
- Acid function
- <TT>stopped</TT>,
- which is called by the interpreter whenever the debugged program stops.
- <TT>Stopped</TT>
- prints the status line giving the pid, the reason the program stopped
- and the address and instruction at the current PC.
- The function
- <TT>bpset</TT>
- makes an entry in the breakpoint table and plants a breakpoint in memory.
- The
- <TT>cont</TT>
- 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
- <TT>ls</TT>
- in the C program. Once again the
- <TT>stopped</TT>
- routine is called to print the status of the program. The function
- <TT>stk</TT>
- 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
- <TT>PC</TT>
- holds the address of the
- cell where the current value of the processor register
- <TT>PC</TT>
- is stored. By indirecting through
- the value of
- <TT>PC</TT>
- the address where the program is stopped can be found.
- All of the processor registers are available by the same mechanism.
- </P>
- <H4>Types
- </H4>
- <P>
- An Acid variable has one of four types:
- <I>integer</I>,
- <I>float</I>,
- <I>list</I>,
- or
- <I>string</I>.
- 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</I>
- section of this manual.
- </P>
- <H4>Variables
- </H4>
- <P>
- 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.
- </P>
- <P>
- Some examples of variables maintained by the interpreter are the register
- pointers listed by name in the Acid list variable
- <TT>registers</TT>,
- and the symbol table listed by name and contents in the Acid variable
- <TT>symbols</TT>.
- </P>
- <P>
- The variable
- <TT>pid</TT>
- is updated by the interpreter to select the most recently created process
- or the process selected by the
- <TT>setproc</TT>
- builtin function.
- </P>
- <H4>Formats
- </H4>
- <P>
- 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
- <A href="/magic/man2html/1/db"><I>db</I>(1).
- </A>By default, symbol table variables and numeric constants
- are assigned the format code
- <TT>X</TT>,
- which specifies 32-bit hexadecimal.
- Printing a variable with this code yields the output
- <TT>0x00123456</TT>.
- The format code of a variable may be changed from the default by using the
- builtin function
- <TT>fmt</TT>.
- 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
- <TT>fmt</TT>.
- The backslash operator is a short form of
- <TT>fmt</TT>.
- 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:
- <DL><DT><DD><TT><PRE>
- 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\o
- 12
- </PRE></TT></DL>
- The supported format characters are:
- <DL><DD>
- </P>
- <DL COMPACT>
- <DT><TT>o</TT><DD>
- Print two-byte integer in octal.
- <DT><TT>O</TT><DD>
- Print four-byte integer in octal.
- <DT><TT>q</TT><DD>
- Print two-byte integer in signed octal.
- <DT><TT>Q</TT><DD>
- Print four-byte integer in signed octal.
- <DT><TT>B</TT><DD>
- Print four-byte integer in binary.
- <DT><TT>d</TT><DD>
- Print two-byte integer in signed decimal.
- <DT><TT>D</TT><DD>
- Print four-byte integer in signed decimal.
- <DT><TT>Y</TT><DD>
- Print eight-byte integer in signed decimal.
- <DT><TT>Z</TT><DD>
- Print eight-byte integer in unsigned decimal.
- <DT><TT>x</TT><DD>
- Print two-byte integer in hexadecimal.
- <DT><TT>X</TT><DD>
- Print four-byte integer in hexadecimal.
- <DT><TT>Y</TT><DD>
- Print eight-byte integer in hexadecimal.
- <DT><TT>u</TT><DD>
- Print two-byte integer in unsigned decimal.
- <DT><TT>U</TT><DD>
- Print four-byte integer in unsigned decimal.
- <DT><TT>f</TT><DD>
- Print single-precision floating point number.
- <DT><TT>F</TT><DD>
- Print double-precision floating point number.
- <DT><TT>g</TT><DD>
- Print a single precision floating point number in string format.
- <DT><TT>G</TT><DD>
- Print a double precision floating point number in string format.
- <DT><TT>b</TT><DD>
- Print byte in hexadecimal.
- <DT><TT>c</TT><DD>
- Print byte as an ASCII character.
- <DT><TT>C</TT><DD>
- Like
- <TT>c</TT>,
- with
- printable ASCII characters represented normally and
- others printed in the form <TT>\x</TT><I>nn</I>.
- <DT><TT>s</TT><DD>
- Interpret the addressed bytes as UTF characters
- and print successive characters until a zero byte is reached.
- <DT><TT>r</TT><DD>
- Print a two-byte integer as a rune.
- <DT><TT>R</TT><DD>
- Print successive two-byte integers as runes
- until a zero rune is reached.
- <DT><TT>i</TT><DD>
- Print as machine instructions.
- <DT><TT>I</TT><DD>
- As
- <TT>i</TT>
- above, but print the machine instructions in
- an alternate form if possible:
- <TT>sunsparc</TT>
- and
- <TT>mipsco</TT>
- reproduce the manufacturers' syntax.
- <DT><TT>a</TT><DD>
- Print the value in symbolic form.
- </DL>
- </dl>
- <H4>Complex types
- </H4>
- <P>
- Acid permits the definition of the layout of memory.
- The usual method is to use the
- <TT>-a</TT>
- flag of the compilers to produce Acid-language descriptions of data structures (see
- <A href="/magic/man2html/1/2c"><I>2c</I>(1))
- </A>although such definitions can be typed interactively.
- The keywords
- <TT>complex</TT>,
- <TT>adt</TT>,
- <TT>aggr</TT>,
- and
- <TT>union</TT>
- 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
- <DL><DT><DD><TT><PRE>
- struct List {
- int type;
- struct List *next;
- };
- </PRE></TT></DL>
- is described by the Acid statement
- <DL><DT><DD><TT><PRE>
- complex List {
- 'D' 0 type;
- 'X' 4 next;
- };
- </PRE></TT></DL>
- </P>
- <H4>Scope
- </H4>
- <P>
- Variables are global unless they are either parameters to functions
- or are declared as
- <TT>local</TT>
- 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
- <TT>f</TT>
- has a local called
- <TT>main</TT>,
- any function called below
- <TT>f</TT>
- will see the local version of
- <TT>main</TT>,
- not the external symbol.
- </P>
- <H4>Addressing
- </H4>
- <P>
- 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.
- </P>
- <P>
- 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 (<I>t</I>,
- <I>b</I>,
- <I>e</I>,
- <I>f</I>),
- defining a segment named
- <I>t</I>
- (usually
- <TT>text</TT>,
- <TT>data</TT>,
- <TT>regs</TT>,
- or
- <TT>fpregs</TT>)
- mapping addresses in the range
- <I>b</I>
- through
- <I>e</I>
- to the part of the file
- beginning at
- offset
- <I>f</I>.
- 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</I>
- is translated
- to a file address
- by finding a segment
- for which
- <I>b</I>
- +
- <I>a</I>
- <
- <I>e</I>;
- the location in the file
- is then
- <I>address</I>
- +
- <I>f</I>
- -
- <I>b</I>.
- </P>
- <P>
- Usually,
- the text and initialized data of a program
- are mapped by segments called
- <TT>text</TT>
- and
- <TT>data</TT>.
- 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
- <TT>*data</TT>
- 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
- <TT>*regs</TT>
- maps the registers;
- <TT>*fpregs</TT>
- maps the floating point registers.
- </P>
- <P>
- 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
- <TT>map</TT>
- examines and modifies Acid's map for a process.
- </P>
- <H4>Name Conflicts
- </H4>
- <P>
- 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
- <TT></TT><I></I><TT>
- 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:
- <DL><DT><DD><TT><PRE>
- /bin/sam: mips plan 9 executable
- /lib/acid/port
- /lib/acid/mips
- Symbol renames:
- append=</TT>append T/0xa4e40
- acid:
- </PRE></TT></DL>
- The symbol
- <TT>append</TT>
- is both a keyword and a text symbol in the program. The message reports
- that the text symbol is now named
- <TT></TT><I>append</I><TT>.
- </P>
- </TT><H4>Expressions
- </H4>
- <P>
- Operators have the same
- binding and precedence as in C.
- For operators of equal precedence, expressions are evaluated from left to right.
- </P>
- <H4>Boolean expressions
- </H4>
- <P>
- 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</I>
- or
- <I>floating</I>
- type the result is true if the value is non-zero. If the expression is a
- <I>list</I>
- the result is true if there are any members in the list.
- If the expression is a
- <I>string</I>
- the result is true if there are any characters in the string.
- <DL><DT><DD><TT><PRE>
- primary-expression:
- identifier
- identifier <TT>:</TT> identifier
- constant
- <TT>(</TT> expression <TT>)</TT>
- <TT>{</TT> elist <TT>}</TT>
- elist:
- expression
- elist , expression
- </PRE></TT></DL>
- 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:
- <DL><DT><DD><TT><PRE>
- *main:argc
- </PRE></TT></DL>
- 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.
- </P>
- <P>
- 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
- <TT>{}</TT>.
- <DL><DT><DD><TT><PRE>
- acid: x = 10
- acid: l = { 1, x, 2\D }
- acid: x = 20
- acid: l
- {0x00000001 , 0x0000000a , 2 }
- </PRE></TT></DL>
- </P>
- <H4>Lists
- </H4>
- <P>
- Several operators manipulate lists.
- <DL><DT><DD><TT><PRE>
- list-expression:
- primary-expression
- <TT>head</TT> primary-expression
- <TT>tail</TT> primary-expression
- <TT>append</TT> expression <TT>,</TT> primary-expression
- <TT>delete</TT> expression <TT>,</TT> primary-expression
- </PRE></TT></DL>
- The
- <I>primary-expression</I>
- for
- <TT>head</TT>
- and
- <TT>tail</TT>
- must yield a value of type
- <I>list</I>.
- If there are no elements in the list the value of
- <TT>head</TT>
- or
- <TT>tail</TT>
- will be the empty list. Otherwise
- <TT>head</TT>
- evaluates to the first element of the list and
- <TT>tail</TT>
- evaluates to the rest.
- <DL><DT><DD><TT><PRE>
- acid: head {}
- {}
- acid: head {1, 2, 3, 4}
- 0x00000001
- acid: tail {1, 2, 3, 4}
- {0x00000002 , 0x00000003 , 0x00000004 }
- </PRE></TT></DL>
- The first operand of
- <TT>append</TT>
- and
- <TT>delete</TT>
- must be an expression that yields a
- <I>list</I>.
- <TT>Append</TT>
- places the result of evaluating
- <I>primary-expression</I>
- at the end of the list.
- The
- <I>primary-expression</I>
- supplied to
- <TT>delete</TT>
- must evaluate to an integer;
- <TT>delete</TT>
- removes the
- <I>n</I>'th
- item from the list, where
- <I>n</I>
- is integral value of
- <I>primary-expression.</I>
- List indices are zero-based.
- <DL><DT><DD><TT><PRE>
- acid: append {1, 2}, 3
- {0x00000001 , 0x00000002 , 0x00000003 }
- acid: delete {1, 2, 3}, 1
- {0x00000001 , 0x00000003 }
- </PRE></TT></DL>
- </P>
- <P>
- 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
- <TT>head</TT>
- and
- <TT>append</TT>.
- </P>
- <H4>Operators
- </H4>
- <P>
- <DL><DT><DD><TT><PRE>
- postfix-expression:
- list-expression
- postfix-expression <TT>[</TT> expression <TT>]</TT>
- postfix-expression <TT>(</TT> argument-list <TT>)</TT>
- postfix-expression <TT>.</TT> tag
- postfix-expression <TT>-></TT> tag
- postfix-expression <TT>++</TT>
- postfix-expression <TT>--</TT>
- argument-list:
- expression
- argument-list , expression
- </PRE></TT></DL>
- The
- <TT>[</TT>
- <I>expression</I>
- <TT>]</TT>
- operator performs indexing.
- The indexing expression must result in an expression of
- <I>integer</I>
- type, say
- <I>n</I>.
- The operation depends on the type of
- <I>postfix-expression</I>.
- If the
- <I>postfix-expression</I>
- yields an
- <I>integer</I>
- 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</I>.
- If the
- <I>postfix-expression</I>
- yields a
- <I>string</I>
- the index operator fetches the
- <I>n</I>'th
- character
- of the string. If the index points beyond the end
- of the string, a zero is returned.
- If the
- <I>postfix-expression</I>
- yields a
- <I>list</I>
- then the indexing operation returns the
- <I>n</I>'th
- item of the list.
- If the list contains less than
- <I>n</I>
- items the empty list
- <TT>{}</TT>
- is returned.
- </P>
- <P>
- The
- <TT>++</TT>
- and
- <TT>--</TT>
- 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.
- <DL><DT><DD><TT><PRE>
- unary-expression:
- postfix-expression
- <TT>++</TT> unary-expression
- <TT>--</TT> unary-expression
- unary-operator: one of
- <TT>*</TT> <TT>@</TT> <TT>+</TT> <TT>-</TT> ~ <TT>!</TT>
- </PRE></TT></DL>
- The operators
- <TT>*</TT>
- and
- <TT>@</TT>
- are the indirection operators.
- <TT>@</TT>
- references a value from the text file of the program being debugged.
- The size of the value depends on the format code. The
- <TT>*</TT>
- 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
- <TT>-w</TT>
- option.
- The prefix
- <TT>++</TT>
- and
- <TT>--</TT>
- operators perform the same operation as their postfix counterparts but
- return the value after the increment or decrement has been performed. Since the
- <TT>++</TT>
- and
- <TT>*</TT>
- 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:
- <DL><DT><DD><TT><PRE>
- defn asm(addr)
- {
- addr = fmt(addr, 'i');
- loop 1, 10 do
- print(*addr++, "\n");
- }
- </PRE></TT></DL>
- The operators
- <TT>~</TT>
- and
- <TT>!</TT>
- perform bitwise and logical negation respectively. Their operands must be of
- <I>integer</I>
- type.
- <DL><DT><DD><TT><PRE>
- cast-expression:
- unary-expression
- unary-expression <TT>\</TT> format-char
- <TT>(</TT> complex-name <TT>)</TT> unary-expression
- </PRE></TT></DL>
- A unary expression may be preceded by a cast. The cast has the effect of
- associating the value of
- <I>unary-expression</I>
- with a complex type structure.
- The result may then be dereferenced using the
- <TT>.</TT>
- and
- <TT>-></TT>
- operators.
- </P>
- <P>
- An Acid variable may be associated with a complex type
- to enable accessing the type's members:
- <DL><DT><DD><TT><PRE>
- 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
- </PRE></TT></DL>
- Note that the
- <TT>next</TT>
- field cannot be given a complex type automatically.
- </P>
- <P>
- When entered at the top level of the interpreter,
- an expression of complex type
- is treated specially.
- If the type is called
- <TT>T</TT>
- and an Acid function also called
- <TT>T</TT>
- exists,
- then that function will be called with the expression as its argument.
- The compiler options
- <TT>-a</TT>
- and
- <TT>-aa</TT>
- will generate Acid source code defining such complex types and functions; see
- <A href="/magic/man2html/1/2c"><I>2c</I>(1).
- </A></P>
- <P>
- A
- <I>unary-expression</I>
- may be qualified with a format specifier using the
- <TT>\</TT>
- operator. This has the same effect as passing the expression to the
- <TT>fmt</TT>
- builtin function.
- <DL><DT><DD><TT><PRE>
- multiplicative-expression:
- cast-expression
- multiplicative-expression <TT>*</TT> multiplicative-expression
- multiplicative-expression <TT>/</TT> multiplicative-expression
- multiplicative-expression <TT>%</TT> multiplicative-expression
- </PRE></TT></DL>
- These operate on
- <I>integer</I>
- and
- <I>float</I>
- types and perform the expected operations:
- <TT>*</TT>
- multiplication,
- <TT>/</TT>
- division,
- <TT>%</TT>
- modulus.
- <DL><DT><DD><TT><PRE>
- additive-expression:
- multiplicative-expression
- additive-expression <TT>+</TT> multiplicative-expression
- additive-expression <TT>-</TT> multiplicative-expression
- </PRE></TT></DL>
- These operators perform as expected for
- <I>integer</I>
- and
- <I>float</I>
- operands.
- Unlike in C,
- <TT>+</TT>
- and
- <TT>-</TT>
- do not scale the addition based on the format of the expression.
- This means that
- <TT>i=i+1</TT>
- will always add 1 but
- <TT>i++</TT>
- will add the size corresponding to the format stored with
- <TT>i</TT>.
- If both operands are of either
- <I>string</I>
- or
- <I>list</I>
- type then addition is defined as concatenation. Subtraction is undefined for
- these two types.
- <DL><DT><DD><TT><PRE>
- shift-expression:
- additive-expression
- shift-expression <TT><<</TT> additive-expression
- shift-expression <TT>>></TT> additive-expression
- </PRE></TT></DL>
- The
- <TT>>></TT>
- and
- <TT><<</TT>
- operators perform bitwise right and left shifts respectively. Both
- require operands of
- <I>integer</I>
- type.
- <DL><DT><DD><TT><PRE>
- relational-expression:
- relational-expression <TT><</TT> shift-expression
- relational-expression <TT>></TT> shift-expression
- relational-expression <TT><=</TT> shift-expression
- relational-expression <TT>>=</TT> shift-expression
- equality-expression:
- relational-expression
- relational-expression <TT>==</TT> equality-expression
- relational-expression <TT>!=</TT> equality-expression
- </PRE></TT></DL>
- The comparison operators are
- <TT><</TT>
- (less than),
- <TT>></TT>
- (greater than),
- <TT><=</TT>
- (less than or equal to),
- <TT>>=</TT>
- (greater than or equal to),
- <TT>==</TT>
- (equal to) and
- <TT>!=</TT>
- (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</I>
- and
- <I>float</I>
- 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.
- <DL><DT><DD><TT><PRE>
- AND-expression:
- equality-expression
- AND-expression <TT>&</TT> equality-expression
- XOR-expression:
- AND-expression
- XOR-expression <TT>^</TT> AND-expression
- OR-expression:
- XOR-expression
- OR-expression <TT>|</TT> XOR-expression
- </PRE></TT></DL>
- These operators perform bitwise logical operations and apply only to the
- <I>integer</I>
- type.
- The operators are
- <TT>&</TT>
- (logical and),
- <TT>^</TT>
- (exclusive or) and
- <TT>|</TT>
- (inclusive or).
- <DL><DT><DD><TT><PRE>
- logical-AND-expression:
- OR-expression
- logical-AND-expression <TT>&&</TT> OR-expression
- logical-OR-expression:
- logical-AND-expression
- logical-OR-expression <TT>||</TT> logical-AND-expression
- </PRE></TT></DL>
- The
- <TT>&&</TT>
- operator returns 1 if both of its operands evaluate to boolean true, otherwise 0.
- The
- <TT>||</TT>
- operator returns 1 if either of its operands evaluates to boolean true,
- otherwise 0.
- </P>
- <H4>Statements
- </H4>
- <P>
- <DL><DT><DD><TT><PRE>
- <TT>if</TT> expression <TT>then</TT> statement <TT>else</TT> statement
- <TT>if</TT> expression <TT>then</TT> statement
- </PRE></TT></DL>
- The
- <I>expression</I>
- is evaluated as a boolean. If its value is true the statement after
- the
- <TT>then</TT>
- is executed, otherwise the statement after the
- <TT>else</TT>
- is executed. The
- <TT>else</TT>
- portion may be omitted.
- <DL><DT><DD><TT><PRE>
- <TT>while</TT> expression <TT>do</TT> statement
- </PRE></TT></DL>
- In a while loop, the
- <I>statement</I>
- is executed while the boolean
- <I>expression</I>
- evaluates
- true.
- <DL><DT><DD><TT><PRE>
- <TT>loop</TT> startexpr, endexpr <TT>do</TT> statement
- </PRE></TT></DL>
- The two expressions
- <I>startexpr</I>
- and
- <I>endexpr</I>
- are evaluated prior to loop entry.
- <I>Statement</I>
- is evaluated while the value of
- <I>startexpr</I>
- is less than or equal to
- <I>endexpr</I>.
- Both expressions must yield
- <I>integer</I>
- values. The value of
- <I>startexpr</I>
- is
- incremented by one for each loop iteration.
- Note that there is no explicit loop variable; the
- <I>expressions</I>
- are just values.
- <DL><DT><DD><TT><PRE>
- <TT>return</TT> expression
- </PRE></TT></DL>
- <TT>return</TT>
- terminates execution of the current function and returns to its caller.
- The value of the function is given by expression. Since
- <TT>return</TT>
- requires an argument, nil-valued functions should return the empty list
- <TT>{}</TT>.
- <DL><DT><DD><TT><PRE>
- <TT>local</TT> variable
- </PRE></TT></DL>
- The
- <TT>local</TT>
- statement creates a local instance of
- <I>variable</I>,
- 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</I>,
- is visible to called functions.
- After a return from the current function the previous value of
- <I>variable</I>
- is
- restored.
- </P>
- <P>
- If Acid is interrupted, the values of all local variables are lost,
- as if the function returned.
- <DL><DT><DD><TT><PRE>
- <TT>defn</TT> function-name <TT>(</TT> parameter-list <TT>)</TT> body
- parameter-list:
- variable
- parameter-list , variable
- body:
- <TT>{</TT> statement <TT>}</TT>
- </PRE></TT></DL>
- Functions are introduced by the
- <TT>defn</TT>
- 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.
- </P>
- <H4>Code variables
- </H4>
- <P>
- Acid permits the delayed evaluation of a parameter to a function. The parameter
- may then be evaluated at any time with the
- <TT>eval</TT>
- operator. Such parameters are called
- <I>code variables</I>
- and are defined by prefixing their name with an asterisk in their declaration.
- </P>
- <P>
- For example, this function wraps up an expression for later evaluation:
- <DL><DT><DD><TT><PRE>
- acid: defn code(*e) { return e; }
- acid: x = code(v+atoi("100")\D)
- acid: print(x)
- (v+atoi("100"))\D;
- acid: eval x
- <stdin>:5: (error) v used but not set
- acid: v=5
- acid: eval x
- 105
- </PRE></TT></DL>
- </P>
- <H4>Source Code Management
- </H4>
- <P>
- 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.
- </P>
- <H4>Builtin Functions
- </H4>
- <P>
- 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
- <TT>{}</TT>
- is used to denote the empty list, which is the default value of a function that
- does not execute a
- <TT>return</TT>
- 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</I>.
- </P>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>Access</TT>
- returns the integer 1 if the file name in
- <I>string</I>
- can be read by the builtin functions
- <TT>file</TT>,
- <TT>readfile</TT>,
- or
- <TT>include</TT>,
- otherwise 0. A typical use of this function is to follow
- a search path looking for a source file; it is used by
- <TT>findsrc</TT>.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- if access("main.c") then
- return file("main.c");
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>atof</TT>
- 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
- <TT>f</TT>.
- <TT>atof</TT>
- returns the value 0.0 if it is unable to perform the conversion.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: +atof("10.4e6")
- 1.04e+07
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>atoi</TT>
- converts the argument
- 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
- <TT>D</TT>.
- <TT>atoi</TT>
- returns the integer 0 if it is unable to perform a conversion.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: +atoi("-1255")
- -1255
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>error</TT>
- 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.
- <TT>error</TT>
- is commonly used to stop the debugger when some interesting condition arises
- in the debugged program.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- while 1 do {
- step();
- if *main != @main then
- error("memory corrupted");
- }
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>file</TT>
- reads the contents of the file specified by
- <I>string</I>
- into a list.
- Each element in the list is a string corresponding to a line in the file.
- <TT>file</TT>
- breaks lines at the newline character, but the newline
- characters are not returned as part each string.
- <TT>file</TT>
- returns the empty list if it encounters an error opening or reading the data.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: print(file("main.c")[0])
- #include <u.h>
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>filepc</TT>
- interprets its
- <I>string</I>
- argument as a source file address in the form of a file name and line offset.
- <TT>filepc</TT>
- uses the symbol table to map the source address into a text address
- in the debugged program. The
- <I>integer</I>
- return value has the format
- <TT>X</TT>.
- <TT>filepc</TT>
- returns an address of -1 if the source address is invalid.
- The source file address uses the same format as
- <A href="/magic/man2html/1/acme"><I>acme</I>(1).
- </A>This function is commonly used to set breakpoints from the source text.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: bpset(filepc("main:10"))
- acid: bptab()
- 0x00001020 usage ADD -0xc,R29
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>fmt</TT>
- evaluates the expression
- <I>item</I>
- and sets the format of the result to
- <I>fmt</I>.
- The format of a value determines how it will be printed and
- what kind of object will be fetched by the
- <TT>*</TT>
- and
- <TT>@</TT>
- operators. The
- <TT>\</TT>
- operator is a short-hand form of the
- <TT>fmt</TT>
- builtin function. The
- <TT>fmt</TT>
- function leaves the format of the
- <I>item</I>
- unchanged.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: main=fmt(main, 'i') // as instructions
- acid: print(main\X, "\t", *main)
- 0x00001020 ADD <I>-64,R29
- </PRE></TT></DL>
- </I><br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>fnbound</TT>
- interprets its
- <I>integer</I>
- argument as an address in the text of the debugged program.
- <TT>fnbound</TT>
- returns a list containing two integers corresponding to
- the start and end addresses of the function containing the supplied address.
- If the
- <I>integer</I>
- address is not in the text segment of the program then the empty list is returned.
- <TT>fnbound</TT>
- is used by
- <TT>next</TT>
- to detect stepping into new functions.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: print(fnbound(main))
- {0x00001050, 0x000014b8}
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- The follow set is defined as the set of program counter values that could result
- from executing an instruction.
- <TT>follow</TT>
- interprets its
- <I>integer</I>
- 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
- <TT>follow</TT>
- raises an error.
- <TT>follow</TT>
- is used to plant breakpoints on
- all potential paths of execution. The following code fragment
- plants breakpoints on top of all potential following instructions.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- lst = follow(*PC);
- while lst do
- {
- *head lst = bpinst;
- lst = tail lst;
- }
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>include</TT>
- opens the file specified by
- <I>string</I>
- 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.
- <TT>include</TT>
- can be used to incrementally load symbol table information without
- leaving the interpreter.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: include("/sys/src/cmd/acme/syms")
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>interpret</TT>
- evaluates the
- <I>string</I>
- 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
- <TT>interpret</TT>
- function allows Acid programs to write Acid code for later evaluation.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: interpret("main+10;")
- 0x0000102a
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>itoa</TT>
- takes an integer argument and converts it into an ASCII string
- in the
- <TT>D</TT>
- format.
- an alternate format string
- may be provided in the
- <TT>%</TT>
- style of
- <A href="/magic/man2html/2/print"><I>print</I>(2).
- </A>This function is commonly used to build
- <TT>rc</TT>
- command lines.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: rc("cat /proc/"+itoa(pid)+"/segment")
- Stack 7fc00000 80000000 1
- Data 00001000 00009000 1
- Data 00009000 0000a000 1
- Bss 0000a000 0000c000 1
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>kill</TT>
- writes a kill control message into the control file of the process
- specified by the
- <I>integer</I>
- pid.
- If the process was previously installed by
- <TT>setproc</TT>
- it will be removed from the list of active processes.
- If the
- <I>integer</I>
- has the same value as
- <TT>pid</TT>,
- then
- <TT>pid</TT>
- will be set to 0.
- To continue debugging, a new process must be selected using
- <TT>setproc</TT>.
- For example, to kill all the active processes:
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- while proclist do {
- kill(head proclist);
- proclist = tail proclist;
- }
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>map</TT>
- either retrieves all the mappings associated with a process or sets a single
- map entry to a new value.
- If the
- <I>list</I>
- argument is omitted then
- <TT>map</TT>
- 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
- <TT>*</TT>
- 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.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: map({"text", _start, end, 0x30})
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>match</TT>
- compares each item in
- <I>list</I>
- using the equality operator
- <TT>==</TT>
- with
- <I>item</I>.
- The
- <I>item</I>
- can be of any type. If the match succeeds the result is the integer index
- of the matching value, otherwise -1.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: list={8,9,10,11}
- acid: print(list[match(10, list)]\D)
- 10
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>newproc</TT>
- starts a new process with an argument vector constructed from
- <I>string</I>.
- The argument vector excludes the name of the program to execute and
- each argument in
- <I>string</I>
- must be space separated. A new process can accept no more
- than 512 arguments. The internal variable
- <TT>pid</TT>
- 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
- <TT>proclist</TT>.
- The new process is created then halted at the first instruction, causing
- the debugger to call
- <TT>stopped</TT>.
- The library functions
- <TT>new</TT>
- and
- <TT>win</TT>
- should be used to start processes when using the standard debugging
- environment.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: newproc("-l .")
- 56720: system call _main ADD -0x14,R29
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>pcfile</TT>
- interprets its
- <I>integer</I>
- 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
- <TT>?file?</TT>
- is returned.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: print("Now at ", pcfile(*PC), ":", pcline(*PC))
- Now at ls.c:46
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>pcline</TT>
- interprets its
- <I>integer</I>
- 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.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: +file("main.c")[pcline(main)]
- main(int argc, char *argv[])
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>print</TT>
- evaluates each
- <I>item</I>
- 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.
- <TT>print</TT>
- accepts a maximum of 512 arguments.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: print(10, "decimal ", 10\D, "octal ", 10\o)
- 0x0000000a decimal 10 octal 000000000012
- acid: print({1, 2, 3})
- {0x00000001 , 0x00000002 , 0x00000003 }
- acid: print(main, main\a, "\t", @main\i)
- 0x00001020 main ADD <I>-64,R29
- </PRE></TT></DL>
- </I><br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>printto</TT>
- offers a limited form of output redirection. The first
- <I>string</I>
- argument is used as the path name of a new file to create.
- Each
- <I>item</I>
- is then evaluated and printed to the newly created file. When all items
- have been printed the file is closed.
- <TT>printto</TT>
- accepts a maximum of 512 arguments.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: printto("/env/foo", "hello")
- acid: rc("echo -n foo")
- hello
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>rc</TT>
- evaluates
- <I>string</I>
- 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.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: rc("B "+itoa(-pcline(addr))+" "+pcfile(addr));
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>readfile</TT>
- takes the contents of the file specified by
- <I>string</I>
- and returns its contents as a new string.
- If
- <TT>readfile</TT>
- encounters a zero byte in the file, it terminates.
- If
- <TT>readfile</TT>
- encounters an error opening or reading the file then the empty list
- is returned.
- <TT>readfile</TT>
- can be used to read the contents of device files whose lines are not
- terminated with newline characters.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: ""+readfile("/dev/label")
- helix
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>reason</TT>
- uses machine-dependent information to generate a string explaining
- why a process has stopped. The
- <I>integer</I>
- argument is the value of an architecture dependent status register,
- for example
- <TT>CAUSE</TT>
- on the MIPS.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: print(reason(*CAUSE))
- system call
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>regexp</TT>
- matches the
- <I>pattern</I>
- string supplied as its first argument with the
- <I>string</I>
- supplied as its second.
- If the pattern matches the result is the value 1, otherwise 0.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: print(regexp(".*bar", "foobar"))
- 1
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>setproc</TT>
- selects the default process used for memory and control operations. It effectively
- shifts the focus of control between processes. The
- <I>integer</I>
- argument specifies the pid of the process to look at.
- The variable
- <TT>pid</TT>
- 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
- <TT>proclist</TT>.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: setproc(68382)
- acid: procs()
- >68382: Stopped at main+0x4 setproc(68382)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>start</TT>
- writes a
- <TT>start</TT>
- message to the control file of the process specified by the pid
- supplied as its
- <I>integer</I>
- argument.
- <TT>start</TT>
- draws an error if the process is not in the
- <TT>Stopped</TT>
- state.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: start(68382)
- acid: procs()
- >68382: Running at main+0x4 setproc(68382)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>startstop</TT>
- performs the same actions as a call to
- <TT>start</TT>
- followed by a call to
- <TT>stop</TT>.
- The
- <I>integer</I>
- argument specifies the pid of the process to control. The process
- must be in the
- <TT>Stopped</TT>
- state.
- Execution is restarted, the debugger then waits for the process to
- return to the
- <TT>Stopped</TT>
- 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.
- <TT>startstop</TT>
- is used to implement single stepping.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: startstop(pid)
- 75374: breakpoint ls ADD <I>-0x16c8,R29
- </PRE></TT></DL>
- </I><br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>status</TT>
- uses the pid supplied by its
- <I>integer</I>
- argument to generate a string describing the state of the process.
- The string corresponds to the state returned by the
- sixth column of the
- <A href="/magic/man2html/1/ps"><I>ps</I>(1)
- </A>command.
- A process must be in the
- <TT>Stopped</TT>
- state to modify its memory or registers.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: ""+status(pid)
- Stopped
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>stop</TT>
- writes a
- <TT>stop</TT>
- message to the control file of the process specified by the
- pid supplied as its
- <I>integer</I>
- argument.
- The interpreter blocks until the debugged process enters the
- <TT>Stopped</TT>
- 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.
- <TT>stop</TT>
- 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
- <TT>Stopped</TT>
- state.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- defn bpset(addr) {
- if (status(pid)!="Stopped") then {
- print("Waiting...\n");
- stop(pid);
- }
- ...
- }
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>strace</TT>
- 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</I>
- of format
- <TT>X</TT>
- 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</I>
- value of format
- <TT>X</TT>
- containing the current value of the variable.
- The arguments to
- <TT>strace</TT>
- 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</I>
- is architecture dependent. On the MIPS linkreg is set to the address of saved
- <TT>R31</TT>,
- on the SPARC to the address of saved
- <TT>R15</TT>.
- For the other architectures
- <I>linkreg</I>
- is not used, but must point to valid memory.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: print(strace(*PC, *SP, linkreg))
- {{0x0000141c, 0xc0000f74,
- {{"s", 0x0000004d}, {"multi", 0x00000000}},
- {{"db", 0x00000000}, {"fd", 0x000010a4},
- {"n", 0x00000001}, {"i", 0x00009824}}}}
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>waitstop</TT>
- writes a waitstop message to the control file of the process specified by the
- pid supplied as its
- <I>integer</I>
- argument.
- The interpreter will remain blocked until the debugged process enters the
- <TT>Stopped</TT>
- 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
- <TT>stop</TT>,
- the
- <TT>waitstop</TT>
- function is passive; it does not itself cause the program to stop.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: waitstop(pid)
- 75374: breakpoint ls ADD -0x16c8,R29
- </PRE></TT></DL>
- <br>
- </dl>
- <H4>Library Functions
- </H4>
- <P>
- A standard debugging environment is provided by modules automatically
- loaded when
- Acid is started.
- These modules are located in the directory
- <TT>/sys/lib/acid</TT>.
- These functions may be overridden, personalized, or added to by code defined in
- <TT></TT><I>home/lib/acid</I><TT>.
- The implementation of these functions can be examined using the
- </TT><TT>whatis</TT><TT>
- operator and then modified during debugging sessions.
- </P>
- </TT><br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>Bsrc</TT>
- interprets the
- <I>integer</I>
- argument as a text address. The text address is used to produce a pathname
- and line number suitable for the
- <TT>B</TT>
- command
- to send to the text editor
- <A href="/magic/man2html/1/sam"><I>sam</I>(1)
- </A>or
- <A href="/magic/man2html/1/acme"><I>acme</I>(1).
- </A><TT>Bsrc</TT>
- builds an
- <A href="/magic/man2html/1/rc"><I>rc</I>(1)
- </A>command to invoke
- <TT>B</TT>,
- 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
- <TT>stopped</TT>
- is redefined so that the editor
- follows and displays the source line currently being executed.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- defn stopped(pid) {
- pstop(pid);
- Bsrc(*PC);
- }
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- For machines equipped with floating point,
- <TT>Fpr</TT>
- displays the contents of the floating point registers as double precision
- values.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: Fpr()
- F0 0. F2 0.
- F4 0. F6 0.
- F8 0. F10 0.
- ...
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>Ureg</TT>
- interprets the integer passed as its first argument as the address of a
- kernel
- <TT>Ureg</TT>
- structure. Each element of the structure is retrieved and printed.
- The size and contents of the
- <TT>Ureg</TT>
- structure are architecture dependent.
- This function can be used to decode the first argument passed to a
- <A href="/magic/man2html/2/notify"><I>notify</I>(2)
- </A>function after a process has received a note.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: Ureg(*notehandler:ur)
- status 0x3000f000
- pc 0x1020
- sp 0x7ffffe00
- cause 0x00004002
- ...
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>acidinit</TT>
- 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.
- <TT>acidinit</TT>
- should not be called by user code.
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>addsrcdir</TT>
- interprets its string argument as a new directory
- <TT>findsrc</TT>
- should search when looking for source code files.
- <TT>addsrcdir</TT>
- draws an error if the directory is already in the source search path. The search
- path may be examined by looking at the variable
- <TT>srcpath</TT>.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: rc("9fs fornax")
- acid: addsrcpath("/n/fornax/sys/src/cmd")
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>asm</TT>
- interprets its integer argument as a text address from which to disassemble
- machine instructions.
- <TT>asm</TT>
- prints the instruction address in symbolic and hexadecimal form, then prints
- the instructions with addressing modes. Up to twenty instructions will
- be disassembled.
- <TT>asm</TT>
- stops disassembling when it reaches the end of the current function.
- Instructions are read from the file image using the
- <TT>@</TT>
- operator.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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 <I>bin(SB),R1
- </PRE></TT></DL>
- </I><br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>bpdel</TT>
- removes a previously set breakpoint from memory.
- The
- <I>integer</I>
- supplied as its argument must be the address of a previously set breakpoint.
- The breakpoint address is deleted from the active breakpoint list
- <TT>bplist</TT>,
- then the original instruction is copied from the file image to the memory
- image so that the breakpoint is removed.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: bpdel(main+4)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>bpset</TT>
- places a breakpoint instruction at the address specified
- by its
- <I>integer</I>
- argument, which must be in the text segment.
- <TT>bpset</TT>
- draws an error if a breakpoint has already been set at the specified address.
- A list of current breakpoints is maintained in the variable
- <TT>bplist</TT>.
- Unlike in
- <A href="/magic/man2html/1/db"><I>db</I>(1),
- </A>breakpoints are left in memory even when a process is stopped, and
- the process must exist, perhaps by being
- created by either
- <TT>new</TT>
- or
- <TT>win</TT>,
- in order to place a breakpoint.
- (<TT>Db</TT>
- 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
- <TT>JAL</TT>
- branch delay slots with the first instruction of the function.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: bpset(main+4)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>bptab</TT>
- 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
- <TT>new</TT>
- and
- <TT>win</TT>.
- They are maintained across a fork, but care must be taken to keep control of
- the child process.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: bpset(ls+4)
- acid: bptab()
- 0x00001420 ls+0x4 MOVW R31,0x0(R29)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>casm</TT>
- continues to disassemble instructions from where the last
- <TT>asm</TT>
- or
- <TT>casm</TT>
- command stopped. Like
- <TT>asm</TT>,
- this command stops disassembling at function boundaries.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: casm()
- main+0x10 0x00001030 MOVW 0x1,R3
- main+0x14 0x00001034 MOVW R3,0x8(R29)
- main+0x18 0x00001038 MOVW <I>0x1,R5
- main+0x1c 0x0000103c JAL Binit(SB)
- </PRE></TT></DL>
- </I><br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>cont</TT>
- 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
- <TT>stopped()</TT>
- to be called twice.
- <TT>cont</TT>
- causes the interpreter to block until the process enters the
- <TT>Stopped</TT>
- state.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: cont()
- 95197: breakpoint ls+0x4 MOVW R31,0x0(R29)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>dump</TT>
- interprets its first argument as an address, its second argument as a
- count and its third as a format string.
- <TT>dump</TT>
- 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,
- <TT>dump</TT>
- prints the address in hexadecimal, a colon, the object and then a newline.
- <TT>dump</TT>
- uses
- <TT>mem</TT>
- to fetch each object.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>findsrc</TT>
- interprets its
- <I>string</I>
- 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
- <TT>file</TT>
- and stored in the list of active source files called
- <TT>srctext</TT>.
- The name of the file is added to the source file name list
- <TT>srcfiles</TT>.
- Users are unlikely to call
- <TT>findsrc</TT>
- from the command line, but may use it from scripts to preload source files
- for a debugging session. This function is used by
- <TT>src</TT>
- and
- <TT>line</TT>
- to locate and load source code. The default search path for the MIPS
- is
- <TT>./</TT>,
- <TT>/sys/src/libc/port</TT>,
- <TT>/sys/src/libc/9sys</TT>,
- <TT>/sys/src/libc/mips</TT>.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: findsrc(pcfile(main));
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- For machines equipped with floating point,
- <TT>fpr</TT>
- 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.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: fpr()
- F0 0. F1 0.
- F2 0. F3 0.
- F4 0. F5 0.
- ...
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>func</TT>
- single steps the active process until it leaves the current function
- by either calling another function or returning to its caller.
- <TT>func</TT>
- will execute a single instruction after leaving the current function.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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 <I>0x2f,R5
- 95197: breakpoint ls+0x18 JAL utfrrune(SB)
- 95197: breakpoint utfrrune ADD </I>-0x18,R29
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>gpr</TT>
- prints the values of the general purpose processor registers.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: gpr()
- R1 0x00009562 R2 0x000010a4 R3 0x00005d08
- R4 0x0000000a R5 0x0000002f R6 0x00000008
- ...
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>labstk</TT>
- performs a stack trace from a Plan 9
- <I>label.</I>
- 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
- <TT>PC</TT>
- and
- <TT>SP</TT>
- pair. This data structure is called a label and is used by the
- the C function
- <TT>longjmp</TT>
- and the kernel to schedule threads and processes.
- <TT>labstk</TT>
- interprets its
- <I>integer</I>
- argument as the address of a label and produces a stack trace for
- the thread of execution. The value of the function
- <TT>ALEF_tid</TT>
- is a suitable argument for
- <TT>labstk</TT>.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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
- ...
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>lstk</TT>
- 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.
- <TT>lstk</TT>
- displays the value rather than the address of each variable and all
- variables are assumed to be an integer in format
- <TT>X</TT>.
- To print a variable in its correct format use the
- <TT>:</TT>
- operator to find the address and apply the appropriate format before indirection
- with the
- <TT>*</TT>
- 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.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>mem</TT>
- interprets its first
- <I>integer</I>
- argument as the address of an object to be printed according to the
- format supplied in its second
- <I>string</I>
- argument.
- The format string can be any combination of format characters, each preceded
- by an optional count.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: mem(bdata+0x326, "2c2Xb")
- P = 0xa94bc464 0x3e5ae44d 19
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>new</TT>
- starts a new copy of the debugged program. The new program is started
- with the program arguments set by the variable
- <TT>progargs</TT>.
- The new program is stopped in the second instruction of
- <TT>main</TT>.
- The breakpoint list is reinitialized.
- <TT>new</TT>
- may be used several times to instantiate several copies of a program
- simultaneously. The user can rotate between the copies using
- <TT>setproc</TT>.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: progargs="-l"
- acid: new()
- 60: external interrupt _main ADD <I>-0x14,R29
- 60: breakpoint main+0x4 MOVW R31,0x0(R29)
- </PRE></TT></DL>
- </I><br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>next</TT>
- steps through a single language level statement without tracing down
- through each statement in a called function. For each statement,
- <TT>next</TT>
- prints the machine instructions executed as part of the statement. After
- the statement has executed, source lines around the current program
- counter are displayed.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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 }
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>notestk</TT>
- interprets its
- <I>integer</I>
- argument as the address of a
- <TT>Ureg</TT>
- structure passed by the kernel to a
- <A href="/magic/man2html/2/notify"><I>notify</I>(2)
- </A>function during note processing.
- <TT>notestk</TT>
- uses the
- <TT>PC</TT>,
- <TT>SP</TT>,
- and link register from the
- <TT>Ureg</TT>
- 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.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>pfl</TT>
- 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
- <A href="/magic/man2html/1/acme"><I>acme</I>(1).
- </A><DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: pfl(main)
- ls.c:48
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>procs</TT>
- 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
- <TT>setproc</TT>
- command required to make that process current.
- The current process is marked in the first column with a
- <TT>></TT>
- character. The debugger maintains a list of processes in the variable
- <TT>proclist</TT>.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: procs()
- >62: Stopped at main+0x4 setproc(62)
- 60: Stopped at Binit+0x8 setproc(60)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>pstop</TT>
- prints the status of the process specified by the
- <I>integer</I>
- pid supplied as its argument.
- <TT>pstop</TT>
- is usually called from
- <TT>stopped</TT>
- every time a process enters the
- <TT>Stopped</TT>
- state.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: pstop(62)
- 0x0000003e: breakpoint main+0x4 MOVW R31,0x0(R29)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>regs</TT>
- prints the contents of both the general and special purpose registers.
- <TT>regs</TT>
- calls
- <TT>spr</TT>
- then
- <TT>gpr</TT>
- to display the contents of the registers.
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>source</TT>
- prints the directory search path followed by a list of currently loaded
- source files. The source management functions
- <TT>src</TT>
- and
- <TT>findsrc</TT>
- 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
- <TT>srcfiles</TT>
- and the contents of each source file in the variable
- <TT>srctext</TT>.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: source()
- /n/bootes/sys/src/libbio/
- /sys/src/libc/port/
- /sys/src/libc/9sys/
- /sys/src/libc/mips/
- binit.c
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>spr</TT>
- 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
- <TT>CAUSE</TT>
- register on the MIPS is
- printed both in hexadecimal and using the
- <TT>reason</TT>
- function.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>src</TT>
- interprets its
- <I>integer</I>
- 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
- <TT>></TT>
- character.
- <TT>src</TT>
- uses the source search path maintained by
- <TT>source</TT>
- and
- <TT>addsrcdir</TT>
- to locate the required source files.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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);
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>step</TT>
- causes the debugged process to execute a single machine level instruction.
- If the program is stopped on a breakpoint set by
- <TT>bpset</TT>
- it is first removed, the single step executed, and the breakpoint replaced.
- <TT>step</TT>
- uses
- <TT>follow</TT>
- 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.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: step()
- 62: breakpoint main+0x8 MOVW R1,argc+4(FP)
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>stk</TT>
- 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
- <TT>X</TT>;
- to print a parameter in the correct format use the
- <TT>:</TT>
- to obtain its address, apply the correct format, and use the
- <TT>*</TT>
- 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.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>stmnt</TT>
- executes a single language level statement.
- <TT>stmnt</TT>
- displays each machine level instruction as it is executed. When the executed
- statement is completed the source for the next statement is displayed.
- Unlike
- <TT>next</TT>,
- the
- <TT>stmnt</TT>
- function will trace down through function calls.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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 {
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>stopped</TT>
- is called automatically by the interpreter
- every time a process enters the
- <TT>Stopped</TT>
- state, such as when it hits a breakpoint.
- The pid is passed as the
- <I>integer</I>
- argument. The default implementation just calls
- <TT>pstop</TT>,
- but the function may be changed to provide more information or perform fine control
- of execution. Note that
- <TT>stopped</TT>
- should return; for example, calling
- <TT>step</TT>
- in
- <TT>stopped</TT>
- will recur until the interpreter runs out of stack space.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- 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
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>symbols</TT>
- uses the regular expression supplied by
- <I>string</I>
- to search the symbol table for symbols whose name matches the
- regular expression.
- <DT><DT> <DD>
- <DL><DT><DD><TT><PRE>
- <br>
- acid: symbols("main")
- main T 0x00001020
- _main T 0x0000623c
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <DL>
- <DT><DT> <DD>
- <TT>win</TT>
- performs exactly the same function as
- <TT>new</TT>
- but uses the window system to create a new window for the debugged process.
- The variable
- <TT>progargs</TT>
- supplies arguments to the new process.
- The environment variable
- <TT></TT><I>8½srv</I><TT>
- 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
- </TT><TT>win</TT><TT>
- 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.
- <DT><DT> <DD>
- </TT><DL><DT><DD><TT><PRE>
- <br>
- acid: win()
- </PRE></TT></DL>
- <br>
- </dl>
- <br> <br>
- <A href=http://www.lucent.com/copyright.html>
- Copyright</A> © 2004 Lucent Technologies Inc. All rights reserved.
- </body></html>
|