Matthew Barker
2008-Dec-03 00:01 UTC
[dtrace-discuss] Tracing application-specific data structures
I have a provider that allows me to look at some application-specific data structs for SJS Web Server 7. The problem I''m finding is that some of the data is stored in a short linked list and I don''t see any way, without the unimplemented "for" or "if" constructs in dtrace, to trace those data structures. I''ve included an excerpt of the structure definitions from my script (copied from the provider). I''m trying to look at the contents of the series of pb_param structs, each referred to by a linked list of pb_entry structs which are hanging off of the pblock struct pointed to by Request.vars. Can anyone provide some insight as to how to go about it? typedef struct pblock { int hsize; struct pb_entry **ht; } pblock; typedef struct pb_param { char *name,*value; } pb_param; typedef struct pb_entry { pb_param *param; struct pb_entry *next; } pb_entry; typedef struct Request { pblock *vars; pblock *reqpb; int loadhdrs; pblock *headers; int senthdrs; pblock *srvhdrs; ... uint32_t orig_rq; /* was Request * */ } Request; sjsws$1::*:saf-entry { self->i=0; r=copyin(arg3,sizeof(struct Request)); v=copyin( ((uint32_t)((Request *)r)->vars), sizeof(pblock)); self->last=((pblock*)v)->hsize; printf("T(%d): Calling saf %s:vars(%d)\n", tid, copyinstr(arg0), self->last ); } sjsws$1:::saf-exit { printf(" T(%d):%s-->%d\n\n", tid, copyinstr(arg0), args[1]); } The provider declares these functions: provider sjsws { probe saf__entry(const char *, pblock *, Session *, Request *); probe saf__exit(const char *, int, pblock *, Session *, Request *); }; -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.opensolaris.org/pipermail/dtrace-discuss/attachments/20081202/eb9d92d5/attachment.html>
Adam Leventhal
2008-Dec-03 06:37 UTC
[dtrace-discuss] Tracing application-specific data structures
Hi Matthew, Your choice are to unroll a loop and use predicates to know when you''ve reached the end condition or to save state in global variables and use a tick probe to iterate through the list. If you need more guidance, feel free to ask, but you may be able to find an example of this in the discussion list archives as similar questions have been asked. Adam On Dec 2, 2008, at 4:01 PM, Matthew Barker wrote:> I have a provider that allows me to look at some application- > specific data structs for SJS Web Server 7. The problem I''m finding > is that some of the data is stored in a short linked list and I > don''t see any way, without the unimplemented "for" or "if" > constructs in dtrace, to trace those data structures. > > I''ve included an excerpt of the structure definitions from my script > (copied from the provider). I''m trying to look at the contents of > the series of pb_param structs, each referred to by a linked list of > pb_entry structs which are hanging off of the pblock struct pointed > to by Request.vars. > > Can anyone provide some insight as to how to go about it? > > typedef struct pblock { > int hsize; > struct pb_entry **ht; > } pblock; > > typedef struct pb_param { > char *name,*value; > } pb_param; > > typedef struct pb_entry { > pb_param *param; > struct pb_entry *next; > } pb_entry; > > typedef struct Request { > pblock *vars; > pblock *reqpb; > int loadhdrs; > pblock *headers; > int senthdrs; > pblock *srvhdrs; > > ... > > uint32_t orig_rq; /* was Request * */ > } Request; > > sjsws$1::*:saf-entry > { > self->i=0; > r=copyin(arg3,sizeof(struct Request)); > v=copyin( ((uint32_t)((Request *)r)->vars), sizeof(pblock)); > self->last=((pblock*)v)->hsize; > printf("T(%d): Calling saf %s:vars(%d)\n", tid, copyinstr(arg0), > self->last ); > } > > > sjsws$1:::saf-exit > { > printf(" T(%d):%s-->%d\n\n", tid, copyinstr(arg0), args[1]); > } > > The provider declares these functions: > > provider sjsws { > probe saf__entry(const char *, pblock *, Session *, Request *); > probe saf__exit(const char *, int, pblock *, Session *, Request *); > }; > > > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org-- Adam Leventhal, Fishworks http://blogs.sun.com/ahl
Matthew Barker
2008-Dec-04 00:18 UTC
[dtrace-discuss] Tracing application-specific data structures
Adam, thanks for your reply. I''m trying to do a root-cause analysis on a troublesome customer bug and single-stepping with a debugger is making the context difficult to track. I''ve been searching the forums before and after the posting. The problem has to do with what terms to search for. I did find a thread in volume 42 which covered why conditionals weren''t included in the language, but alternative patterns for traversing data structures seem to be lacking. Again, it probably comes down to knowing well enough the taxonomy to employ in searching in the DTrace forum. Questions: 1) By "tick probe" are you meaning a probe that fires on a timer tick, used to trigger the next iteration through the data structure? If so, I''d thought the data structure would be morphing underneath the traversal. If not, can you point me to an example? 2) Before writing to the alias, I was trying to get my head around something like the first approach you mention, of unrolling the loop and determining a stopping point. Having dealt with Prolog in the distant past, this at least occurred to me, but I''m missing how one can express this with DTrace. Any pointers are appreciated. Cheers, Matthew -- This message posted from opensolaris.org
Adam Leventhal
2008-Dec-04 02:15 UTC
[dtrace-discuss] Tracing application-specific data structures
> 2) Before writing to the alias, I was trying to get my head around > something like the first approach you mention, of unrolling the loop and > determining a stopping point. Having dealt with Prolog in the distant > past, this at least occurred to me, but I''m missing how one can express > this with DTrace.For example, you could do something like this: struct foo { int data; struct foo *next; }; <probe> { this->lst = arg1; } <probe> /this->list != NULL/ { trace(this->lst->data); this->lst = this->lst->next; } /* ... */ <probe> /this->list != NULL/ { trace(this->lst->data); this->lst = this->lst->next; } I blogged about something like this awhile ago: http://blogs.sun.com/ahl/entry/pid2proc_for_dtrace> Questions: 1) By "tick probe" are you meaning a probe that fires on a timer > tick, used to trigger the next iteration through the data structure? If > so, I''d thought the data structure would be morphing underneath the > traversal. If not, can you point me to an example?You could do something like this: <probe> { lst = arg1; } tick-10ms /lst != NULL/ { trace(lst->data); lst = lst->next; } But remember, that the use of global variables means that you can only have one of these at a time. Adam -- Adam Leventhal, Fishworks http://blogs.sun.com/ahl
Matthew Barker
2008-Dec-04 04:34 UTC
[dtrace-discuss] Tracing application-specific data structures
Thanks, Adam! This is what I was starting to converge on, but was fumbling with ordering of clauses. Your examples make things a lot clearer. Cheers, Matthew On Dec 3, 2008, at 6:15 PM, Adam Leventhal wrote:>> 2) Before writing to the alias, I was trying to get my head around >> something like the first approach you mention, of unrolling the >> loop and >> determining a stopping point. Having dealt with Prolog in the >> distant >> past, this at least occurred to me, but I''m missing how one can >> express >> this with DTrace. > > For example, you could do something like this: > > struct foo { > int data; > struct foo *next; > }; > > <probe> > { > this->lst = arg1; > } > > <probe> > /this->list != NULL/ > { > trace(this->lst->data); > this->lst = this->lst->next; > } > > /* ... */ > > <probe> > /this->list != NULL/ > { > trace(this->lst->data); > this->lst = this->lst->next; > } > > I blogged about something like this awhile ago: > > http://blogs.sun.com/ahl/entry/pid2proc_for_dtrace > >> Questions: 1) By "tick probe" are you meaning a probe that fires on >> a timer >> tick, used to trigger the next iteration through the data >> structure? If >> so, I''d thought the data structure would be morphing underneath the >> traversal. If not, can you point me to an example? > > You could do something like this: > > <probe> > { > lst = arg1; > } > > tick-10ms > /lst != NULL/ > { > trace(lst->data); > lst = lst->next; > } > > But remember, that the use of global variables means that you can > only have > one of these at a time. > > Adam > > -- > Adam Leventhal, Fishworks http://blogs.sun.com/ahl