Attila Rajmund Nohl
2011-Apr-22 16:54 UTC
[dtrace-discuss] How to access fields of structs?
Hello! I''m trying to write a dtrace script that will log the parameters of the putmsg calls of a process. So far I''ve got this: #!/usr/sbin/dtrace -qs syscall::putmsg:entry { printf("Calling putmsg, filedes: %5d, ctlptr: %8x, dataptr: %8x, flags: %5d", arg0, arg1, arg2, arg3); } syscall::putmsg:return { printf("Return from putmsg: %d", (int)arg0); } Of course, the value of the ctlptr is a rather meaningless memory address of a struct - how can I access the values of the fields of that struct? I''ve tried this: printf("maxlen: %5d", arg1->maxlen); compilation error, then ctlptr = (struct strbuf*)arg1; printf("maxlen: %5d", ctlptr->maxlen); and got: dtrace: error on enabled probe ID 1 (ID 6236: syscall::putmsg:entry): invalid address (0xffbfeeac) in action #6 at DIF offset 4 How can that be an invalid address? Or is the program I''m tracing buggy?
On Fri, Apr 22, 2011 at 11:54 AM, Attila Rajmund Nohl <attila.r.nohl at gmail.com> wrote:> compilation error, then > > ? ? ? ?ctlptr = (struct strbuf*)arg1; > ? ? ? ?printf("maxlen: %5d", ctlptr->maxlen); > > and got: > > dtrace: error on enabled probe ID 1 (ID 6236: syscall::putmsg:entry): > invalid address (0xffbfeeac) in action #6 at DIF offset 4This gives you a pointer into userspace. The dtrace probes operate in kernel space. Something like this should do it: ctlptr = (struct strbuf*)copyin(arg1, sizeof(struct strbuf)); -- Mike Gerdts http://mgerdts.blogspot.com/
Attila Rajmund Nohl
2011-Apr-26 15:43 UTC
[dtrace-discuss] How to access fields of structs?
2011/4/22, Mike Gerdts <mgerdts at gmail.com>:> On Fri, Apr 22, 2011 at 11:54 AM, Attila Rajmund Nohl > <attila.r.nohl at gmail.com> wrote: >> compilation error, then >> >> ctlptr = (struct strbuf*)arg1; >> printf("maxlen: %5d", ctlptr->maxlen); >> >> and got: >> >> dtrace: error on enabled probe ID 1 (ID 6236: syscall::putmsg:entry): >> invalid address (0xffbfeeac) in action #6 at DIF offset 4 > > This gives you a pointer into userspace. The dtrace probes operate in > kernel space. Something like this should do it: > > ctlptr = (struct strbuf*)copyin(arg1, sizeof(struct strbuf));Thanks, that helped. However, this strbuf structure has a pointer and I''d like to know what it points at. My guess this is also a user space pointer, so I should use something like this: printf("buf: %s\n", copyinstr((uintptr_t)ctlptr->buf, ctlptr->len)); but I get again an error like this: dtrace: error on enabled probe ID 2 (ID 6237: syscall::putmsg:return): invalid address (0xffbfeeb800000000) in action #10 at DIF offset 64 Of course, I get similar error even without the copyinstr: printf("buf: %s\n", stringof(ctlptr->buf)); dtrace: error on enabled probe ID 2 (ID 6237: syscall::putmsg:return): invalid address (0xffbfeeb800000000) in action #10 I''ve moved the printf call to the system call return section, but no lock. The value of ctlptr->buf is 0x0000000b (which is slightly suspicious, because it''s quite low number). Should the printf above work or does the pointer has wrong value?
On Tue, Apr 26, 2011 at 10:43 AM, Attila Rajmund Nohl <attila.r.nohl at gmail.com> wrote:> Thanks, that helped. However, this strbuf structure has a pointer and > I''d like to know what it points at. My guess this is also a user space > pointer, so I should use something like this: > > ? ? ? ?printf("buf: %s\n", copyinstr((uintptr_t)ctlptr->buf, ctlptr->len));What''s ctlptr point to? If it''s a user-land pointer then you have to copyin() that structure first, and, because user-land might be running 32-bit while the kernel runs in 64-bit, you''d have to interpret the copied-in data carefully to dig out the ''buf'' field from whatever ctlptr points to, then you have to copyinstr() that. It''s pretty painful... I''ve written many a script that did this sort of thing, and so have others. Anyways, if you look at blogs.sun.com, you''ll find some examples of what you trying to do, such as: http://blogs.sun.com/peteh/entry/dereferencing_user_space_pointers_in http://blogs.sun.com/nico/entry/using_dtrace_to_debug_encrypted http://blogs.sun.com/nico/entry/dtracing_idmapd http://blogs.sun.com/ahl/entry/dtrace_is_open The last one shows you what you need to know in order to build a script that can trace 32- and 64-bit user-land processes at once.> but I get again an error like this: > > dtrace: error on enabled probe ID 2 (ID 6237: syscall::putmsg:return): > invalid address (0xffbfeeb800000000) in action #10 at DIF offset 64>From this I gather that ctlptr points to a struct in user-land. Youhave to copy that in first before you can get at a field of it. Nico --