Discussion:
How to access fields of structs?
Attila Rajmund Nohl
2011-04-22 16:54:51 UTC
Permalink
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?
Mike Gerdts
2011-04-22 17:38:12 UTC
Permalink
On Fri, Apr 22, 2011 at 11:54 AM, Attila Rajmund Nohl
Post by Attila Rajmund Nohl
compilation error, then
       ctlptr = (struct strbuf*)arg1;
       printf("maxlen: %5d", ctlptr->maxlen);
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));
--
Mike Gerdts
http://mgerdts.blogspot.com/
Attila Rajmund Nohl
2011-04-26 15:43:41 UTC
Permalink
Post by Mike Gerdts
On Fri, Apr 22, 2011 at 11:54 AM, Attila Rajmund Nohl
Post by Attila Rajmund Nohl
compilation error, then
ctlptr = (struct strbuf*)arg1;
printf("maxlen: %5d", ctlptr->maxlen);
invalid address (0xffbfeeac) in action #6 at DIF offset 4
This gives you a pointer into userspace. The dtrace probes operate in
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?
Nico Williams
2011-04-26 16:49:12 UTC
Permalink
On Tue, Apr 26, 2011 at 10:43 AM, Attila Rajmund Nohl
Post by Attila Rajmund Nohl
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
       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.
Post by Attila Rajmund Nohl
invalid address (0xffbfeeb800000000) in action #10 at DIF offset 64
From this I gather that ctlptr points to a struct in user-land. You
have to copy that in first before you can get at a field of it.

Nico
--
_______________________________________________
dtrace-discuss mailin

Loading...