c++ - DTracing objc_msgSend doesn't print the receiver class name -


i using dtrace print objc_msgsend in code. i've done far can see selector's name cannot correct class name.

this dtrace script:

#!/usr/sbin/dtrace -qs  pid$target::objc_msgsend:entry {     self->isa = *(long *)copyin(arg0, 8);     printf("-[%s %s]\n",     copyinstr(*(long *)copyin(self->isa + 16, 8)),     copyinstr(arg1)); } 

and assuming the id receiver object of following struct:

typedef struct objc_class {     struct objc_class *isa;     struct objc_class *super_class;     char *name;     ... } 

in head, in order reach name pointer has moved 2 * sizeof(objc_class*) makes 16, , pointer of name of size 8. therefore expected see class name garbage printed instead.

any ideas of doing wrong?

my system mavericks x64.

after poking around obj-c runtime source code 64 bit architecture , "objc-private.h" file, "formula" class name class pointer:

#define rw_realized (1<<31) #define rw_future (1<<30) #define class_fast_flag_mask  3 #define tag_mask 1 #define tag_slot_shift 0 #define tag_slot_mask 0xf  extern "c" class objc_debug_taggedpointer_classes[];  // available in 10.9 tagged pointers decoding  static const char* classnamefrominstance(id instance) {   char* ptr0 = (char*)instance;    char* ptr1;   if ((long)ptr0 & tag_mask) {     long slot = ((long)ptr0 >> tag_slot_shift) & tag_slot_mask;     ptr1 = (char*)objc_debug_taggedpointer_classes[slot];  // struct objc_class pointer   } else {     ptr1 = *(char**)ptr0;  // struct objc_class pointer i.e. instance isa   }    char* ptr2 = *((char**)(((long)ptr1 + 32) & ~class_fast_flag_mask));  // struct class_ro_t or struct class_rw_t pointer    uint32_t flags = *((uint32_t*)ptr2);  // struct class_ro_t or struct class_rw_t flags   char* ptr3;   if ((flags & rw_realized) || (flags & rw_future)) {     ptr3 = *((char**)((long)ptr2 + 8));  // struct class_ro_t pointer struct class_rw_t pointer   } else {     ptr3 = ptr2;  // struct class_ro_t pointer same struct class_rw_t pointer   }    const char* name = *((char**)((long)ptr3 + 24));  // name string pointer struct class_ro_t pointer    return name; } 

which in dtrace becomes in example script logs obj-c objects creation & destruction:

#!/usr/bin/env dtrace -s #pragma d option quiet  pid$target:libobjc.a.dylib:class_createinstance:entry {   ptr1 = *(long*)copyin(arg0, 8);  /* arg0 class pointer */   ptr2 = *(long*)copyin((ptr1 + 32) & ~3, 8);   flags = *(int*)copyin(ptr2, 4);   ptr3 = (flags & (1 << 31)) || (flags & (1 << 30)) ? *(long*)copyin(ptr2 + 8, 8) : ptr2;   ptr4 = *(long*)copyin(ptr3 + 24, 8);   self->class = copyinstr(ptr4); }  pid$target:libobjc.a.dylib:class_createinstance:return {   printf("[+] %s = %p\n", self->class, arg1);  /* arg1 instance pointer */   self->class = 0; }  pid$target:libobjc.a.dylib:object_dispose:entry /arg0 != 0/ {   ptr0 = *(long*)copyin(arg0, 8);  /* arg0 instance pointer */   ptr1 = *(long*)copyin(ptr0, 8);  /* todo: handle tagged pointers */   ptr2 = *(long*)copyin((ptr1 + 32) & ~3, 8);   ptr3 = (flags & (1 << 31)) || (flags & (1 << 30)) ? *(long*)copyin(ptr2 + 8, 8) : ptr2;   ptr4 = *(long*)copyin(ptr3 + 24, 8);   class = copyinstr(ptr4);    printf("[-] %s = %p\n", class, arg0); } 

important dtrace script not handle tagged pointers. sure set environment variable "dyld_shared_region=avoid" when using script explained here.


Comments

Popular posts from this blog

c# - How to get the current UAC mode -

postgresql - Lazarus + Postgres: incomplete startup packet -

javascript - Ajax jqXHR.status==0 fix error -