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:
Содержание ENTERPRISE LINUX 4 - DEVELOPER TOOLS GUIDE
Страница 1: ...Red Hat Enterprise Linux 4 Debugging with gdb ...
Страница 12: ...2 Chapter 1 Debugging with gdb ...
Страница 28: ...18 Chapter 4 Getting In and Out of gdb ...
Страница 34: ...24 Chapter 5 gdb Commands ...
Страница 44: ...34 Chapter 6 Running Programs Under gdb ...
Страница 68: ...58 Chapter 8 Examining the Stack ...
Страница 98: ...88 Chapter 10 Examining Data ...
Страница 112: ...102 Chapter 12 Tracepoints ...
Страница 118: ...108 Chapter 13 Debugging Programs That Use Overlays ...
Страница 138: ...128 Chapter 14 Using gdb with Different Languages ...
Страница 144: ...134 Chapter 15 Examining the Symbol Table ...
Страница 170: ...160 Chapter 19 Debugging remote programs ...
Страница 198: ...188 Chapter 21 Controlling gdb ...
Страница 204: ...194 Chapter 22 Canned Sequences of Commands ...
Страница 206: ...196 Chapter 23 Command Interpreters ...
Страница 216: ...206 Chapter 25 Using gdb under gnu Emacs ...
Страница 296: ...286 Chapter 27 gdb Annotations ...
Страница 300: ...290 Chapter 28 Reporting Bugs in gdb ...
Страница 322: ...312 Chapter 30 Using History Interactively ...
Страница 362: ...352 Appendix D gdb Remote Serial Protocol ...
Страница 380: ...370 Appendix F GNU GENERAL PUBLIC LICENSE ...
Страница 386: ...376 Appendix G GNU Free Documentation License ...
Страница 410: ......