Joel,
My research indicates that you will have to know the
offsets of the data you wish to examine through the this
pointer. It is not a C struct and DTrace does understand C++.
Attached is an example.
What must be identified is the location of the virtual function
table. On a simple object it is the first field. If you have
multiple inheritance there may be more than one.
arwen: make
CC -m64 -g -c CCtest.cc
CC -m64 -g -c TestClass.cc
CC -m64 -g -o CCtest CCtest.o TestClass.o
echo "Done."
Done.
arwen: dbx CCtest
For information about new features see `help changes''
To remove this message, put `dbxenv suppress_startup_message 7.7'' in
your .dbxrc
Reading CCtest
Reading ld.so.1
Reading libCstd.so.1
Reading libCrun.so.1
Reading libm.so.2
Reading libc.so.1
(dbx) stop in main
(2) stop in main
(dbx) run
Running: CCtest
(process id 2803)
stopped in main at line 10 in file "CCtest.cc"
10 int i=0;
(dbx) n
stopped in main at line 13 in file "CCtest.cc"
13 t = new TestClass(i);
(dbx) n
stopped in main at line 14 in file "CCtest.cc"
14 t->a=''a'';
(dbx) n
stopped in main at line 15 in file "CCtest.cc"
15 t->j=0xffff;
(dbx) n
stopped in main at line 16 in file "CCtest.cc"
16 cout << t->ClassName();
(dbx) n
Integer = 0stopped in main at line 17 in file "CCtest.cc"
17 t->setname((const char *)"Goodbye.");
(dbx) n
stopped in main at line 18 in file "CCtest.cc"
18 cout << t->ClassName() << endl;
(dbx) n
Goodbye.
stopped in main at line 19 in file "CCtest.cc"
19 sleep(5);
(dbx)
(dbx) print t
t = 0x4175b0
(dbx) print &t
&t = 0xfffffd7fffdfeb30
(dbx) print *t
*t = {
a = ''a''
j = 65535
str = 0x41cbe0 "Goodbye."
}
(dbx) examine t/20
0x00000000004175b0: 0x00412870 0x00000000 0x00000061 0x0000ffff
0x00000000004175c0: 0x0041cbe0 0x00000000 0x00000000 0x00000000
0x00000000004175d0: 0x00000020 0x00000000 0x00000000 0x00000000
0x00000000004175e0: 0x00417600 0x00000000 0x00000000 0x00000000
0x00000000004175f0: 0x00000000 0x00000000 0x00000000 0x00000000
========================================================less str.d
#!/usr/sbin/dtrace -Cs
typedef struct TestClass
{
void *ptr;
char a;
int j;
char *str;
}TestClass_t;
pid$target::__1cJTestClassHsetname6Mpkc_i_:entry
{
/* this->str = *(uintptr_t *)copyin(arg1, sizeof(void *)); */
this->ptr = arg0; /* this pointer */
printf("\n this ptr = %p\n", this->ptr);
this->sptr=(TestClass_t *)copyin(this->ptr, sizeof(TestClass_t));
printf("\n this my_ptr = %p\n", ((TestClass_t
*)this->sptr)->ptr);
printf("\n this my_char = %c\n", ((TestClass_t
*)this->sptr)->a);
printf("\n this my_int = %d\n", ((TestClass_t
*)this->sptr)->j);
printf("\n this my_str_ptr = %p\n", ((TestClass_t
*)this->sptr)->str);
printf("\n this my_str = %s \n", copyinstr((uintptr_t)((TestClass_t
*)this->sptr)->str));
this->str = copyinstr(arg1);
printf("\nnew string = %s\n", this->str);
}
========================================================arwen: str.d -c CCtest
dtrace: script ''str.d'' matched 1 probe
Integer = 0Goodbye.
CPU ID FUNCTION:NAME
0 83901 __1cJTestClassHsetname6Mpkc_i_:entry
this ptr = 4175b0
this my_ptr = 412870
this my_char = a
this my_int = 65535
this my_str_ptr = 435d10
this my_str = Integer = 0
new string = Goodbye.
Integer = 1Goodbye.
1 83901 __1cJTestClassHsetname6Mpkc_i_:entry
this ptr = 4175b0
this my_ptr = 412870
this my_char = a
this my_int = 65535
this my_str_ptr = 435d10
this my_str = Integer = 1
new string = Goodbye.
rick
--
Rickey C. Weisner
Software Development and Performance Specialist
Principal Field Technologist
Systems Quality Office
cell phone: 615-308-1147
email: rick.weisner at sun.com
-------------- next part --------------
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "TestClass.h"
int main(int argc, char **argv)
{
TestClass *t;
int i=0;
while (1) {
t = new TestClass(i);
t->a=''a'';
t->j=0xffff;
cout << t->ClassName();
t->setname((const char *)"Goodbye.");
cout << t->ClassName() << endl;
sleep(5);
delete t;
i++;
}
}
-------------- next part --------------
OBJS=CCtest.o TestClass.o
PROGS=CCtest
CC=CC -m64
all: $(PROGS)
echo "Done."
clean:
rm $(OBJS) $(PROGS)
CCtest: $(OBJS) TestClass.h
$(CC) -g -o CCtest $(OBJS)
.cc.o: TestClass.h
$(CC) -g $(CFLAGS) -c $<
-------------- next part --------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "TestClass.h"
TestClass::TestClass() {
str=strdup("empty.");
}
TestClass::TestClass(const char *name) {
str=strdup(name);
}
int TestClass::setname(const char *name) {
if ( str ) free(str);
str=strdup(name);
return 0;
}
TestClass::TestClass(int i) {
str=(char *)malloc(128);
sprintf(str, "Integer = %d", i);
}
TestClass::~TestClass() {
if ( str )
free(str);
}
char *TestClass::ClassName() const {
return str;
}
-------------- next part --------------
class TestClass
{
public:
TestClass();
TestClass(const char *name);
TestClass(int i);
int setname(const char *name);
virtual ~TestClass();
virtual char *ClassName() const;
char a;
int j;
private:
char *str;
};
-------------- next part --------------
#!/usr/sbin/dtrace -Cs
typedef struct TestClass
{
void *ptr;
char a;
int j;
char *str;
}TestClass_t;
pid$target::__1cJTestClassHsetname6Mpkc_i_:entry
{
/* this->str = *(uintptr_t *)copyin(arg1, sizeof(void *)); */
this->ptr = arg0; /* this pointer */
printf("\n this ptr = %p\n", this->ptr);
this->sptr=(TestClass_t *)copyin(this->ptr, sizeof(TestClass_t));
printf("\n this my_ptr = %p\n", ((TestClass_t
*)this->sptr)->ptr);
printf("\n this my_char = %c\n", ((TestClass_t
*)this->sptr)->a);
printf("\n this my_int = %d\n", ((TestClass_t
*)this->sptr)->j);
printf("\n this my_str_ptr = %p\n", ((TestClass_t
*)this->sptr)->str);
printf("\n this my_str = %s \n", copyinstr((uintptr_t)((TestClass_t
*)this->sptr)->str));
this->str = copyinstr(arg1);
printf("\nnew string = %s\n", this->str);
}