STREAMS/UX for the HP 9000 Reference Manual

210
Debugging STREAMS/UX Modules and Drivers
Debugging Examples
We can find flushq()'s calling sequence in its man page in SVR4PG:
void flushq(queue_t *q, int flag)
It is more likely that *q or one of its members is NULL than the parameter
flag being the cause of our problem. We will trace the use of the first
argument, originally in arg0, through flushq, to see how it might be related to
the contents of r21.
At flushq+0x8, arg0 is pushed onto the stack at offset sp - 0x64. Neither
arg0 nor -64(sp) is referenced again until flushq+0x34. At flushq+0x34, r21
is loaded with -64(sp), so at this point r21 contains *q. At flushq+0x38, r22
is loaded from memory location 4 + r21. Looking at the structure definition
for queue_t, found in /usr/include/sys/stream.h, we see that the second word
in a queue_t structure, which would be found at memory location r21 + 4, is
the q_first pointer.
So r22 now contains q->q_first. At flushq+0x3C, r22 is stored back in the
stack, at sp - 0x34.
At this point, it may be useful to try and work backwards from flushq+0x5C,
where r21 gets loaded from 0x14 + r20, because at the next instruction,
flushq+0x60, we know that r21 is NULL. We notice that at flushq+0x58, r20
is loaded from sp - 0x34. At flushq+0x3C, we know that sp - 0x34 was
struct queue {
struct qinit * q_qinfo; /* procedures and limits for queue */
struct msgb * q_first; /* head of message queue */
struct msgb * q_last; /* tail of message queue */
struct queue * q_next; /* next QUEUE in Stream */
struct queue * q_link; /* link to scheduling queue */
caddr_t q_ptr; /* to private data structure */
ulong q_count; /* weighted count of characters on q
*/
ulong q_flag; /* QUEUE state */
long q_minpsz; /* min packet size accepted */
long q_maxpsz; /* max packet size accepted */
ulong q_hiwat; /* high water mark, for flow control
*/
ulong q_lowat; /* low water mark */
struct qband * q_bandp; /* band information */
unsigned char q_nband; /* number of bands */
unsigned char q_pad1[3]; /* reserved */
struct queue * q_other; /* pointer to other Q in queue pair
*/
QUEUE_KERNEL_FIELDS
};