STREAMS/UX for the HP 9000 Reference Manual

204
Debugging STREAMS/UX Modules and Drivers
Debugging Examples
We may be able to determine whether we executed the “if” clause or the
“else” clause of the if statement, based on the fact that we know we executed
spput+0x4C (because a trap occurred while executing it). The comibf
instruction branches to its target address if the condition it is checking is
false. This comibf instruction compares ret0 to zero. If ret0 equals zero,
comibf will not branch, and execution will continue to spput+0x3C and
spput+0x40. spput+0x40 is an unconditional branch to spput+0x54, which
is past spput+0x4C. Therefore, if ret0 had been zero, we never would have
executed spput+0x4C. So ret0 was not zero. Since we know that the comibf
instruction corresponds to “if (!lp->mp),” we know that lp->mp was not
NULL, and the comibf instruction branches to spput+0x48 if lp->mp is not
NULL, we can be confident that spput+0x48 and spput+0x4C are part of the
else clause of the if statement, which consists of one statement,
“lp->last_mp->b_next = mp;.”
Now we know which source code line we panicked on. We need to
determine which source code pointer the register r1 corresponds to, because
dereferencing r1 is what caused the panic. To do this, we work backwards
from spput+0x4C to see where r1's contents came from. On spput+0x48, r1
gets loaded from arg1 + 0xC. Now we look backward to see where arg1
came from. It is tempting to assume that arg1 is the second argument to
spput, which is mp. But at spput+0x10, arg1 is the target of a load, so at
spput+0x48 arg1 does not contain mp. It is also tempting to look at
spput+0x44 for the origins of arg1's contents, because that instruction has
arg1 as its target. But because we took the comibf at spput+0x38, we must
have branched around spput+0x44, so we can ignore this instruction.
Looking further backward to spput+0x30, arg1 gets loaded from arg0 +
0x14. arg0 has not been the target of a load instruction since the beginning
of spput, so it must still contain the first argument to spput, q. Looking at the
source code, the only time that q is referenced is to set lp in the statement
before the if. So arg1 must correspond to lp. Looking at the source code line
where the panic occurred, “lp->last_mp->b_next = mp,” and the assembly
code lines spput+0x48 and spput+0x4C, it appears that spput+0x48 is setting
r1 to lp->last_mp, and spput+0x4C is attempting to put the contents of r31
into memory location r1 + 0, which must be “lp->last_mp->b_next”.
So our problem is that lp->last_mp is NULL. It may help us to look at the
rest of *lp, and to do so we need to find the value of arg1 at the time of the
panic. We may be able to extract this information from the stack if we know