[dtrace-discuss] Handling userland char ** pointers

Chip Bennett cbennett at laurustech.com
Tue Aug 8 13:06:45 PDT 2006


I've been trying to get access to a userland string that's behind a 
second level pointer using DTrace, but I can't seem to get it to work.

I started with the example on the Team DTrace Tips and Tricks slides:

   trace(copyinstr(*(uintptr_t *)copyin(arg0, curpsinfo->pr_dmodel == 
PR_MODEL_ILP32 ? 4 : 8)));

And when I couldn't get it to work, I started breaking it down into 
smaller pieces to see what was going on at each step.  Here's the "C" 
and "D" code:

--- pt.c ---

static int sz = sizeof(char *);

main()
{
   char *s = "abcdefghijk";
   char **p = &s;
   printf ("Size of pointer = %d\n", sz);
   sub1(s);
   sub2(p);
   exit(0);
}
sub1 (char *arg)
{
   if (sz == 4)
      printf ("First 32 bit pointer = %x\n", arg);
   else
      printf ("First 64 bit pointer = %llx\n", arg);
   puts (arg);
   return;
}

sub2 (char **arg)
{
   if (sz == 4)
      printf ("Second 32 bit pointer = %x\n", arg);
   else
      printf ("Second 64 bit pointer = %llx\n", arg);
   puts (*arg);
   return;
}

--- pt.d ---

pid$target::sub1:entry
{
   trace (copyinstr(arg0));
}
pid$target::sub2:entry
{
   sz = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? 4 : 8;
   printf ("Userland pointer size = %d\n", sz);
}
pid$target::sub2:entry
{
   pcp = (uint32_t *) copyin (arg0, sz);     /* pcp is ptr to copy of 
char * */
   printf ("D pointer pcp = %a\n", pcp);
}
pid$target::sub2:entry
{
   cp = *pcp;                                /* cp is copy of char *  */
   printf ("%d byte userland pointer = %a\n", sizeof (cp), cp);
}
pid$target::sub2:entry
{
   str = copyinstr(cp);                       /* str is the actual string */
   trace (str);
}

When I enter the command : "dtrace -s pt.d -c ./pt", I get:

dtrace: script 'pt2.d' matched 5 probes
Size of pointer = 4
First 32 bit pointer = 108a8
abcdefghijk
Second 32 bit pointer = ffbffdec
abcdefghijk
CPU     ID                    FUNCTION:NAME
  0  38670                       sub1:entry   abcdefghijk
  0  38671                       sub2:entry Userland pointer size = 4

  0  38671                       sub2:entry D pointer pcp = 0x300adeda120

  0  38671                       sub2:entry 4 byte userland pointer = 0x4

dtrace: error on enabled probe ID 5 (ID 38671: pid10122:pt:sub2:entry): 
invalid address (0x0) in action #1 at DIF offset 16
dtrace: pid 10122 has exited

Obviously, what I'm copying is not the right char pointer.  What am I 
missing?

One side note: the example on the slide used uintptr_t as the type for 
the userland pointer.  Using that instead of uint32_t and uint64_t, 
didn't work for me either, but I changed it because, even though my 
application seems to be 32 bit, sizeof(uintptr_t) kept returning 8 bytes.

Also, I'm using gcc, if that matters.

Thanks,
Chip


More information about the dtrace-discuss mailing list