⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agentexpr.texi

📁 这个是LINUX下的GDB调度工具的源码
💻 TEXI
📖 第 1 页 / 共 3 页
字号:
@c \input texinfo@c %**start of header@c @setfilename agentexpr.info@c @settitle GDB Agent Expressions@c @setchapternewpage off@c %**end of header@c Revision: $Id: agentexpr.texi,v 1.2 1998/12/09 21:23:46 jimb Exp $@node Agent Expressions@appendix The GDB Agent Expression MechanismIn some applications, it is not feasable for the debugger to interruptthe program's execution long enough for the developer to learn anythinghelpful about its behavior.  If the program's correctness depends on itsreal-time behavior, delays introduced by a debugger might cause theprogram to fail, even when the code itself is correct.  It is useful tobe able to observe the program's behavior without interrupting it.Using GDB's @code{trace} and @code{collect} commands, the user canspecify locations in the program, and arbitrary expressions to evaluatewhen those locations are reached.  Later, using the @code{tfind}command, she can examine the values those expressions had when theprogram hit the trace points.  The expressions may also denote objectsin memory --- structures or arrays, for example --- whose values GDBshould record; while visiting a particular tracepoint, the user mayinspect those objects as if they were in memory at that moment.However, because GDB records these values without interacting with theuser, it can do so quickly and unobtrusively, hopefully not disturbingthe program's behavior.When GDB is debugging a remote target, the GDB @dfn{agent} code runningon the target computes the values of the expressions itself.  To avoidhaving a full symbolic expression evaluator on the agent, GDB translatesexpressions in the source language into a simpler bytecode language, andthen sends the bytecode to the agent; the agent then executes thebytecode, and records the values for GDB to retrieve later.The bytecode language is simple; there are forty-odd opcodes, the bulkof which are the usual vocabulary of C operands (addition, subtraction,shifts, and so on) and various sizes of literals and memory referenceoperations.  The bytecode interpreter operates strictly on machine-levelvalues --- various sizes of integers and floating point numbers --- andrequires no information about types or symbols; thus, the interpreter'sinternal data structures are simple, and each bytecode requires only afew native machine instructions to implement it.  The interpreter issmall, and strict limits on the memory and time required to evaluate anexpression are easy to determine, making it suitable for use by thedebugging agent in real-time applications.@menu* General Bytecode Design::     Overview of the interpreter.* Bytecode Descriptions::       What each one does.* Using Agent Expressions::     How agent expressions fit into the big picture.* Varying Target Capabilities:: How to discover what the target can do.* Tracing on Symmetrix::        Special info for implementation on EMC's                                boxes.* Rationale::                   Why we did it this way.@end menu@c @node Rationale@c @section Rationale@node General Bytecode Design@section General Bytecode DesignThe agent represents bytecode expressions as an array of bytes.  Eachinstruction is one byte long (thus the term @dfn{bytecode}).  Someinstructions are followed by operand bytes; for example, the @code{goto}instruction is followed by a destination for the jump.The bytecode interpreter is a stack-based machine; most instructions poptheir operands off the stack, perform some operation, and push theresult back on the stack for the next instruction to consume.  Eachelement of the stack may contain either a integer or a floating pointvalue; these values are as many bits wide as the largest integer thatcan be directly manipulated in the source language.  Stack elementscarry no record of their type; bytecode could push a value as aninteger, then pop it as a floating point value.  However, GDB will notgenerate code which does this.  In C, one might define the type of astack element as follows:@exampleunion agent_val @{  LONGEST l;  DOUBLEST d;@};@end example@noindentwhere @code{LONGEST} and @code{DOUBLEST} are @code{typedef} names forthe largest integer and floating point types on the machine.By the time the bytecode interpreter reaches the end of the expression,the value of the expression should be the only value left on the stack.For tracing applications, @code{trace} bytecodes in the expression willhave recorded the necessary data, and the value on the stack may bediscarded.  For other applications, like conditional breakpoints, thevalue may be useful.Separate from the stack, the interpreter has two registers:@table @code@item pcThe address of the next bytecode to execute.@item startThe address of the start of the bytecode expression, necessary forinterpreting the @code{goto} and @code{if_goto} instructions.@end table@noindentNeither of these registers is directly visible to the bytecode languageitself, but they are useful for defining the meanings of the bytecodeoperations.There are no instructions to perform side effects on the runningprogram, or call the program's functions; we assume that theseexpressions are only used for unobtrusive debugging, not for patchingthe running code.  Most bytecode instructions do not distinguish between the various sizesof values, and operate on full-width values; the upper bits of thevalues are simply ignored, since they do not usually make a differenceto the value computed.  The exceptions to this rule are:@table @asis@item memory reference instructions (@code{ref}@var{n})There are distinct instructions to fetch different word sizes frommemory.  Once on the stack, however, the values are treated as full-sizeintegers.  They may need to be sign-extended; the @code{ext} instructionexists for this purpose.@item the sign-extension instruction (@code{ext} @var{n})These clearly need to know which portion of their operand is to beextended to occupy the full length of the word.@end tableIf the interpreter is unable to evaluate an expression completely forsome reason (a memory location is inaccessible, or a divisor is zero,for example), we say that interpretation ``terminates with an error''.This means that the problem is reported back to the interpreter's callerin some helpful way.  In general, code using agent expressions shouldassume that they may attempt to divide by zero, fetch arbitrary memorylocations, and misbehave in other ways.Even complicated C expressions compile to a few bytecode instructions;for example, the expression @code{x + y * z} would typically producecode like the following, assuming that @code{x} and @code{y} live inregisters, and @code{z} is a global variable holding a 32-bit@code{int}:@examplereg 1reg 2const32 @i{address of z}ref32ext 32muladdend@end exampleIn detail, these mean:@table @code@item reg 1Push the value of register 1 (presumably holding @code{x}) onto thestack.@item reg 2Push the value of register 2 (holding @code{y}).@item const32 @i{address of z}Push the address of @code{z} onto the stack.@item ref32Fetch a 32-bit word from the address at the top of the stack; replacethe address on the stack with the value.  Thus, we replace the addressof @code{z} with @code{z}'s value.@item ext 32Sign-extend the value on the top of the stack from 32 bits to fulllength.  This is necessary because @code{z} is a signed integer.@item mulPop the top two numbers on the stack, multiply them, and push theirproduct.  Now the top of the stack contains the value of the expression@code{y * z}.@item addPop the top two numbers, add them, and push the sum.  Now the top of thestack contains the value of @code{x + y * z}.@item endStop executing; the value left on the stack top is the value to berecorded.@end table@node Bytecode Descriptions@section Bytecode DescriptionsEach bytecode description has the following form:@table @asis@item @code{add} (0x02): @var{a} @var{b} @result{} @var{a+b}Pop the top two stack items, @var{a} and @var{b}, as integers; pushtheir sum, as an integer.@end tableIn this example, @code{add} is the name of the bytecode, and@code{(0x02)} is the one-byte value used to encode the bytecode, inhexidecimal.  The phrase ``@var{a} @var{b} @result{} @var{a+b}'' showsthe stack before and after the bytecode executes.  Beforehand, the stackmust contain at least two values, @var{a} and @var{b}; since the top ofthe stack is to the right, @var{b} is on the top of the stack, and@var{a} is underneath it.  After execution, the bytecode will havepopped @var{a} and @var{b} from the stack, and replaced them with asingle value, @var{a+b}.  There may be other values on the stack belowthose shown, but the bytecode affects only those shown.Here is another example:@table @asis@item @code{const8} (0x22) @var{n}: @result{} @var{n}Push the 8-bit integer constant @var{n} on the stack, without signextension.@end tableIn this example, the bytecode @code{const8} takes an operand @var{n}directly from the bytecode stream; the operand follows the @code{const8}bytecode itself.  We write any such operands immediately after the nameof the bytecode, before the colon, and describe the exact encoding ofthe operand in the bytecode stream in the body of the bytecodedescription.For the @code{const8} bytecode, there are no stack items given beforethe @result{}; this simply means that the bytecode consumes no valuesfrom the stack.  If a bytecode consumes no values, or produces novalues, the list on either side of the @result{} may be empty.If a value is written as @var{a}, @var{b}, or @var{n}, then the bytecodetreats it as an integer.  If a value is written is @var{addr}, then thebytecode treats it as an address.We do not fully describe the floating point operations here; althoughthis design can be extended in a clean way to handle floating pointvalues, they are not of immediate interest to the customer, so we avoiddescribing them, to save time.@table @asis@item @code{float} (0x01): @result{}Prefix for floating-point bytecodes.  Not implemented yet.@item @code{add} (0x02): @var{a} @var{b} @result{} @var{a+b}Pop two integers from the stack, and push their sum, as an integer.@item @code{sub} (0x03): @var{a} @var{b} @result{} @var{a-b}Pop two integers from the stack, subtract the top value from thenext-to-top value, and push the difference.@item @code{mul} (0x04): @var{a} @var{b} @result{} @var{a*b}Pop two integers from the stack, multiply them, and push the product onthe stack.  Note that, when one multiplies two @var{n}-bit numbersyielding another @var{n}-bit number, it is irrelevant whether thenumbers are signed or not; the results are the same.@item @code{div_signed} (0x05): @var{a} @var{b} @result{} @var{a/b}Pop two signed integers from the stack; divide the next-to-top value bythe top value, and push the quotient.  If the divisor is zero, terminatewith an error.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -