2009-09-11 14 views
8

मेरे पास एक फ़ंक्शन पर कॉल करने की एक डीटी्रेस जांच है, और फ़ंक्शन के तर्कों में से एक CFStringRef है। यह निजी संरचना है जो एक यूनिकोड स्ट्रिंग के लिए पॉइंटर रखती है। लेकिन CFStringRef अपने आप को char* नहीं है, इसलिए copyinstr() जैसे सामान्य DTrace विधियां बस ?cp? पर वापस आएं, जो वास्तव में उपयोगी नहीं है।मैं एक DTrace कार्रवाई में CFStringRef कैसे मुद्रित करूं?

तो मैं डीटीआरएस कार्रवाई में स्ट्रिंग को कैसे मुद्रित कर सकता हूं?

उत्तर

12

जहां तक ​​मुझे पता है, इस तरह की चीज़ के लिए अंतर्निहित समर्थन नहीं है। आम तौर पर एक लाइब्रेरी एक जांच प्रकाशित करेगी जो आपके लिए स्ट्रिंग को डीकोड करेगी (ब्रैड उल्लेख के रूप में)। इसलिए जब से आप अपने पुस्तकालय को संशोधित नहीं कर सकते हैं, तो आपको pid प्रदाता का उपयोग करने और उपयोगकर्ता फ़ंक्शन में हुक करने की आवश्यकता होगी, और इसे स्वयं डीकोड करें।

समाधान (जो std::string डंप करने के लिए सी ++ में उपयोग किए जाने वाले दृष्टिकोण के समान है) को CFStringRef पॉइंटर से 2 शब्द ऑफसेट पर संग्रहीत पॉइंटर को डंप करना है। ध्यान दें कि CFString विभिन्न स्वरूपों और प्रस्तुतियों में आंतरिक रूप से तारों को स्टोर कर सकता है, यह परिवर्तन के अधीन है।

तुच्छ परीक्षण आवेदन दिया गया है:

#!/usr/sbin/dtrace -s 

/* 
    Dumps a CFStringRef parameter to a function, 
    assuming MacRoman or ASCII encoding. 
    The C-style string is found at an offset of 
    2 words past the CFStringRef pointer. 
    This appears to work in 10.6 in 32- and 64-bit 
    binaries, but is an implementation detail that 
    is subject to change. 

    Written by Gavin Baker <gavinb.antonym.org> 
*/ 

#pragma D option quiet 

/* Uncomment for LP32 */ 
/* typedef long ptr_t; */ 
/* Uncomment for LP64 */ 
typedef long long ptr_t; 

pid$target::mungeString:entry 
{ 
    printf("Called mungeString:\n"); 
    printf("arg0 = 0x%p\n",arg0); 

    this->str = *(ptr_t*)copyin(arg0+2*sizeof(ptr_t), sizeof(ptr_t)); 
    printf("string addr = %p\n", this->str); 
    printf("string val = %s\n", copyinstr(this->str)); 

} 

और उत्पादन किया जाएगा कुछ:

#include <CoreFoundation/CoreFoundation.h> 

int mungeString(CFStringRef someString) 
{ 
    const char* str = CFStringGetCStringPtr(someString, kCFStringEncodingMacRoman); 
    if (str) 
     return strlen(str); 
    else 
     return 0; 
} 

int main(int argc, char* argv[]) 
{ 
    CFStringRef data = CFSTR("My test data"); 

    printf("%u\n", mungeString(data)); 

    return 0; 
} 

निम्नलिखित dtrace स्क्रिप्ट पहले तर्क की स्ट्रिंग मान प्रिंट होगा, यह मानते हुए कि एक CFStringRef है जैसे:

$ sudo dtrace -s dump.d -c ./build/Debug/dtcftest 
12 
Called mungeString: 
arg0 = 0x2030 
string addr = 1fef 
string val = My test data 

बस unco आप 32-बिट या 64-बिट बाइनरी के खिलाफ चल रहे हैं या नहीं, इस पर निर्भर करता है कि typedef सही है। मैंने 10.6 पर दोनों आर्किटेक्चर के खिलाफ इसका परीक्षण किया है और यह ठीक काम करता है।

+0

इस प्रोग्राम और इस जांच फ़ाइल का उपयोग करके, मुझे बस इसकी एक बड़ी सूची मिलती है: dtrace: सक्षम जांच आईडी 1 पर त्रुटि (आईडी 93815: pid11402: sc: mungeString: प्रविष्टि): कार्रवाई में अमान्य पता (0x7c8) # 5 DIF पर ऑफसेट 12 लाइन है कि स्ट्रिंग प्रिंट बाहर ले रहा है, मुझे लगता है कि सभी स्ट्रिंग addrs एक बालक असामान्य हैं: नामक mungeString: arg0 = 0x100001068 स्ट्रिंग addr = 7c8 एक दूसरे, विभिन्न निरंतर स्ट्रिंग जोड़ा जा रहा है और mungeString'ing, मैं दोनों तारों के लिए एक ही स्ट्रिंग addr मिलता है। – TALlama

+0

ठीक है, मैं स्मृति पते से बता सकता हूं कि आपको 10.6 का उपयोग करना होगा और 64-बिट ऐप बनाना होगा। मैंने 10.5 पर टेस्ट ऐप (जल्दी में!) लिखा था क्योंकि उस समय मेरे पास पहुंच थी। मुझे डीटीआरएस स्क्रिप्ट में ऑफ़सेट के लिए आकार (intptr_t) का उपयोग किया जाना चाहिए ताकि आर्क-तटस्थ हो (हार्डकोड 8 की बजाय, जो अब 64-बिट ऐप में 16 हो)। मैं 10.6 मशीन पर एक नज़र डालेगा। – gavinb

+0

@TALlama कृपया ऊपर दी गई अद्यतन स्क्रिप्ट का प्रयास करें। मैंने इसे 32-बिट और 64-बिट दोनों बाइनरी पर परीक्षण किया और यह ठीक काम करता है। – gavinb

1

मेरा मानना ​​है कि आप इसे सीधे नहीं कर सकते हैं, लेकिन आप एक कस्टम स्थिर जांच बना सकते हैं जो सीएफस्ट्रिंग/एनएसएसटींग में एक char * के रूप में फ़ीड करता है, जिसे आप copyinstr() के साथ उपयोग कर सकते हैं। मैं वर्णन करता हूं कि यह लेख here में कैसे करें।

+0

दुर्भाग्य से, मैं कुछ संकलित कोड की जांच करने के लिए इसका उपयोग करने की कोशिश कर रहा हूं जिस पर मेरा नियंत्रण नहीं है, इसलिए स्रोत बदलना संभव नहीं है। – TALlama

संबंधित मुद्दे