سؤال

ولدي التحقيق DTrace اصطياد المكالمات إلى وظيفة، واحدة من حجج الدالة هو CFStringRef. هذا هو الهيكل الخاص الذي يحمل مؤشر إلى سلسلة يونيكود. ولكن CFStringRef ليس في حد ذاته char*، لذلك أساليب DTrace العادية مثل copyinstr() فقط عودة ?cp?، وهي ليست مفيدة تماما.

ولكن كيف يمكنني طباعة السلسلة في العمل DTrace؟

هل كانت مفيدة؟

المحلول

وبقدر ما أعرف، ليس هناك المدمج في دعم لهذا النوع من الشيء. عادة مكتبة ستقوم بنشر التحقيق الذي يترجم السلسلة بالنسبة لك (كما يذكر براد). ذلك لأنه في حالتك لا يمكنك تعديل المكتبة، ستحتاج إلى استخدام موفر pid وربط في وظيفة المستخدم، وترجم ذلك بنفسك.

والحل (التي هي مشابهة جدا لنهج ستستخدم في C ++ لتفريغ std::string) هو تفريغ مؤشر والتي يتم تخزينها في كلمة 2 تعويض من المؤشر قاعدة CFStringRef. لاحظ أنه منذ CFString يمكن تخزين سلاسل داخليا في مجموعة متنوعة من الأشكال والتمثيل، وهذا هو عرضة للتغيير.

ونظرا لتطبيق اختبار تافهة:

#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:

#!/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));

}

وسوف يكون الإخراج شيئا مثل:

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

وببساطة غير تعليق على typedef الحق اعتمادا على ما إذا كنت تقوم بتشغيل ضد ثنائي 32 بت أو 64 بت. لقد جربت هذا ضد كل من أبنية على 10.6 وأنه يعمل بشكل جيد.

نصائح أخرى

وأعتقد أنه لا يمكنك القيام بذلك مباشرة، ولكن يمكنك إنشاء مسبار ثابت مخصص الذي يغذي في CFString / NSString كما شار *، والتي يمكنك استخدامها مع copyinstr (). أصف كيفية القيام بذلك في مقال <وأ href = "http://www.macresearch.org/tuning-cocoa-applications-using-dtrace-custom-static-probes-and-instruments" يختلط = "نوفولو noreferrer" > هنا .

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top