354
Appendix E. The GDB Agent Expression Mechanism
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,
trace
bytecodes in the expres-
sion will have recorded the necessary data, and the value on the stack may be discarded. For other
applications, like conditional breakpoints, the value may be useful.
Separate from the stack, the interpreter has two registers:
pc
The address of the next bytecode to execute.
start
The address of the start of the bytecode expression, necessary for interpreting the
goto
and
if_goto
instructions.
Neither of these registers is directly visible to the bytecode language itself, but they are useful for
defining the meanings of the bytecode operations.
There are no instructions to perform side effects on the running program, or call the program’s func-
tions; we assume that these expressions are only used for unobtrusive debugging, not for patching the
running code.
Most bytecode instructions do not distinguish between the various sizes of values, and operate on
full-width values; the upper bits of the values are simply ignored, since they do not usually make a
difference to the value computed. The exceptions to this rule are:
memory reference instructions (
refn
)
There are distinct instructions to fetch different word sizes from memory. Once on the stack,
however, the values are treated as full-size integers. They may need to be sign-extended; the
ext
instruction exists for this purpose.
the sign-extension instruction (
ext n
)
These clearly need to know which portion of their operand is to be extended to occupy the full
length of the word.
If the interpreter is unable to evaluate an expression completely for some 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 caller in some helpful way. In general,
code using agent expressions should assume that they may attempt to divide by zero, fetch arbitrary
memory locations, and misbehave in other ways.
Even complicated C expressions compile to a few bytecode instructions; for example, the expression
x + y * z
would typically produce code like the following, assuming that
x
and
y
live in registers,
and
z
is a global variable holding a 32-bit
int
:
reg 1
reg 2
const32
address of z
ref32
ext 32
mul
add
end
In detail, these mean:
Summary of Contents for ENTERPRISE LINUX 4 - DEVELOPER TOOLS GUIDE
Page 1: ...Red Hat Enterprise Linux 4 Debugging with gdb ...
Page 12: ...2 Chapter 1 Debugging with gdb ...
Page 28: ...18 Chapter 4 Getting In and Out of gdb ...
Page 34: ...24 Chapter 5 gdb Commands ...
Page 44: ...34 Chapter 6 Running Programs Under gdb ...
Page 68: ...58 Chapter 8 Examining the Stack ...
Page 98: ...88 Chapter 10 Examining Data ...
Page 112: ...102 Chapter 12 Tracepoints ...
Page 118: ...108 Chapter 13 Debugging Programs That Use Overlays ...
Page 138: ...128 Chapter 14 Using gdb with Different Languages ...
Page 144: ...134 Chapter 15 Examining the Symbol Table ...
Page 170: ...160 Chapter 19 Debugging remote programs ...
Page 198: ...188 Chapter 21 Controlling gdb ...
Page 204: ...194 Chapter 22 Canned Sequences of Commands ...
Page 206: ...196 Chapter 23 Command Interpreters ...
Page 216: ...206 Chapter 25 Using gdb under gnu Emacs ...
Page 296: ...286 Chapter 27 gdb Annotations ...
Page 300: ...290 Chapter 28 Reporting Bugs in gdb ...
Page 322: ...312 Chapter 30 Using History Interactively ...
Page 362: ...352 Appendix D gdb Remote Serial Protocol ...
Page 380: ...370 Appendix F GNU GENERAL PUBLIC LICENSE ...
Page 386: ...376 Appendix G GNU Free Documentation License ...
Page 410: ......