Charles.Forsyth20060303-partialeea662d19 years agoHistory
1327 lines · 43.8 KB · Text
RawDownload
.TLAcid: A Debugger Built From A Language.AU.I "Phil Winterbottom".AI.I "Lucent Technologies Inc".AB.FS\l'1i'.brOriginally appeared in.IProc. of the Winter 1994 USENIX Conf.,.Rpp. 211-222,San Francisco, CA;and subsequently in the.I "Plan 9 Programmer's Manual, Volume 2 (Second Edition)" ..FEAcid is an unusual source-level symbolic debugger for Plan 9. It is implementedas a language interpreter with specialized primitives that providedebugger support.  Programs written in the language manipulateone or more target processes; variables in the language represent thesymbols, state, and resources of those processes. This structure allows complexinteraction between the debugger and the target program andprovides a convenient method of parameterizing differences betweenmachine architectures.Although some effort is required to learnthe debugging language, the richness and flexibility of thedebugging environment encourages new ways of reasoning about the wayprograms run and the conditions under which they fail..AE.NHIntroduction.PPThe size and complexityof programs have increased in proportion to processor speed and memory butthe interface between debugger and programmer has changed little.Graphical user interfaces have eased some of the tediousaspects of the interaction. A graphical interface is a convenientmeans for navigating through source and data structures but provideslittle benefit for process control.The introduction of a new concurrent language, Alef [Win93], emphasized theinadequacies of the existing Plan 9 [Pike90] debugger.I db ,a distant relative of.I adb ,and made it clear that a new debugger was required..PPCurrent debuggers like.I dbx ,.I sdb ,and.I gdbare limited to answering only the questions their authorsenvisage.  As a result, they supply a plethoraof specialized commands, each attempting to anticipatea specific question a user may ask.When a debugging situation arises that is beyond the scopeof the command set, the tool is useless.Further,it is often tedious or impossible to reproduce an anomalous stateof the program, especially whenthe state is embedded in the program's data structures..PPAcid applies some ideas found in CAD software used forhardware test and simulation.It is based on the notion that the state and resources of a programare best represented and manipulated by a language. The state and resources,such as memory, registers, variables, type information and source codeare represented by variables in the language.Expressions provide a computation mechanism and controlstatements allow repetitive or selective interpretation basedon the result of expression evaluation.The heart of the Acid debugger is an interpreter for a small typelesslanguage whose operators mirror the operationsof C and Alef, which in turn correspond well to the basic operations ofthe machine. The interpreter itself knows nothing of the underlyinghardware; it deals with the program state and resourcesin the abstract.Fundamental routines to controlprocesses, read files, and interface to the system are implementedas builtin functions available to the interpreter.The actual debugger functionality is codedin Acid; commands are implemented as Acid functions..PPThis language-based approach has several advantages.Most importantly, programs written in Acid, including most of thedebugger itself, are inherently portable.Furthermore, Acid avoids the limitations other debuggers impose whendebugging parallel programs.  Instead of embedding a fixedprocess model in the debugger, Acid allows theprogrammer to adapt the debugger to handle anarbitrary process partitioning or program structure. The ability tointeract dynamically with an executing process provides clear advantagesover debuggers constrained to probe a static image.Finally, the Acid language is a powerful vehicle for expressingassertions about logic, process state, and the contents of data structures.When combined with dynamic interaction it allows alimited form of automated program verification without requiringmodification or recompilation of the source code.The language is also anexcellent vehicle for preserving a test suite for later regression testing..PPThe debugger may be customized by its users; standardfunctions may be modified or extended to suit a particular applicationor preference.For example, the kernel developers in our group require acommand set supporting assembler-level debugging while the applicationprogrammers prefer source-level functionality.Although the default library is biased toward assembler-level debugging,it is easily modified to provide a convenient source-level interface.The debugger itself does not change; the user combines primitivesand existing Acid functions in different ways toimplement the desired interface..NHRelated Work.PPDUEL [Gol93], an extension to.I gdb[Stal91], proposes using a high level expression evaluator to solvesome of these problems. The evaluator provides iterators to loop over datastructures and conditionals to control evaluation of expressions.The author shows that complex state queries can be formulatedby combining concise expressions but this only addresses part of the problem.A program is a dynamic entity; questions asked when the program is ina static state are meaningful only after the program has been `caught' inthat state. The framework for manipulating the program is still asprimitive as the underlying debugger. While DUEL provides a means toprobe data structures it entirely neglects the most beneficial aspectof debugging languages: the ability to control processes. Acid is structuredaround a thread of control that passes between the interpreter and thetarget program..PPThe NeD debugger [May92] is a set of extensions to TCL [Ous90] that providedebugging primitives. The resulting language, NeDtcl, is used to implementa portable interface between a conventional debugger, pdb [May90], anda server that executes NeDtcl programs operating on the target program.Execution of the NeDtcl programs implements the debugging primitivesthat pdb expects.NeD is targeted at multi-process debugging across a network,and proves the flexibility of a language as a means ofcommunication between debugging tools. Whereas NeD provides an interfacebetween a conventional debugger and the process it debugs, Acid is thedebugger itself. While NeD has some of the ideasfound in Acid it is targeted toward a different purpose. Acid seeks tointegrate the manipulation of a program's resources into the debuggerwhile NeD provides a flexible interconnect between components ofthe debugging environment. The choice of TCL is appropriate for its usein NeD but is not suitable for Acid. Acid relies on the coupling of the typesystem with expression evaluation, which are the root of its design,to provide the debugging primitives..PPDalek [Ols90] is an event based language extension to gdb. State transitionsin the target program cause events to be queued for processing by thedebugging language..PPAcid has many of the advantages of same process or.I local.I agentdebuggers, like Parasight [Aral], without the need for dynamic linking orshared memory.Acid improves on the ideas of these other systems by completely integratingall aspects of the debugging process into the language environment. Ofparticular importance is the relationship between Acid variables,program symbols, source code, registers and type information. Thisintegration is made possible by the design of the Acid language..PPInterpreted languages such as Lisp and Smalltalk are able to providericher debugging environments through more complete information thantheir compiled counterparts. Acid is a means to gather and representsimilar information about compiled programs through cooperationwith the compilation tools and library implementers..NHAcid the Language.PPAcid is a small interpreted language targeted to its debugging task.It focuses on representing program state and addressing data rather thanexpressing complex computations. Program state is.I addressablefrom an Acid program.In addition to parsing and executing expressions and providingan architecture-independent interface to the target process,the interpreter supplies a mark-and-scan garbage collectorto manage storage..PPEvery Acid session begins with the loading of the Acid libraries.These libraries contain functions, written in Acid, that providea standard debugging environment including breakpoint management,stepping by instruction or statement, stack tracing, andaccess to variables, memory, and registers.The library contains 600 lines of Acid code and providesfunctionality similar to.I dbx .Following the loading of the system library, Acid loadsuser-specified libraries; this load sequence allows theuser to augment or override the standard commandsto customize the debugging environment.  When all librariesare loaded, Acid issues an interactive prompt and beginsevaluating expressions entered by the user.  The Acid `commands'are actually invocations of builtin primitives or previously definedAcid functions. Acid evaluates each expression as it is entered andprints the result..NHTypes and Variables.PPAcid variables are of four basic types:.I integer ,.I string ,.I float ,and.I list .The type of a variable is inferred by the type of the right-hand side ofan assignment expression.Many of the operators can be applied to more thanone type; for these operators the action of the operator is determinedby the type of its operands.For example,the.CW +operator adds.I integerand.I floatoperands, and concatenates.I stringand.I listoperands.Lists are the only complex type in Acid; there are no arrays, structuresor pointers. Operators provide.CW head ,.CW tail ,.CW appendand.CW deleteoperations.Lists can also be indexed like arrays..PPAcid has two levels of scope: global and local.Function parameters and variables declared in a function bodyusing the.CW localkeyword are created at entry to the function andexist for the lifetime of a function.Global variables are created by assignment and need not be declared.All variables and functions in the programbeing debugged are entered in the Acid symbol table as globalvariables during Acid initialization.Conflicting variable names are resolved by prefixing enough `$' charactersto make them unique.Syntactically, Acid variables and target programsymbols are referenced identically.However, the variables are managed differently in the Acidsymbol table and the user must be aware of this distinction.The value of an Acid variable is stored in the symboltable; a reference returns the value.The symbol table entry for a variable or function in the targetprogram contains the address of that symbol in the imageof the program.  Thus, the value of a program variable isaccessed by indirect reference through the Acidvariable that has the same name; the value of an Acid variable is theaddress of the corresponding program variable..NHControl Flow.PPThe.CW whileand.CW loopstatements implement looping.The formeris similar to the same statement in C.The latter evaluates starting and ending expressions yieldingintegers and iterates while an incrementing loop indexis within the bounds of those expressions..P1acid: i = 0; loop 1,5 do print(i=i+1)0x000000010x000000020x000000030x000000040x00000005acid:.P2The traditional.CW if-then-else statement implements conditional execution..NHAddressing.PPTwo indirection operators allow Acid to access values inthe program being debugged.The.CW *operator fetches a value from the memory image of anexecuting process;the.CW @operator fetches a value from the text file of the process.When either operator appears on the left side of an assignment, the valueis written rather than read..PPThe indirection operator must know the size of the objectreferenced by a variable.The Plan 9 compilers neglect to include thisinformation in the program symbol table, so Acid cannotderive this information implicitly.Instead Acid variables have formats.The format is a codeletter specifying the printing style and the effect of some of theoperators on that variable.The indirection operators look at the format code to determine thenumber of bytes to read or write.The format codes are derived from the format letters used by.I db .By default, symbol table variables and numeric constantsare assigned the format code.CW 'X'which specifies 32-bit hexadecimal.Printing such a variable yields output of the form.CW 0x00123456 .An indirect reference through the variable fetches 32 bitsof data at the address indicated by the variable.Other formats specify various data types, for example.CW ian instruction,.CW Da signed 32 bit decimal,.CW sa null-terminated string.The.CW fmtfunctionallows the user to change the format code of a variableto control the printing format andoperator side effects.This function evaluates the expression supplied as the firstargument, attaches the format code supplied as the secondargument to the result and returns that value.If the result is assigned to a variable,the new format code applies tothat variable.  For convenience, Acid provides the.CW \eoperator as a shorthand infix form of.CW fmt .For example:.P1acid: x=10acid: x				 // print x in hex0x0000000a acid: x = fmt(x, 'D')		 // make x type decimalacid: print(x, fmt(x, 'X'), x\eX) // print x in decimal & hex10 0x0000000a 0x0000000aacid: x				 // print x in decimal10acid: x\eo			 // print x in octal000000000012.P2The .CW ++and.CW --operators increment or decrement a variable by an amountdetermined by its format code.  Some formats imply a non-fixed size.For example, the.CW iformat code disassembles an instruction into a string.On a 68020, which has variable length instructions:.P1acid: p=main\ei                     // p=addr(main), type INSTacid: loop 1,5 do print(p\eX, @p++) // disassemble 5 instr's0x0000222e LEA	0xffffe948(A7),A70x00002232 MOVL	s+0x4(A7),A20x00002236 PEA	0x2f($0)0x0000223a MOVL	A2,-(A7)0x0000223c BSR	utfrruneacid:.P2Here,.CW mainis the address of the function of the same name in the program under test.The loop retrieves the five instructions beginning at that address andthen prints the address and the assembly language representation of each.Notice that the stride of the increment operator varies with the size ofthe instruction: the.CW MOVLat .CW 0x0000223ais a two byte instruction while all others are four bytes long..PPRegisters are treated as normal program variables referencedby their symbolic assembler language names.When aprocess stops, the register set is saved by the kernelat a known virtual address in the process memory map.The Acid variables associated with the registers pointto the saved values and the.CW *indirection operator can then be used to read and write the register set.Since the registers are accessed via Acid variables they maybe used in arbitrary expressions..P1acid: PC                            // addr of saved PC0xc0000f60 acid: *PC0x0000623c                          // contents of PCacid: *PC\eamainacid: *R1=10                        // modify R1acid: asm(*PC+4)                    // disassemble @ PC+4main+0x4 0x00006240 	MOVW	R31,0x0(R29)main+0x8 0x00006244 	MOVW	$setR30(SB),R30main+0x10 0x0000624c 	MOVW	R1,_clock(SB).P2Here, the saved.CW PCis stored at address.CW 0xc0000f60 ;its current content is.CW 0x0000623c .The.CW a ' `format code converts this value to a string specifyingthe address as an offset beyond the nearest symbol.After setting the value of register.CW 1 ,the example uses the.CW asmcommand to disassemble a short section of code beginningat four bytes beyond the current value of the.CW PC ..NHProcess Interface.PPA program executing under Acid is monitored through the.I procfile system interface provided by Plan 9.Textual messages written to the.CW ctlfile control the execution of the process.For example writing.CW waitstopto the control file causes the write to block until the targetprocess enters the kernel and is stopped. When the process is stoppedthe write completes. The.CW startstopmessage starts the target process and then does a.CW waitstopaction.Synchronization between the debugger and the target process is determinedby the actions of the various messages. Some operate asynchronously to thetarget process and always complete immediately, others block until theaction completes. The asynchronous messages allow Acid to controlseveral processes simultaneously..PPThe interpreter has builtin functions named after each of the controlmessages. The functions take a process id as argument.Any time a control message causes the program to execute instructions the interpreter performs two actions when the control operation has completed.The Acid variables pointing at the register set are fixed up to pointat the saved registers, and thenthe user defined function.CW stoppedis executed.The .CW stoppedfunction may print the current address,line of source or instruction and return to interactive mode. Alternativelyit may traverse a complex data structure, gather statistics and then setthe program running again..PPSeveral Acid variables are maintained by the debugger rather than theprogrammer.These variables allow generic Acid code to deal with the current process,architecture specifics or the symbol table.The variable.CW pidis the process id of the current process Acid is debugging.The variable.CW symbolscontains a list of lists where each sublist contains the symbolname, its type and the value of the symbol.The variable.CW registerscontains a list of the machine-specific register names. Global symbols in the target programcan be referenced directly by name from Acid. Local variablesare referenced using the colon operator as \f(CWfunction:variable\fP..NHSource Level Debugging.PPAcid provides several builtin functions to manipulate source code.The.CW filefunction reads a text file, inserting each line into a list.The.CW pcfileand

Lines 1–500 of 1327.