Можно ли получить результат метода objc в dtrace?

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

1 ответ

Решение

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

У Билла Бумгарнера есть сообщение о трассировке сообщений до нуля, в котором он говорит следующее:

В сторону: 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 который является основным партнером Фонда NSASCIIStringEncoding, В какой-то момент метод или функция, вызываемая этим методом, переместили 0x600 в RAX, и это значение, которое DTrace ошибочно считало возвращаемым значением.

Другие вопросы по тегам