Discussion:
Printing a const char *
m***@public.gmane.org
17 years ago
Permalink
I have a C program,
$cat sample.cpp
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
struct xxx
{
int yyy;
int zzz;
const char *name;
};


void sub1 (struct xxx *p)
{
printf ("CProgram: %d %d %s\n", p->yyy, p->zzz, p->name);
}

main()
{
char * key = (char *)malloc(5);
key[0] = 'A';
key[1] = 'B';
key[2] = 'C';
key[3] = 'D';
key[4] = '\0';
struct xxx *t1 = new struct xxx;
t1->yyy = 20;
t1->zzz = 30;
t1->name = key;
sub1 (t1);
}

and a DTrace script :
$cat sample.d
struct xxx
{
int yyy;
int zzz;
const char *name;
};

pid$target:a.out:*sub1*:entry
{
sp = (struct xxx *) copyin (arg0, sizeof (struct xxx));
printf ("DTrace: %d %d \n", sp->yyy, sp->zzz);
printf ("DTrace: name=%s\n", stringof(sp->name));
exit (0);
}
$CC sample.cpp

$dtrace: script 'sample.d' matched 1 probe
CProgram: 20 30 ABCD
dtrace: pid 2624 has exited
dtrace: error on enabled probe ID 1 (ID 47665: pid2624:a.out:__1cEsub16FpnDxxx__v_:entry): invalid address (0x2872800000000) in action #4

What is this error ? I get this error when I compile the program in 64 bit as well.

$CC -xarch=v9 sample.cpp

$dtrace -s sample.d -c ./a.out
dtrace: script 'sample.d' matched 1 probe
CProgram: 20 30 ABCD
dtrace: pid 2629 has exited
dtrace: error on enabled probe ID 1 (ID 47665: pid2629:a.out:__1cEsub16FpnDxxx__v_:entry): invalid address (0x10010a000) in action #4
Adam Leventhal
17 years ago
Permalink
Post by m***@public.gmane.org
$cat sample.d
struct xxx
{
int yyy;
int zzz;
const char *name;
};
pid$target:a.out:*sub1*:entry
{
sp = (struct xxx *) copyin (arg0, sizeof (struct xxx));
printf ("DTrace: %d %d \n", sp->yyy, sp->zzz);
printf ("DTrace: name=%s\n", stringof(sp->name));
exit (0);
}
You've correctly copied the structure into DTrace's address space, but
you
didn't copy in the const char * (string). Rather than doing stringof()
on
sp->name, use the copyinstr() subroutine.

Adam

--
Adam Leventhal, Fishworks http://blogs.sun.com/ahl
m***@public.gmane.org
17 years ago
Permalink
$dtrace -s sample.d -c ./a.out
dtrace: failed to compile script sample.d: line 12: copyinstr( ) argument #1 is incompatible with prototype:
prototype: uintptr_t
argument: char *

$cat sample.d
struct xxx
{
int yyy;
int zzz;
const char *name;
};

pid$target:a.out:*sub1*:entry
{
sp = (struct xxx *) copyin (arg0, sizeof (struct xxx));
printf ("DTrace: %d %d \n", sp->yyy, sp->zzz);
printf ("DTrace: name=%s\n", copyinstr(sp->name));
exit (0);
}
Post by Adam Leventhal
You've correctly copied the structure into DTrace's
address space, but you
didn't copy in the const char * (string). Rather than
doing stringof() on
sp->name, use the copyinstr() subroutine.
m***@public.gmane.org
17 years ago
Permalink
Casting it explicitly as "uintptr_t" works for 64 bit program and not for 32 bit program.

$CC -xarch=v9 sample.cpp

$dtrace -s sample.d -c ./a.out
dtrace: script 'sample.d' matched 1 probe
CProgram: 20 30 ABCD
dtrace: pid 2974 has exited
CPU ID FUNCTION:NAME
0 47856 __1cEsub16FpnDxxx__v_:entry DTrace: 20 30
DTrace: name=ABCD


$CC sample.cpp

$dtrace -s sample.d -c ./a.out
dtrace: script 'sample.d' matched 1 probe
CProgram: 20 30 ABCD
dtrace: error on enabled probe ID 1 (ID 47856: pid2979:a.out:__1cEsub16FpnDxxx__v_:entry): invalid address (0x2872800000000) in action #4 at DIF offset 28
dtrace: pid 2979 has exited


$cat sample.d
struct xxx
{
int yyy;
int zzz;
const char *name;
};

pid$target:a.out:*sub1*:entry
{
sp = (struct xxx *) copyin (arg0, sizeof (struct xxx));
printf ("DTrace: %d %d \n", sp->yyy, sp->zzz);
printf ("DTrace: name=%s\n", copyinstr((uintptr_t)sp->name));
exit (0);
}
Adam Leventhal
17 years ago
Permalink
If the kernel is 64-bit and the traced program is 32-bit, you'll want
to change your structure definition so that it reflects the bitness of
the traced program. This means that for pointers you should use a
uint32_t rather than a char * for example.

Adam
...
--
Adam Leventhal, Fishworks http://blogs.sun.com/ahl
m***@public.gmane.org
17 years ago
Permalink
Post by Adam Leventhal
If the kernel is 64-bit and the traced program is 32-bit,
you'll want to change your structure definition so that
it reflects the bitness of the traced program. This means
that for pointers you should use a uint32_t rather than a
char * for example.
Adam
Ok Thanx.

If my program is 32 bit I include this in DTrace script :
struct xxx
{
int yyy;
int zzz;
uint32_t name;
};

If my program is 64 bit I include this in DTrace script :
struct xxx
{
int yyy;
int zzz;
const char *name;
};

Continue reading on narkive:
Loading...