Можно ли получить результат метода objc в dtrace? - PullRequest
7 голосов
/ 13 августа 2011

Я написал действие, которое запускается при возврате любого метода objc (objc ::: return).Сейчас мне нужно получить возвращаемое значение.Возможно ли это?

1 Ответ

5 голосов
/ 03 сентября 2011

В итоге: нет, вы не можете получить возвращаемое значение метода Objective-C в тесте DTrace.

У Билла Бумгарнера есть запись о сообщениях трассировки до nil вчто он говорит следующее:

В сторону: objc_msgSend() возвращение не может быть отслежено через dtrace в это время.Не удивительно, учитывая, что функция на самом деле не возвращает - что касается dtrace, то это всего лишь преамбула.

Сообщение в блоге довольно старое (январь 2008 г.) и использует провайдера pid., а не провайдер objc.Тем не менее, он все еще действует в Mac OS X v10.7.1 и также применяется к поставщику objc.

Забавно, но иногда может показаться, что это работает, но зависит от того, когда DTrace читает регистр RAX.Поскольку objc_msgSend() не возвращает, DTrace в конечном итоге использует значения в RAX, которые были сохранены кодом, который не обязательно является возвращением отслеживаемого метода.

Рассмотрим следующий код:

NSNumber *n = [NSNumber numberWithInt:1234];
printf("n has address %p\n", n);

и следующий зонд:

objc$target:NSPlaceholderNumber:-initWithInt?:return
{
    printf("Returning from -[NSPlaceholderNumber initWithInt:]\n");
    printf("\treturn value = 0x%p\n", (void *)arg1);
}

При запуске с использованием DTrace я получаю следующий вывод:

n has address 0x4d283
Returning from -[NSPlaceholderNumber initWithInt:]
    return value = 0x4d283

, поэтому кажется, что зонд смог захватить возвратзначение -initWithInt:.Это только удача, вероятно, вызванная функцией (например, CFNumberCreate() или CFMakeCollectable()), вызываемой -initWithInt:, которая в итоге поместила ожидаемое значение в RAX.

Теперь рассмотрим следующий код:

char *c = "hello";
NSData *data = [NSData dataWithBytes:c length:strlen(c)];
NSString *s = [[NSString alloc] initWithData:data
                                    encoding:NSASCIIStringEncoding];
printf("s has address %p\n", s);

и следующий зонд:

objc$target:NSPlaceholderString:-initWithData?encoding?:return
{
    printf("Returning from -[NSPlaceholderString initWithData:encoding:]\n");
    printf("\treturn value = 0x%p\n", (void *)arg1);
}

При запуске с использованием DTrace я получаю следующий вывод:

s has address 0x7fcd92414ea0
Returning from -[NSPlaceholderString initWithData:encoding:]
    return value = 0x600

Как видите, адреса (т.е., возвращаемые значения) не совпадают.Фактически, 0x600 - это значение kCFStringEncodingASCII, которое является эквивалентом Core Foundation NSASCIIStringEncoding.В какой-то момент метод или функция, вызываемая этим методом, переместили 0x600 в RAX, и это значение, которое DTrace ошибочно считало возвращаемым значением.

...