[dtrace-discuss] C++ objects from DTrace

rickey c weisner rohanrcw at comcast.net
Thu Oct 1 13:58:41 PDT 2009


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);
}


More information about the dtrace-discuss mailing list