Пользовательский форматировщик данных в LLDB - PullRequest
0 голосов
/ 25 августа 2018

Я глубоко погружаюсь в LLDB и его специальный форматер данных.Допустим, я хочу исследовать следующий код:

import simd

let f2 = float2(42, 50)
print(f2.x)

Я помещаю разрыв в строку print, затем в отладчике выводим значение f2:

(lldb) p f2
(float2) $R3 = (_vector = Builtin.Vec2xFPIEEE32 @ 0x00007fd15a9b4520)

Ничего полезного здесь!Поэтому я создал свою собственную строку сводки в LLDB:

(lldb) type summary add --summary-string "x = ${var.x}, y = ${var.y}" float2
(lldb) p f2
(float2) $R2 = error: summary string parsing error

Я сбит с толку из-за ошибки в последней строке.Он действителен в соответствии со страницей LLDB Data Formatter .Моя следующая интуиция: float2 не имеет свойства с именем x, но это совсем не так.

Почему не получается строка резюме?


Редактировать : с помощью Джима Ингэма мне удалось найти следующее решение:

В файле simd.py:

import lldb

def GetSummary(valobj, internal_dict):
    frame = valobj.GetFrame()
    name = valobj.GetName()
    x_value = frame.EvaluateExpression('{0}.x'.format(name))
    y_value = frame.EvaluateExpression('{0}.y'.format(name))
    x = x_value.GetValueAsUnsigned()
    y = y_value.GetValueAsUnsigned()
    return 'x = {0}, y = {1}'.format(x, y)

Затем загрузитьфункция в LLDB:

(lldb) command script import ~/simd.py
(lldb) type summary add -F simd.GetSummary float2

Теперь она работает с fr v f2, но не p f2:

(lldb) fr v f2
(float2) f2 = x = 42, y = 50
(lldb) p f2
(float2) $R4 = x = 0, y = 0

Она также не обрабатывает числа с плавающей запятой, если я изменяю f2 значения в числа с плавающей запятой

let f2 = float2(42, 50)
(lldb) fr v f2
(float2) f2 = x = 42, y = 50

1 Ответ

0 голосов
/ 25 августа 2018

Синтаксис ${var.*} форматировщиков данных lldb только ищет ivar, чтобы найти *, он не запускает выражение с предоставленной вами строкой.Он будет иметь доступ ко всем элементам объекта, которые может показать команда lldb frame var.

Причина этого ограничения заключается в том, что вызов функций намного дороже, чем прямой доступ к ivar, и если бы мы запустили все спецификации ${var.*} как вызовы функций, вы могли бы легко получить довольно неэффективный форматер.

Если вам нужно вызывать функции в вашем форматере, вы можете использовать функцию Python для функции форматирования и SBFrame.EvaluateExpression для запуска выражения.

Это актуально, поскольку x является вычисляемым свойствомна float2 это не ивар:

(lldb) fr v --raw f2
(simd.float2) f2 = {
  _value = {}
}

Единственный фактический ивар float2 - это непрозрачный _value.

Обратите внимание, что для этой особой необходимости Xcode 10 имеет форматеры данныхдля типов simd вы увидите:

(lldb) fr v f2
(float2) f2 = (4.200000e+01, 5.000000e+01)

Человек, написавший этот форматер данных, знает, как на самом деле располагаются данные simd, поэтому он написал тот, который мог бы собирать значения при доступе к памяти, а не в функциизвонки, так что все еще будет довольно быстро.Для наблюдателя я также должен был добавить --raw в команду frame var выше.

...